Week 4 : Embedded Programming

๐Ÿ“šAssignment


Getting Started with Embedded Systems

โ€œFrom silicon chips to maker boards โ€” todayโ€™s class connected the hidden world of microelectronics to hands-on microcontroller programming.โ€

The class focused on understanding how computers are built โ€” starting from microscopic semiconductor chips and progressing toward modern microcontroller platforms used in digital fabrication and prototyping.


๐Ÿง  From Microelectronics to Computer Systems

We began by exploring microelectronics and chip manufacturing, watching industry videos that demonstrated how billions of transistors are fabricated onto silicon wafers using photolithography and processes.

To visualize the incredible scale of microchips, imagine analogy: Imagine a fully planned city like Gandhinagar constructed inside the cross-section of a few human hairs - Billions of nanoscopic transistors manufactured into a microchip. This helped me understand how densely packed modern electronic circuits truly are.

We then zoomed out from chips to complete 💻 computer systems and discussed: Input devices (keyboard, mouse, sensors) , Output devices (screens, speakers, actuators)and the motherboard as the central communication platform.Key components explained included: CPU (microprocessor), GPU, RAM, Network modules, Storage evolution: Floppy Disk 💾 โ†’ CD/DVD 📀 โ†’ HDD โ†’ SSD


Microprocessor (CPU) vs Microcontroller (MCU)

CPU (Computer Brain) MCU (Microcontroller)
Needs external RAM, storage, peripherals CPU + RAM + storage + I/O on one chip
Runs operating systems (Windows, Linux, macOS) Runs a single program directly
Used in laptops, desktops, servers Used in embedded systems & electronics projects
In short:
๐Ÿ‘‰ CPUs run full computers
๐Ÿ‘‰ MCUs control devices

Datasheet Study and Maker Board Evolution โšก From Arduino to RP2040

We explored the evolution of maker platforms:

I compared Arduino, RP2040 and ESP32S3 in terms of:

Feature Arduino Uno (ATmega328P) Raspberry Pi Pico (RP2040) ESP32-S3
Processor Single-core AVR (8-bit) Dual-core ARM Cortex-M0+ (32-bit) Dual-core Xtensa LX7 CPU (32-bit)
Clock Speed 16 MHz Up to 133 MHz Up to 240 MHz
SRAM 2 KB 264 KB 512 KB
Flash Memory 32 KB 2 MB (onboard) 4MB to 16MB
Operating Voltage 5V 3.3V 3.3V
GPIO Pins 20 26 45
Analog Input (ADC) 6 channels, 10-bit 3 channels, 12-bit up to 20 channels, 12-bits
PWM Channels 6 16 8
[LED PWM controller, Two Motor Control PWM]
Connectivity interfaces 1 UART, 1 I2C, 1 SPI 2 UART, 2 I2C, 2 SPI 3 UART, 2 I2C, 2 SPI
USB Support USB via Serial Converter USB 1.1 Device/Host USB 2.0 Full Speed (12Mbps) OTG (On-The-Go) support
Languages C, C++ (Arduino IDE) MicroPython, C, C++ C/C++ and MicroPython/CircuitPython
WIFI โŒ โŒ โœ… Wi-Fi (IEEE 802.11b/g/n)
Bluetooth โŒ โŒ โœ… Bluetoothยฎ 5 (LE)
Camera โŒ โŒ โœ… 8-bit ~ 16-bit DVP camera interface
Sensor Onboard โŒ โŒ โœ… IMU, mic, etc
Where each board shines blinking LEDs, push buttons, simple robotics displays, fast PWM, real-time sensing wireless communication, voice/sound sensing,
onboard inertial sensors, camera apps, IoT dashboards

The Arduino Uno is an 8-bit microcontroller well-suited for basic input/output and embedded control with minimal overhead. The Raspberry Pi Pico, built on the RP2040, offers a more powerful 32-bit dual-core platform ideal for real-time applications and multimedia interfacing. The Seeed XIAO ESP32-S3 Sense combines high computing power with built-in Wi-Fi/Bluetooth, onboard sensors, and camera support, making it capable of advanced IoT, sensing, vision, and edge machine learning projects.

The RP2040โ€™s tiny form factor combined with high performance makes it ideal for embedded and wearable projects.

What Does MHz Actually Mean? : MHz (Megahertz) = how many operations happen per second โฑ

For example:

Higher MHz โ†’ faster instruction execution.

Now lets relate with RP2040 - how much data it can handle at once and how fast?

๐Ÿ‘‰ Bit = single switch
๐Ÿ‘‰ Byte = 8 switches together
๐Ÿ‘‰ RP 2040 is 32-bits = it flips 32 switches in one move
๐Ÿ‘‰ RP 2040 has clock speed upto 133 MHz = it flips (133 million ร— 32 bits) 4.25 billion per second

Thus theoretically, RP 2040 can handle about 506MB/sec.


๐Ÿ“š RP2040 Datasheet Study and ๐Ÿ”Œ Hands-on with Seeed Studio XIAO RP2040

I explored datasheet of ESP32-S3.

Official Datasheet : https://documentation.espressif.com/esp32-s3_datasheet_en.pdf

SEP32S3 Overview

Functional Block Diagram of SoC [System on Chip]

The dark gray blocks are Low power consumption components capable of working in Deep-sleep mode.

Image source

Xtensaยฎ 32-bit LX7 dual-core microprocessor

Memory

Memory Organization - below image illustrates the address mapping structure of ESP32-S3

Image source

GPIO PIN layout

Image source

We received Seeed Studio XIAO RP2040, LEDs, Jumper wires, and Breadboard. We learned Pinout layout and breadboard layout.

Image Source

Image Source

add caution image


๐Ÿงฐ Toolchain is the full pipeline from code โ†’ silicon

A toolchain converts human-readable code into machine instructions and uploads it to the microcontroller.

Toolchain includes:

Elements of Toolchain Seed Studio RP2040 + Arduino Seed Studio RP2040 + Thonny + MicroPython ATtiny44/84 + Microchip Studio + C programming
This Toolchain is part of group assignment
Programming Language Arduino-Style C/C++
[Fast, Low-Level]
MicroPython
[High-level & easy]
Embedded C
[Faster then Arduino-Style C/C++]
Programming Environment Arduino IDE
[Code editor + build + upload in one place]
Thonny
[Editor + REPL + flashing]
Microchip Studio 7
[Editor + compiler + debugger]
Code translated by Compiler
[Converts C/C++ โ†’ machine code]
Interpreter
[Executes Python line by line]
Compiler
[Converts C โ†’ AVR machine code]
Upload tools UF2 bootloader / OpenOCD
[Flashes firmware to chip]
Thonny flasher
[Installs MicroPython firmware]
Libraries Arduino + vendor libraries
[OLED, GPIO, I2C, SPI, etc]
machine, utime, drivers
[GPIO, I2C, LEDs, etc]
avr-libc
[Delays, IO macros, timers]
Runtime Runs directly on hardware Python virtual machine
[Runs on top of MCU]
Runs directly on hardware
Flow looks like
  1. C/C++ code
  2. compiler
  3. machine code
  4. firmware file
  5. uploaded to flash
  6. runs directly on CPU
  1. Python code
  2. Sent to MCU
  3. Interpreted by MicroPython
  4. Executed live
  1. C source code
  2. AVR-GCC compiler
  3. AVR machine instructions
  4. .hex firmware file
  5. Programmer uploads to ATtiny flash
  6. ATtiny executes directly on hardware

โš–๏ธ Quick Comparison Compiler Vs. Interpreter

Feature Compiler Interpreter
Translation Entire program at once Line by line
Output Creates executable file No separate file
Speed Faster execution Slower execution
Error Detection After compilation During execution
Example C/C++, Rust Python, JavaScript, Ruby

Hardware Connection - I connected the Seeed Studio XIAO RP2040 to my computer using a USB Type C cable. When powered, I observed that the onboard RGB LED, the Power LED, and the User LED were turned on. This indicates that the board comes with a factory pre-flashed default program.

To upload new firmware, I pressed and held the BOOT button while connecting the USB cable between the XIAO RP2040 and my PC. The board entered bootloader mode, and a new removable drive named โ€œRPI-RP2โ€ appeared on my computer.

The Power LED remaining ON confirms that the board is properly powered and successfully connected.


Software Setup- I downloaded and installed the latest version of the Arduino IDE compatible with my operating system.

After opening the IDE, I added support for the XIAO RP2040 board package:

  1. Navigate to File โ†’ Preferences
  2. In Additional Boards Manager URLs, add the following URL: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
  3. Click OK

Next, I installed the required board package:

  1. Go to Tools โ†’ Board โ†’ Boards Manager
  2. Search for โ€œRP2040โ€
  3. Install the latest version of โ€œRaspberry Pi Pico/RP2040โ€

I assembled an embedded system using a push button as the input device and an LED and OLED display as output devices, connecting all components on a breadboard with jumper wires.


Using example codes from wiki.seeedstudio.com, I developed and uploaded a program that detects the push button state and turns on the LED and displays "Fab lab Kerala" on OLED when the button is pressed. Wired communication - I2C is used for communication between Seeed RP2040 and OLED Display.

Arduino style C/C++ Code

        /*
          Task :  Write and test a program for an embedded system using a microcontroller to interact with input and / or output devices and communicate with wired or wireless devices.
                  Flash LED and display something on serial monitor and OLED Display when the Push button is pressed.

          Hardware assembly description 
          Development Board   : Seeed Studio XIAO RP2040
          Inputs              : PIN D7 Push button
          Outputs             : PIN D0 Blue LED 
          Wired Communication : I2C with OLED Display                    

          Created on          : 14 Feb 2026 
          Author              : Abhishek
          Modification History: 17 Feb 2026 - code flashed first time and debugging done added Wire.begin()
          
          Library installed for this code are U8g2 by Oliver. (You can install Library Sketch > Include Library > Manage Libraries > Search U8g2 > Install)
          Arduino Programming Reference : https://docs.arduino.cc/language-reference/
          Seed Studio Reference : https://wiki.seeedstudio.com/XIAO-RP2040-with-Arduino/
        */

        #include             // this header file provides access to all the standard, built-in Arduino functions, variables, and constants. Without it, the compiler would not recognize basic Arduino commands. it is must include for VS Code and other programing environments. 
        #include             // this header file provides a preprocessor directive in Arduino/C++ programming that imports the U8g2 library.
        #ifdef U8X8_HAVE_HW_SPI
        #include 
        #endif
        #ifdef U8X8_HAVE_HW_I2C         // this header checks if token U8X8_HAVE_HW_I2C has been defined earlier and check if OLED display supports I2C communication, if yes then include Wire.h library. 
        #include 
        #endif

        U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

        const int BlueLED = D0;         // the number of Blue LED pin
        const int PushButton = D7;      // the number of PushB Button pin, note that here const mean "read-only" variable its value is set at initialization and cannot be changed later in the program, which helps prevent accidental modification of important values.

        int ButtonStatus = LOW;         // Variable for reading the pushbutton status
        int i;                          // counter for for loop

        void setup() // the setup function runs once when you press reset or power the board
        {
          pinMode(BlueLED, OUTPUT);     // initialize digital PIN D0 as output 
          pinMode(PushButton, INPUT);   // initialize digital PIN D7 as Input
          Serial.begin(115200);         // Set the data rate 115200 baud (bits per second) for serial data transmission.
          Wire.begin();                 // Activates the I2C hardware peripheral, Assigns SDA & SCL pins to I2C mode, Gets ready to send/receive data
          u8g2.begin();                 // initialize the display and prepare it for drawing with u8g2 Arduino graphics library
        }

        void loop() // the loop function runs over and over again forever
        {
          ButtonStatus = digitalRead(PushButton);   //read the digital status of Push Button 
          
          if (ButtonStatus == LOW)                 //if Push Button Status in HIGH then flash the LED as Airbus Strobe lights pattern for 5 times 
          {
            for (i = 0; i<10; i++)
            {
              Serial.println("FABLAB Kerala!");   // this prints "FABLAB Kerala!" on the serial monitor
            
              digitalWrite(BlueLED, HIGH);           // turn ON Blue LED
              delay(100);                            // delay of 0.1 second

              digitalWrite(BlueLED, LOW);            // turn OFF Blue LED
              delay(100);                            // delay of 0.1 second

              digitalWrite(BlueLED, HIGH);           // turn ON Blue LED
              delay(100);                            // delay of 0.1 second

              digitalWrite(BlueLED, LOW);            // turn OFF Blue LED
              delay(400);                            // delay of 0.7 second

              u8g2.setFont(u8g2_font_ncenB08_tr);       // ncenB: New Century Schoolbook (font name), Bold (weight). Height of the font is 8 pixels
              u8g2.drawStr(0,10,"Airbus Strobe light..");   // draw string at x = 0 and y = 10
              u8g2.drawStr(0,30,"By");                      // draw string at x = 0 and y = 30
              u8g2.drawStr(0,50,"FAB LAB Kerala!");         // draw string at x = 0 and y = 50
              u8g2.sendBuffer();                         // transfer internal memory to the display
              u8g2.clearBuffer();                       // clear the internal memory
              delay(700);
            }
            u8g2.sendBuffer();                         // transfer internal memory to the display
          }
          
          else 
          {
            digitalWrite(BlueLED, LOW);              // turn Off Red LED
          }

        }

      
      

Learning Note: Today, I learned how to bulk select and replace a word/variable in my code.

  1. Cursor is on a word (for example ledPin)
  2. Press Ctrl + D โ†’ that word gets selected
  3. Press Ctrl + D again โ†’ the next same word gets selected
  4. Keep pressing โ†’ it keeps grabbing all matches

Asking AI for Troubleshoot the code, I prepared the above code by taking bits and pices from 3 different codes from wiki.seeedstudio.com. After asking AI it turn out that the I2C code provided on wiki.seeedstudio.com to run OLED is wrong constructor and Wire.begin() to be added in setup().

Prompt : "what is wrong in this code? it is not working, the OLED is not displaying anything!" and then I pasted the whole code.


Uploading the program, make sure the correct Board and Port are selected from the Tools menu before proceeding with the upload on the Top-left corner as shown below.


Exploring Serial Monitor first thing is to connect micro with PC and set baud rate, Click Tools โ†’ Serial Monitor. Baud rate defines the speed of serial communication in bits per second between the microcontroller and the computer.

Baud rate is simply: ๐Ÿ•’ how fast bits march across the wire

The Serial Monitor was used to establish two-way communication between the computer and the RP2040 microcontroller. Text commands were transmitted from the PC and interpreted by the microcontroller to control multiple LEDs and update the OLED display in real time. This demonstrated real-time debugging, user interaction, and serial-based control.

        /* Exploring Serial Monitor
        Baud rate = how many bits are sent per second 
        */
        #include             // Access to all the standard, built-in Arduino functions, variables, and constants.
        #include             // Imports the U8g2 library.
        #ifdef U8X8_HAVE_HW_SPI
        #include 
        #endif
        #ifdef U8X8_HAVE_HW_I2C         // Check if OLED display supports I2C communication, if yes then include Wire.h library. 
        #include 
        #endif

        //OLED controller chip, Resolution (128 columns ร— 64 rows), Full frame buffer (stores entire screen in RAM), Uses hardware I2C (fast & reliable)
        U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); 

        // Defined the number of LED pin 
        const int RED = D0;
        const int GREEN = D1;
        const int BLUE = D2;
        const int YELLOW = D3;
        char cmd;

        // put your setup code here, to run once:
        void setup() 
        {
          //Initialize Digital pins as Output
          pinMode(RED, OUTPUT);
          pinMode(GREEN, OUTPUT);
          pinMode(BLUE, OUTPUT);
          pinMode(YELLOW, OUTPUT);

          // We are telling the RP2040 to send and receive 115200 bits per second. 
          Serial.begin(115200); 
          while (!Serial); //Donโ€™t run the rest of the program until the PC connects.
          Serial.println("Send R G B Y or O : ");
          
          Wire.begin();  // Activates the I2C hardware peripheral, Assigns SDA & SCL pins to I2C mode, Gets ready to send/receive data
          u8g2.begin();  // initialize the display and prepare it for drawing with u8g2 Arduino graphics library
          delay(1000);
        }

        // put your main code here, to run repeatedly:
        void loop() 
        {
          
          u8g2.setFont(u8g2_font_ncenB08_tr);  // ncenB: New Century Schoolbook (font name), Bold (weight). Height of the font is 8 pixels
          u8g2.drawStr(0,10,"Enter R G B Y or O :");  //draw string at x = 0 and y = 10
          u8g2.drawStr(0,20,"Command:");

          // transfer internal memory to the display
          u8g2.sendBuffer(); 
          
          // Check if PC/Computer sent anything
          if (Serial.available()) 
          {
            char cmd = Serial.read();  // store the character in variable cmd
            u8g2.drawStr(0,40,String(cmd).c_str()); //draw string at x = 0 and y = 40
            u8g2.sendBuffer(); // transfer internal memory to the display

            // Turn-off all the LEDs
            digitalWrite(RED, LOW);
            digitalWrite(GREEN, LOW);
            digitalWrite(BLUE, LOW);
            digitalWrite(YELLOW, LOW);

            // Turn on the LED corresponding to entered character 

            if (cmd == 'R') digitalWrite(RED, HIGH);
            if (cmd == 'G') digitalWrite(GREEN, HIGH);
            if (cmd == 'B') digitalWrite(BLUE, HIGH);
            if (cmd == 'Y') digitalWrite(YELLOW, HIGH);
            
            Serial.print("Command received: ");
            Serial.println(cmd);
            
          }

        }
      

Asking AI to generate code

Prompt : I've an LED connected to D3, and button to D0, of a xiao rp2040. I want a program which allows me click the button to turn on blinking the led and turn off when I click again, then it should print the LED status on serial monitor.

I asked same prompt to two different AI and result for Claude.ai was interesting. It also give me pin diagram for connections according to the code that it has written.

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        //   XIAO RP2040 - Button Toggle LED Blink
        //   LED    โ†’ D3
        //   Button โ†’ D0 (active LOW, internal pull-up enabled)
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

        // โ”€โ”€ Pin Definitions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        #define LED_PIN    D3
        #define BUTTON_PIN D0

        // โ”€โ”€ Timing Configuration โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        const unsigned long BLINK_INTERVAL  = 500;   // ms between LED toggles
        const unsigned long DEBOUNCE_DELAY  = 50;    // ms debounce time

        // โ”€โ”€ State Variables โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        bool blinking        = false;  // Is LED currently blinking?
        bool ledState        = false;  // Current LED on/off state
        int  lastBtnState    = HIGH;   // Previous button reading
        unsigned long lastBlinkTime   = 0;
        unsigned long lastDebounceTime = 0;

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        void setup() {
          pinMode(LED_PIN,    OUTPUT);
          pinMode(BUTTON_PIN, INPUT_PULLUP);  // Active LOW

          digitalWrite(LED_PIN, LOW);         // Start with LED off

          Serial.begin(115200);
          while (!Serial);                    // Wait for Serial Monitor to open

          Serial.println("=====================================");
          Serial.println("  XIAO RP2040 - LED Toggle Blink");
          Serial.println("=====================================");
          Serial.println("  LED Pin  : D3");
          Serial.println("  BTN Pin  : D0");
          Serial.println("  Press button to START / STOP blinking");
          Serial.println("=====================================");
          Serial.println("  LED Status : OFF");
          Serial.println();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        void loop() {
          int currentBtnState = digitalRead(BUTTON_PIN);

          // โ”€โ”€ Button Press Detection (falling edge + debounce) โ”€โ”€
          if (currentBtnState != lastBtnState) {
            lastDebounceTime = millis();       // reset debounce timer on any change
          }

          if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) {
            // State has been stable long enough โ€” check for press
            if (currentBtnState == LOW && lastBtnState == HIGH) {
              blinking = !blinking;            // toggle blink mode

              if (blinking) {
                Serial.println("  LED Status : BLINKING โœ“");
              } else {
                digitalWrite(LED_PIN, LOW);   // ensure LED turns off
                ledState = false;
                Serial.println("  LED Status : OFF");
              }
            }
          }

          lastBtnState = currentBtnState;

          // โ”€โ”€ Non-Blocking Blink โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
          if (blinking) {
            if (millis() - lastBlinkTime >= BLINK_INTERVAL) {
              lastBlinkTime = millis();
              ledState = !ledState;
              digitalWrite(LED_PIN, ledState);
            }
          }
        }

      

I explored MicroPython using the Thonny IDE, a different programming language and development environment for programming the Seeed Studio XIAO RP2040.

First, I downloaded and installed the latest version of Thonny for my operating system and launched the IDE. I then navigated to Tools โ†’ Options โ†’ Interpreter, where I selected MicroPython (Raspberry Pi Pico) as the interpreter and set the port to Try to detect automatically. Next, I pressed and held the BOOT button while connecting the board to my PC using a USB Type-C cable, after which the โ€œRPI-RP2โ€ drive appeared, confirming that the board had entered bootloader mode. I returned to Tools โ†’ Options โ†’ Interpreter and clicked Install or Update MicroPython, allowing Thonny to automatically detect the device. Under the version selection, I chose Raspberry Pi Pico / Pico H, clicked Install, and closed the window once the status showed Done. The firmware completion message then appeared in the interface as shown below.

Now, the development environment was ready for coding. The first MicroPython program I tested was taken from the example provided for the onboard NeoPixel LED on the Seeed Studio wiki page. Since controlling the NeoPixel requires a third-party library, I downloaded the ws2812.py file. In Thonny, I then navigated to File โ†’ Open, selected the downloaded ws2812.py file, and saved it to the board by choosing Raspberry Pi Pico as the target location (ensuring the filename remained ws2812.py).

Next, I copied the NeoPixel example code from the Seeed Studio wiki page and used AI assistance to obtain a line-by-line explanation to better understand how the program works.

In this code, Pin 11 is set to HIGH because it is connected to the VIN pin of the NeoPixel LED to supply power, while Pin 12 is passed to the WS2812 function since it is connected to the data/control pin of the NeoPixel for signal communication.

MicroPython Code

        # Import WS2812 class from the ws2012 library/module, (by this instruction we are saying to import WS2812 function from ws2812 library), this fucntion is used to control WS2812 RGB LEDs (WS2812 is a Neopixel LED)
        from ws2812 import WS2812

        # Import utime module (by "import utime" we are saying that bring me the whole time toolbox, Iโ€™ll grab tools from inside when needed), this module is use for time related fucntions like delay function.
        import utime
        
        # Import machine module, which gives access to hardware features like GPIO pins.
        import machine
        
        # Configures GPIO pin 11 as an output pin and assigns it to the variable power.
        power = machine.Pin(11,machine.Pin.OUT)
        
        # Sets pin 11 to HIGH (1), which likely provides power to the onboard RGB LED circuit.
        power.value(1)

        # Each tuple represents (RED value, GREEN value, BLUE value) Red, Green, and Blue (RGB) are considered primary colors of light, additive color theory is use to derive different colors.
        BLACK = (0, 0, 0)
        RED = (255, 0, 0)
        YELLOW = (255, 150, 0)
        GREEN = (0, 255, 0)
        CYAN = (0, 255, 255)
        BLUE = (0, 0, 255)
        PURPLE = (180, 0, 255)
        WHITE = (255, 255, 255)

        # Creates a tuple named COLORS that stores all above defined colors. This makes it easy to loop through them later.
        COLORS = (BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE)

        # WS2812(pin_num,led_count), Creates an object named led and Control 1 WS2812 LED connected to GPIO 12.
        led = WS2812(12,1)

        # Start an infinite loop everything inside this loop will repeat forever.
        while True:
            # Prints this message to the Thonny serial console each time the loop runs.
            print("Beautiful color")
            # Loops through each color stored in the COLORS tuple, one by one.
            for color in COLORS:
                # Sets the LED to the current color in the loop.
                led.pixels_fill(color)
                # Sends the color data to the LED so it actually updates and lights up. Without this line, the color wouldnโ€™t change visually.
                led.pixels_show()
                # Waits for 0.2 seconds
                utime.sleep(0.2)
      

To upload and run the code, I first clicked the โ€œRun current scriptโ€ button in Thonny. During the first execution, Thonny prompted me to choose where to save the script file. Both This Computer and Raspberry Pi Pico are valid options; however, if the program needs to run independently without connecting the laptop, the file must be saved directly on the board as main.py. After saving the file, I clicked Run current script again to execute the program.


LED Racer

๐ŸŽฏ Game Settings (you can adjust)

Download Code

I used Claude.ai to make this game. Thank you Nadec Biju to introducing me to Claude.

Below prompts I gave to Claude.ai step by step and reached to final code for the game.

Prompt 1: Do you know what is WS2812B LED Strip?

Prompt 2: Does the length of WS2812B matters?

Prompt 3: It has 60 LEDs per meter

Prompt 4: Could you please provide the code and the required libraries? I have connected the LED strip data line to pin D3 and supplied 5 V and GND from an external DC power source.

Prompt 5: I am using Seed Studio XIAO 2040 and Arduino IDE.

Prompt 6:

Prompt 7:

Prompt 8: ok great its working

Prompt 9: Now is the real part, I have made a track from this 5 m WS2812B Strip, I want to make a racing game with two push buttons, one is to move forward meaning when I press the forward push button (connected to pin D0) the Red color LED shall move one LED forward so if I press 300 times it shall move from position LED 1 to LED 300 at each press incrementally and I have connect second push button called Booster button to pin D1. so when I press the booster button the red led shall move forward faster. So when I press the Booster button and Forward button the LED shall move forward like 5 LEDs at one forward button press. So above was for RED LED, I want to make three Player Game 2nd player Green LED and 3rd Player BLUE LED. Could you please help with the code?

Prompt 10: can you change it a little, instead of a separate boost button please use forward button long press as Boost feature.

Prompt 11: Hello Claude, I have made a track where in from 17 LED to 31 LED is hill and from 33 LED to 54th LED there is another hill and from 127 LED to 183 LED I have a spiral with 3 loops entering from top at 127 and exiting at 183 and then again from LED 223 to 273 I have another spiral of three loops. The 127 to 183 is placed horizontal and spiral 223 to 273 is placed vertical. So can you have some fun with the speed of moving forward at these locations?

Prompt 11: Can you divide hill length in two parts up and down, when up you can keep 0.5 and while going down you can keep 2 . and also for example if RED player finishes first then 300th LED shall be RED, if green player finishes 2nd then 299th LED shall be lit up green and BLUE reached last then BLUE LED shall be lit up on 298th position. I need one improvement that when RED , GREEN and BLUE enters HILL1 or SPIRAL1 or SPIRAL2 the RED shall have RED color the GREEN shall have GREEN color and BLUE shall have BLUE color, currently what is happening is that he HILL and SPIRAL color are getting mix-up and creating new COLOR instead of RED, GREEN and BLUE. In the beginning, when you are blinking only the first LED 3 times, instead blink the whole track in white with 3 times. What name shall I give to this game?


๐ŸŒŸ Reflection

Thursday : This session beautifully connected: Invisible microelectronics โ†’ Real-world embedded systems

Friday : Don't try to take 3-4 steps at once, go step by step, we should first learn the hard way and then use the easy way.

๐Ÿ“ References and Downloads