Search This Blog

Showing posts with label Embedded development. Show all posts
Showing posts with label Embedded development. Show all posts

Saturday, 4 January 2025

DIY Game Console Using SSD1306 OLED Display and NodeMCU/Arduino UNO



DIY Game Console Using OLED Display and NodeMCU/Arduino UNO

Have you ever wondered if you could create your own handheld game console? In this project, I built a compact and functional game console using a 0.96-inch OLED display and a NodeMCU or Arduino UNO. This console is not only a fun project but also a great way to dive into game development and hardware programming.



Project Highlights

  1. Hardware Features:

    • Display: A crisp, 0.96-inch OLED display that brings the game graphics to life.
    • Controller: Designed with buttons for user input, providing a classic gaming feel.
    • Microcontroller: Choose between NodeMCU for Wi-Fi capabilities or Arduino UNO for a simpler setup.
  2. Software Development:

    • Programmed with libraries for handling the OLED display and managing game logic.
    • Simple, retro-style games developed to showcase the console's capabilities.
  3. Applications:

    • Learn about display handling, game logic, and embedded systems.
    • Expandable to include more games or additional features.


Challenges and Learnings

During this project, I explored handling small displays, optimizing microcontroller performance, and balancing functionality with hardware constraints. It’s a rewarding experience for anyone interested in IoT, game development, or Arduino programming.



Why You Should Try It

This project is perfect for hobbyists, makers, or students wanting to combine creativity and technology. With affordable components and endless customization options, you can make it uniquely yours.



Components Required

  • NodeMCU or Arduino UNO Microcontroller
  • 4 Push Buttons
  • Tools like Soldering Iron, Hot Glue Gun
  • OLED 0.96 inch I2C Display


Circuit diagram

This is Circuit Diagram for this project, I used TinkerCAD to make this diagram, so SSD1306 OLED Display was not available, that's why I used 16x2 i2c Display, because these both display is using same communication method which is I2C communication.
So you can replace 16x2 display connections with your 0.96 inch OLED Display.



Upload the Code

#define SSD1306_I2C_ADDRESS 0x3C

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED display size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1  // Reset pin not used

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Button pins
#define UP_BUTTON 00
#define LEFT_BUTTON 14
#define DOWN_BUTTON 13
#define RIGHT_BUTTON 12

// Snake parameters
#define MAX_LENGTH 100
int snakeX[MAX_LENGTH];
int snakeY[MAX_LENGTH];
int snakeLength = 5;
int foodX, foodY;

// Movement direction
int directionX = 1;
int directionY = 0;

// Game state
bool gameOver = false;

// Debounce variables
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // 50ms debounce delay

void setup() {
  // Initialize buttons as inputs with internal pull-up resistors
  pinMode(UP_BUTTON, INPUT_PULLUP);
  pinMode(LEFT_BUTTON, INPUT_PULLUP);
  pinMode(DOWN_BUTTON, INPUT_PULLUP);
  pinMode(RIGHT_BUTTON, INPUT_PULLUP);

  // Initialize display
  if (!display.begin(SSD1306_I2C_ADDRESS, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();

  // Initialize snake position
  for (int i = 0; i < snakeLength; i++) {
    snakeX[i] = 64 - i;
    snakeY[i] = 32;
  }

  // Place initial food
  placeFood();
}

void loop() {
  if (gameOver) {
    showGameOver();
    return;
  }

  // Handle button presses with debounce
  handleButtonPress();

  // Move the snake
  moveSnake();

  // Check for collisions
  checkCollision();

  // Update display
  drawGame();

  // Delay for game speed
  delay(200);
}

void placeFood() {
  foodX = random(0, SCREEN_WIDTH / 4) * 4;
  foodY = random(0, SCREEN_HEIGHT / 4) * 4;
}

void moveSnake() {
  // Move body
  for (int i = snakeLength - 1; i > 0; i--) {
    snakeX[i] = snakeX[i - 1];
    snakeY[i] = snakeY[i - 1];
  }

  // Move head
  snakeX[0] += directionX * 4;
  snakeY[0] += directionY * 4;

  // Check if food is eaten
  if (snakeX[0] == foodX && snakeY[0] == foodY) {
    if (snakeLength < MAX_LENGTH) {
      snakeLength++;
    }
    placeFood();
  }
}

void checkCollision() {
  // Check wall collision
  if (snakeX[0] < 0 || snakeX[0] >= SCREEN_WIDTH || snakeY[0] < 0 || snakeY[0] >= SCREEN_HEIGHT) {
    gameOver = true;
  }

  // Check self-collision
  for (int i = 1; i < snakeLength; i++) {
    if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
      gameOver = true;
      break;
    }
  }
}

void handleButtonPress() {
  unsigned long currentTime = millis();

  // Check UP button
  if (digitalRead(UP_BUTTON) == LOW && currentTime - lastDebounceTime > debounceDelay && directionY == 0) {
    directionX = 0;
    directionY = -1;
    lastDebounceTime = currentTime;
   
  }
  // Check LEFT button
  else if (digitalRead(LEFT_BUTTON) == LOW && currentTime - lastDebounceTime > debounceDelay && directionX == 0) {
    directionX = -1;
    directionY = 0;
    lastDebounceTime = currentTime;
  }
  // Check DOWN button
  else if (digitalRead(DOWN_BUTTON) == LOW && currentTime - lastDebounceTime > debounceDelay && directionY == 0) {
    directionX = 0;
    directionY = 1;
    lastDebounceTime = currentTime;
  }
  // Check RIGHT button
  else if (digitalRead(RIGHT_BUTTON) == LOW && currentTime - lastDebounceTime > debounceDelay && directionX == 0) {
    directionX = 1;
    directionY = 0;
    lastDebounceTime = currentTime;
  }

  else {
    pinMode(UP_BUTTON, INPUT_PULLUP);
  }
}

void drawGame() {
  display.clearDisplay();

  // Draw the snake
  for (int i = 0; i < snakeLength; i++) {
    display.fillRect(snakeX[i], snakeY[i], 4, 4, SSD1306_WHITE);
  }

  // Draw the food
  display.fillRect(foodX, foodY, 4, 4, SSD1306_WHITE);

  // Show the updated screen
  display.display();
}

void showGameOver() {
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 25);
  display.println("Game Over!");
  display.display();
  while (true); // Stop the game
}

This is the code you can copy and paste if you used same button and display connections. If you changed the pin connection, you can change this code from line 14 - 18

// Button pins
#define UP_BUTTON 00
#define LEFT_BUTTON 14
#define DOWN_BUTTON 13
#define RIGHT_BUTTON 12


YOU CAN WATCH THIS VIDEO -



 https://youtu.be/cTQhhXtyOdo


This project showcases how simple components like an OLED display and a microcontroller can come together to create something amazing. The possibilities are endless, and the journey of learning and building is the most exciting part. Happy making!

Wednesday, 20 November 2024

PWM Motor Control: control the power supplied to a load by varying the width of the pulses in a digital signal

 

Beginner Embedded C++ Project: PWM Motor Control



Introduction

Pulse-width modulation (PWM) is a technique used to control the power supplied to a load by varying the width of the pulses in a digital signal. This allows us to control the speed and direction of a DC motor.

Uses of this Project

  • Control the speed of a fan
  • Control the direction of a robot
  • Dim the brightness of an LED

Requirements

  • A microcontroller with a PWM peripheral
  • A DC motor
  • A motor driver (if the motor requires more current than the microcontroller can provide)
  • Some wires

Code


// Define the PWM pin
const int pwmPin = 9;

// Define the motor driver pins
const int motorA = 10;
const int motorB = 11;

void setup() {
  // Set the PWM pin to output mode
  pinMode(pwmPin, OUTPUT);

  // Set the motor driver pins to output mode
  pinMode(motorA, OUTPUT);
  pinMode(motorB, OUTPUT);
}

void loop() {
  // Set the duty cycle of the PWM signal to control the speed of the motor
  analogWrite(pwmPin, 128);

  // Set the direction of the motor by setting the motor driver pins
  digitalWrite(motorA, HIGH);
  digitalWrite(motorB, LOW);

  // Delay for 1 second
  delay(1000);

  // Reverse the direction of the motor
  digitalWrite(motorA, LOW);
  digitalWrite(motorB, HIGH);

  // Delay for 1 second
  delay(1000);
}

Conclusion

PWM motor control is a powerful technique that can be used to control the speed and direction of a DC motor. This project is a great way to learn how to use PWM and get started with embedded C++ development.

```

**PWM Motor Control: A Beginner Embedded C++ Project** Pulse-width modulation (PWM) is a technique used to control the power supplied to a load by varying the width of the pulses in a digital signal. This allows us to control the speed and direction of a DC motor. This beginner-friendly Embedded C++ project will guide you through the steps of controlling a DC motor using PWM. You will learn how to set up the hardware, write the code, and control the motor's speed and direction. **Requirements:** * Microcontroller with PWM peripheral * DC motor * Motor driver (if required) * Wires **Benefits:** * Learn the basics of PWM * Gain hands-on experience with embedded C++ * Control the speed and direction of a DC motor This project is suitable for beginners with basic knowledge of electronics and programming. It is a great way to get started with embedded C++ development and learn a valuable technique for controlling motors.

Monday, 18 November 2024

Get started with embedded systems development | Micropython to control hardware

 

Micropython Tutorial: Getting Started

Introduction

Micropython is a compact and efficient implementation of the Python programming language designed for microcontrollers. It combines the ease of use and readability of Python with the low-level control and hardware access capabilities of microcontrollers, making it an ideal choice for embedded systems development.

Uses of Micropython

  • Rapid prototyping of embedded systems
  • Data acquisition and processing
  • IoT device development
  • Robotics and automation
  • Wearable device development

Requirements

  • A microcontroller board with Micropython support (e.g., ESP32, Raspberry Pi Pico)
  • A text editor or IDE (e.g., Thonny, Mu)
  • A USB cable for connecting the microcontroller board to your computer

Getting Started

To get started with Micropython, follow these steps:

  1. Install Micropython on your microcontroller board.
  2. Connect the microcontroller board to your computer using a USB cable.
  3. Open a text editor or IDE and create a new file.
  4. Write your Micropython code in the file.
  5. Save the file and transfer it to your microcontroller board.
  6. Run your Micropython program on the microcontroller board.

Basic Syntax

Micropython's syntax is very similar to Python's. Here are some of the basic syntax elements:

  • Variables are declared without a type and can be assigned any value.
  • Statements end with a newline character.
  • Indentation is used to group statements into blocks.
  • Comments start with a hash symbol (#).

Example Code

Here is a simple Micropython program that blinks an LED:

import machine led = machine.Pin(13, machine.Pin.OUT) 
while True: 
 led.on() 
 time.sleep(1)  
 led.off() 
 time.sleep(1)

Conclusion

This tutorial provides a comprehensive introduction to Micropython. By following the steps outlined in this tutorial, you can get started with Micropython and start developing your own embedded systems projects.

```

**Micropython Tutorial:** Micropython is a powerful and easy-to-use programming language for microcontrollers. It combines the simplicity of Python with the low-level control of microcontrollers, making it an ideal choice for embedded systems development. This comprehensive guide covers everything you need to get
, how to use it to control hardware, and how to develop IoT applications. Whether you're a beginner or an experienced programmer, this guide will help you get the most out of Micropython and start building your own embedded systems projects. **Key Features:** * Step-by-step instructions for getting started with Micropython * Coverage of all the essential Micropython concepts * Examples and exercises to help you learn * Troubleshooting tips and tricks **Benefits:** * Learn how to use Micropython to control hardware * Develop IoT applications with Micropython * Get started with embedded systems development * Build your own custom projects with Micropython

Wednesday, 8 May 2024

Blink an LED using RaspberryPi pico,nano,3,4,b,b+ in Python and C/C++ both

 

How to Blink an LED on a Raspberry Pi

How to Blink an LED on a Raspberry Pi - Jeremy Morgan's Tech Blog 

The blinking LED is the “hello world” of the maker community, and today I’ll show you how easy it is to do with the Raspberry Pi 2 (or Model B)! We’re going to use Python and WiringPi for this project.

What you’ll need

For this article I’m using a Raspberry Pi 2, but you can also use a Raspberry Pi Model B. You will also need:

  • A GPIO Adapter
  • Breadboard
  • Resistor
  • LED
  • The quickest way to get that LED to blink is to take a look at the pins of the GPIO 

    Raspberry gPIo - learn.sparkfun.com

     and decide which one to tie to. Then you can use Python and the Raspberry Pi GPIO Library to create a script to light it up.

    import RPi.GPIO as GPIO ## Import GPIO Library
    import time ## Import 'time' library (for 'sleep')

    blue = 7 ## These are our LEDs
    ourdelay = 1 ## Delay
    # pins 4,17,18,21,22,23,24,25

    GPIO.setmode(GPIO.BOARD) ## Use BOARD pin numbering
    GPIO.setup(pin, GPIO.OUT) ## set output

    ## function to save code

    def activateLED( pin, delay ):
    GPIO.output(pin, GPIO.HIGH) ## set HIGH (LED ON)
    time.sleep(delay) ## wait
    GPIO.output(pin, GPIO.LOW) ## set LOW (LED OFF)
    return;

    activateLED(blue,ourdelay)

    GPIO.cleanup() ## close down library
    
    

    As you can see in the code above, it doesn’t take much to get things working. But I’ll explain the code a little deeper.

    import RPi.GPIO as GPIO
    import time

    The following code imports the Python GPIO library, and the time library. The GPIO library, as you probably guessed is the library for interacting with the GPIO in Python. It does an amazing job of simplifying the process. The time library is there so we can put a delay in, otherwise the blink might be too fast to notice.

    blue = 7
    ourdelay = 1

    Here I created a variable named “blue” (the color of the LED) and assigned it “7” which is the pin number we want. If I wanted to add multiple LEDs I could name it something like:

    blue = 7
    red = 13
    green 14

    I then created a “delay” variable of one second. This way I can change the delay of the lights blinking however I want.

    You can name the variables anything you want, but this was just to make it easy to see which LED is which if I wanted to do some fancy light show.

    GPIO.setmode(GPIO.BOARD) 

    Then, we set the GPIO mode to “Board” which means we’ll use the numbering of the pin by board instead of GPIO. This makes it a little easier to understand when using a bread board.

    With this line of code we set the pin to be an output:

    GPIO.setup(pin, GPIO.OUT)

    There are 2 main commands to turn the LED on then off:

    GPIO.output(pin, GPIO.HIGH)
    GPIO.output(pin, GPIO.LOW)

    If you wanted to blink an LED twice you would have to repeat the last two lines each time. So I decided to put this in a function and put the pin and delay as parameters. This way making a particular LED blink is as simple as:

    activateLED(blue,ourdelay)

    This is repeatable and saves code when doing larger programs.

    To close everything down, we need to run the following:

    GPIO.cleanup()

    It’s that easy! You could easily write a nice Python script that do some pretty cool stuff with just a few lines of code.

     

    For this step we’ll install WiringPi for the libraries to interact with the GPIO. This allows us to do what we just did, but from the command line. We’ll need to install WiringPi:

    cd ~/sources
    git clone git://git.drogon.net/wiringPi
    cd wiringPi
    git pull origin
    ./build
    
    

    If successful you should see a screen like this:

    Blink an LED Raspberry Pi

    Now we can light up the LED from the command line. Remember the pin 7 in the example above? We can now light up like so:

    gpio mode 7 out
    gpio mode 7 1
    
    

    This will light up the LED. You can turn it off by entering:

    gpio mode 7 0
    
    

    Blink an LED Raspberry Pi

    This makes it super easy to light up LEDs from the command line. You could create a pretty neat BASH script to do this, and do some neat things, or call this from other languages.

    Summary

    I hope this has helped in showing how easy it is to blink an LED on the Raspberry Pi 2/B. Of course as you progress on you’ll want to do far more than just blink an LED, but the GPIO libraries make it very easy to create some neat stuff. If you’ve experimented with this and done something cool, Let me know!!!


Two Month Masterclass on Python Programming Language

Hello Guys, Register in this Amazing Two Month Masterclass on Python Programming Language If you have any queries, You can email me - surya...