i
  1. Week 1 : Project Management
  2. Week 2 : Computer-aided
  3. Week 3 : Computer Controlled Cutting
  4. Week 4 : Embedded Programming
  5. Week 5 :3D Scanning and Printing
  6. Week 6 : Electronic Design
  7. Week 7 : Computer Controlled Machining
  8. Week 8 : Electronics Production
  9. Week 9 : Input Devices
  10. Week 10 : Output Devices
  11. Week 11 : Networking and Communication
  12. Week 12 : Mechanical Design and Machine Design
  13. Week 13 : Midterm Review
  14. Week 14 : Molding and Casting
  15. Week 15 : Interface and Application Programming
  16. Week 16 : System Integeration
  17. Week 17 : Wildcard Week
  18. Week 18 : Applications and Implications, Project Development
  19. Week 19 : Invention, Intellectual property and Income

Week 4 : Embedded Programming

Objectives of the Week

  • Linked to the group assignment page
  • Documented your project and what you have learned from implementing networking and/or communication protocols.
  • Explained the programming process(es) you used.
  • Ensured and documented that your addressing for boards works
  • Outlined problems and how you fixed them.
  • Included design files (or linked to where they are located if you are using a board you have designed and fabricated earlier) and original source code.
  • Included a 'hero shot' of your network and/or communications setup

  • Group Assignment Contribution

    #

    For More about Group Assignment

    Sample image


    Individual Assignment Contribution

    This project involved building an interactive control interface using a joystick, an OLED display, and LEDs, all managed through the XIAO ESP32-C3 microcontroller. The primary goal was to learn and demonstrate how analog input from a joystick can be interpreted and translated into real-time feedback through both digital (LED) and graphical (OLED) outputs. The project successfully simulates a basic Human-Machine Interface (HMI), where directional movement of a joystick is used to provide multi-channel output response.

    The joystick module provides two degrees of analog motion (X and Y) along with an optional button press. These inputs are connected to analog pins of the ESP32-C3 and sampled using analogRead() to detect direction. Based on the tilt or displacement, the microcontroller determines whether the joystick is being pushed up, down, left, or right.

    Each direction corresponds to a separate LED output. When the joystick is pushed up, for example, the UP LED lights up. The OLED display complements this by showing the current direction in text form—providing visual feedback for user input. This kind of dual-output design reinforces the concept of multi-modal feedback in embedded systems.

    The OLED display operates via the I2C protocol, meaning it requires only two wires (SDA and SCL), making it ideal for compact designs like the XIAO ESP32-C3, which has limited pins. Using the Adafruit_SSD1306 and Adafruit_GFX libraries, the OLED was programmed to dynamically update text whenever the joystick is moved.

    One important concept learned during the implementation was signal thresholding. Joystick analog values can fluctuate even when idle, which may result in false direction readings. To address this, center dead-zones were implemented in code to avoid noise-based misreads. If the X-axis is within ±300 of center (2048 on 12-bit ADC), it's considered idle. The same logic is applied to the Y-axis.

    Another important lesson was understanding pin mapping and addressing, especially with the GPIO pins of the XIAO ESP32-C3, which can behave differently than traditional ESP32 or Arduino Uno boards. Using a pin mapping table specific to the XIAO ESP32-C3 was crucial for correct setup.

    Overall, this project helped me gain practical experience in:

    By integrating multiple components into a unified setup, I improved my understanding of embedded systems design and the synergy between input devices, microcontrollers, and output interfaces.

    Programming Process Used

    The programming for this joystick-based control system follows a modular structure, beginning with hardware setup and then focusing on logic implementation and output synchronization. The programming process was executed using the Arduino IDE, with the XIAO ESP32-C3 board selected from the board manager and libraries installed for OLED and I2C communication.

    The first part of the program involves setting up the necessary libraries:

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

    These handle I2C communication and graphics rendering on the OLED. After defining the display size and initializing the display object, pin definitions were made for both the joystick analog pins and the digital pins connected to LEDs.

    The setup() function initializes serial communication for debugging, the OLED display using display.begin(), and sets the LED pins as outputs using pinMode(). The joystick pins are left as analog inputs by default.

    The loop() function is where the bulk of the logic occurs. First, analog readings are taken from the joystick's X and Y axes:

                  
                    int xVal = analogRead(A0);
                    int yVal = analogRead(A1);

    Using calibrated thresholds, the code determines which direction the joystick is pointing. For example, if xVal > 3000, it's considered "Right". These conditions are used to trigger the corresponding LED and update the OLED display. Before every new update, display.clearDisplay() is called to avoid overlapping frames.

    The direction is then printed to the OLED using:

                  
                    display.setCursor(0, 20);
                    display.print("Direction: RIGHT");
                    display.display();

    The corresponding LED is also activated using digitalWrite().

    To add a sliding effect, a global variable xOffset can be used to shift the cursor position across frames. This adds UI flair and simulates text scrolling across the screen.

    One challenge in the programming process was creating a responsive interface without flicker or delay. OLEDs can flicker when content is cleared and redrawn too quickly. To address this, frame updates were optimized, and redraws were done only when the direction changed.

    Debouncing logic was added to prevent rapid LED flicker when the joystick was near the center threshold. Flags were used to track direction changes and update outputs only when a transition occurred.

    Modularity was emphasized through use of functions like updateDisplay(direction) and setLED(direction), which made debugging and scalability easier.

    In summary, the programming involved:

    • Pin configuration
    • Threshold-based analog input handling
    • Conditional direction detection
    • I2C communication with OLED
    • Dynamic UI updates
    • LED output synchronization
    • Debounce and state change logic

    This structured approach made the entire system responsive and reliable.

    Hardware Addressing and Problem Solving

    A critical part of this project was ensuring proper **hardware addressing**, especially because multiple peripherals were used: an **OLED screen** (using I2C) and four **LEDs** (using GPIO). The **XIAO ESP32-C3** has a unique pin mapping structure compared to traditional Arduino boards, and confirming pin assignments and communication addresses was essential to achieving reliable operation.

    OLED I2C Addressing

    The OLED display used in this project operates on the **I2C protocol**. I2C devices require a unique 7-bit address to communicate with the microcontroller. The common address for most SSD1306 OLED displays is **0x3C**, but it can vary depending on the module's configuration. To confirm this:

    • I uploaded an **I2C scanner sketch** (available online) to the XIAO ESP32-C3.
    • This scanner detected the OLED at address **0x3C**, confirming communication.
                  
                    #include <Wire.h>
                    void setup() {
                      Wire.begin();
                      Serial.begin(115200);
                      while (!Serial); // wait for serial monitor
                      Serial.println("I2C Scanner");
                    }
    
                    void loop() {
                      byte error, address;
                      for (address = 1; address < 127; address++) {
                        Wire.beginTransmission(address);
                        error = Wire.endTransmission();
                        if (error == 0) {
                          Serial.print("I2C device found at 0x");
                          Serial.println(address, HEX);
                        }
                      }
                      delay(1000);
                    }
                  
                

    This verified that my OLED module was correctly wired to the default I2C pins:

    • SDA → GPIO5 (D5)
    • SCL → GPIO4 (D4)

    These are default hardware I2C pins on the XIAO ESP32-C3. While it's possible to use Wire.begin(SDA, SCL), sticking with default pins ensured library compatibility.

    LED GPIO Addressing

    The LEDs were assigned to digital GPIO pins on the microcontroller. The following assignments were used:

    Direction Function Pin Label GPIO Number
    UP UP_LED D0 GPIO0
    DOWN DOWN_LED D2 GPIO2
    LEFT LEFT_LED D3 GPIO3
    RIGHT RIGHT_LED D9 GPIO9

    To avoid any hardware confusion:

    • I double-checked the XIAO ESP32-C3 pinout diagram.
    • Used digitalWrite() after setting pinMode(pin, OUTPUT) in setup().
    • Verified each LED connection by writing a test program to blink them individually.

    Joystick Analog Input Addressing

    The joystick's X and Y axes were connected to analog pins:

    • X → A0 (GPIO1)
    • Y → A1 (GPIO2)

    These inputs were confirmed using `analogRead()` and `Serial.print()` to verify the response to physical joystick movement. I also ensured the analog resolution matched the ESP32's default 12-bit ADC range (0 to 4095).

    Conclusion

    By verifying the I2C address using an I2C scanner, confirming GPIO pin mappings via official documentation, and testing each peripheral in isolation, I ensured the full addressing scheme worked correctly. This step was crucial to avoid overlapping resources and debugging conflicts. Proper addressing is foundational in embedded systems, especially when multiple input/output devices share the same communication bus or pin bank.

    Joystick Analog Input Addressing

    Every embedded project introduces a set of technical challenges, and this joystick-OLED-LED interface was no exception. Through iterative testing and debugging, I encountered several problems related to communication, flickering displays, unstable readings, and wiring misconfigurations. Here is a breakdown of the major problems and how they were fixed:

    Problem 1: OLED Not Displaying Anything

    • Issue: The OLED screen remained blank on startup even though the code compiled successfully.
    • Cause: The I2C address was either incorrect or the OLED wasn’t connected to the expected pins.
    • Fix: I uploaded an I2C scanner sketch to the board and verified the OLED was connected at 0x3C. I had initially misconnected SDA/SCL to the wrong GPIOs. After correcting them to GPIO5 (SDA) and GPIO4 (SCL), the display worked.

    Problem 2: Flickering Text on OLED

    • Issue: The OLED flickered every time a new direction was printed.
    • Cause: This was due to the frequent use of `display.clearDisplay()` and redrawing everything on every loop iteration.
    • Fix: I implemented a simple optimization where the OLED is only updated when the direction changes. I used a string variable `prevDirection` to store the last displayed value and compared it with the current one before updating the display.

    Lessons Learned

    These problems taught me the importance of:

    • Proper hardware debugging through test sketches
    • Using serial debugging to isolate problems
    • Understanding noise and debounce in analog signals
    • Verifying I2C wiring and address settings
    • Consulting board-specific documentation (especially for non-standard pin maps)

    By systematically tackling each issue, I was able to build a stable, real-time UI interface driven by joystick input.

    Finally Leaving my files here

    Arduino Uno Datasheet

    Xiao ESP32C3 Datasheet

    Source Code