Skip to content

Embedded Programming

Arduino Q (UNO Q)

Arduino Q (also referred to as the Arduino UNO Q or UNO R4 WiFi) is a microcontroller development board that combines the simplicity of Arduino with the power of an industrial-grade microprocessor. It features a unique "Dual-Brain" architecture:

  • A Microprocessor (MPU): Powered by the Qualcomm® QRB2210 (Quad-core ARM® Cortex®-A53). It runs a full Debian-based Linux OS, allowing for advanced tasks like Edge AI, Python scripting, and robust WiFi management.
  • A Microcontroller (MCU): The STM32U585 (ARM® Cortex®-M33). This handles real-time hardware control, precise timing for pins, and the built-in LED matrix.

Unlike traditional Arduino boards, the UNO Q integrates a Linux-capable processor with AI acceleration, making its development workflow closer to embedded Linux systems than microcontroller-only platforms.

Arduino Cloud


🛠 Setting Up Arduino Q (UNO Q)

For full functionality—especially for WiFi and cloud control—I use Arduino Cloud / App Lab.

Arduino Cloud

📥 Installation Steps

  1. Download: Go to the Arduino Software page and download Arduino App Lab / Arduino Cloud Agent.

App Lab Download

  1. Open Application: Launch the application on your computer.

App Launch

  1. Connect: Plug in the Arduino Q (UNO R4 WiFi) using a USB-C cable.

  2. Auto-Detection: The board should be auto-detected by the software.

  3. Configuration:

    • Set Device Name.

    Device Name Setup

    • Enter WiFi SSID and Password.

    WiFi Configuration

  4. Firmware Update: Check for firmware updates and update if prompted.

    Firmware Update Check

    Firmware Update Progress

    Firmware Installation

    Firmware Completion

  5. Linux Setup: Setup the Linux credentials.

    Linux Credentials Setup

After setup, the board is ready for App Lab based programming.


I tested the cloud functionality by running a basic blink sketch.

  1. Select a built-in Blink example.

    Blink Example Selection

  2. Click Run.

    Run Button

  3. Code compiles automatically.

    Code Compilation

  4. A webpage opens where the LED can be controlled from the browser.


💻 Arduino IDE Programming

Even though Cloud is available, the board can also be programmed using the Arduino IDE.

Step 1 — Install Board Package

  1. Open Board Manager.

  2. Install Arduino UNO Q Boards.

    Board Manager

Step 2 — Install Required Libraries

Install the following libraries to use the display:

  • #include "ArduinoGraphics.h"

  • #include "Arduino_LED_Matrix.h"

    Library Installation


🟢 Example 2 — LED Matrix Animation + Text

Open the example code and select the Matrix Basic Code.

Matrix Example Code

Code

#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"

Arduino_LED_Matrix matrix;

void setup() {
  matrix.begin();
  matrix.textFont(Font_5x7);
  matrix.textScrollSpeed(100);
  matrix.clear();
  Serial.begin(115200);
}

uint8_t shades[104] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,1,1,1,1,1,1,1,1,1,1,1,
  2,2,2,2,2,2,2,2,2,2,2,2,2,
  3,3,3,3,3,3,3,3,3,3,3,3,3,
  4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,
};

const uint32_t animation[][5] = {
  {0x38022020,0x810408a0,0x2200e800,0x20000000,66},
  {0x1c011010,0x40820450,0x11007400,0x10000000,66},
  {0x0e008808,0x20410228,0x08803a00,0x08000000,66},
  {0x07004404,0x10208114,0x04401d00,0x04000000,66},
  {0x03802202,0x0810408a,0x02200e80,0x02000000,66},
  {0x01c01101,0x04082045,0x01100740,0x01000000,66},
  {0x00e00880,0x82041022,0x808803a0,0x00000000,66},
  {0x00700440,0x40020011,0x004401c0,0x00000000,66},
  {0x00380200,0x20010008,0x802000e0,0x00000000,66},
  {0x00180100,0x10008004,0x00100060,0x00000000,66},
  {0x00080080,0x08004002,0x00080020,0x00000000,66},
  {0x00000040,0x04002001,0x00040000,0x00000000,66},
  {0x00000000,0x02001000,0x80000000,0x00000000,66},
  {0x00000000,0x00000000,0x00000000,0x00000000,66}
};

void loop() {

  matrix.beginText(0, 0, 127, 0, 0);
  matrix.print("      arduino.cc/uno-q      ");
  matrix.endText(SCROLL_LEFT);

  delay(1000);

  matrix.setGrayscaleBits(3);
  matrix.draw(shades);

  delay(1000);

  matrix.clear();

  matrix.loadSequence(animation);
  for (int i = 0; i < 10; i++) {
    matrix.playSequence();
  }
}

Action: I hit Compile and Upload.

Output: This example demonstrates:

  • Scrolling text

  • Custom animation


🧪 Custom LED Matrix Project

The next thing I tried out was printing on the LED matrix my own Custom Message. Below is the code for that.

Code

#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
Arduino_LED_Matrix matrix;

void setup() {
matrix.begin();
matrix.textFont(Font_5x7);
matrix.textScrollSpeed(60);
matrix.clear();
}

void loop() {
matrix.beginText(0, 0, 127, 0, 0);
matrix.print("   SUPERFABLAB KOCHI   FabAcademy 26   ");
matrix.endText(SCROLL_LEFT);

delay(500);
}

Output: The matrix displayed our custom group message.


Then I got back to the App Lab and tested another basic blink—the one without any UI.

Action:

  1. Open Arduino App Lab.

App Lab Open

  1. Select the Basic Blink example (the version without the Cloud/Web Switch).
  2. Click Run.

Basic Blink Example

Output: The board reset and the LED started blinking immediately.

ESP32-C6

Step 1: Toolchain Installation on macOS

The process began with setting up a professional development environment. Unlike MicroPython, which is pre-installed, Assembly requires a native compiler on the host machine.

interface Caption: tool chain

  • System Dependencies: Installed via Homebrew.

    brew install libgcrypt glib pixman sdl2 libslirp dfu-util cmake python

  • EIM GUI: Used the Espressif Installation Manager to handle the background setup of the RISC-V toolchain.

interface Caption: interface page

  • VS Code Extension: Installed the ESP-IDF extension for a graphical interface to build and flash.

interface Caption: extention download


Step 2: Project Creation & Target Setting

I used a template to ensure the bootloader and partition tables were correctly configured.

  • Generating the Project: Started with the get-started/blink example.

interface Caption: new project page

  • Targeting RISC-V: Manually set the target to esp32c6 in the VS Code status bar.
  • Observation: If this isn't set to C6, the compiler would try to use Xtensa logic (standard ESP32), which is architecturally incompatible with this chip.

Step 3: The "Assembly Pivot" & Initial Error

This phase involved transitioning from C to Assembly to interact directly with the silicon.

  • The Change: Renamed the source file to main.S and updated CMakeLists.txt.

interface Caption: cmakelist page

  • The First Obstacle: Encountered an error stating the .elf file was missing. This occurred because the build system was holding onto old C-language artifacts.

  • The Troubleshooting: In collaboration with Gemini, I forced a "Clean" state via the terminal:

    idf.py fullclean(Wiped the old build cache). idf.py set-target esp32c6 (Re-initialized the RISC-V environment).

    interface

Caption: file clearing process


Step 4: The Assembly Implementation (main.S)

The following code was written in RV32I Assembly to control the GPIO registers directly.

\` assembly

PURE RISC-V ASSEMBLY FOR ESP32-C6

GPIO Base: 0x60091000

Offsets: Enable (+0x20), Set (+0x08), Clear (+0x0C)

.section .text .global app_main

app_main: # 1. Enable GPIO 14 as Output li t0, 0x60091000 # Load GPIO Base Address li t1, (1 << 14) # Bitmask for Pin 14

addi t3, t0, 0x20      # t3 = GPIO_ENABLE_REG
sw t1, 0(t3)           # Physically set pin to Output

loop: # 2. Set GPIO 14 HIGH (Turn LED ON) addi t3, t0, 0x08 # t3 = GPIO_OUT_W1TS_REG sw t1, 0(t3)

# 3. Delay (Busy-Wait Loop)
li t2, 5000000

1: addi t2, t2, -1 bnez t2, 1b

# 4. Set GPIO 14 LOW (Turn LED OFF)
addi t3, t0, 0x0C      # t3 = GPIO_OUT_W1TC_REG
sw t1, 0(t3)

# 5. Delay
li t2, 5000000

2: addi t2, t2, -1 bnez t2, 2b

j loop

\`

interface Caption: main.S page

Step 5: Successful Build and Flash

With a clean environment, the native compilation was successful.

  • Compiling: Executed idf.py build . This step took several minutes as it compiled the underlying system libraries for the RISC-V core.

  • Flashing: Deployed the code via the specific Mac USB port:

    idf.py -p /dev/tty.usbmodem101 flash monitor

    interface

Caption: flashing process

  • Result: The hardware responded immediately—the LED on the GLYPH C6 began to blink.

Step 6: Researching the "Magic Numbers"

To understand why the code worked, I moved from the general datasheet to the internal hardware specifications.

  • Documentation Search: Realized the General Datasheet lacks register-level details. Switched to the Technical Reference Manual (TRM).
  • Finding the Base Address: In Chapter 2 (Peripheral Address Mapping), I confirmed the GPIO Matrix is located at 0x60091000.
  • Understanding Hex Offsets:
    • 0x20: Enable Register (Sets the pin direction to Output).
    • 0x08: Set Register (Pull pin High/3.3V).
    • 0x0C: Clear Register (Pull pin Low/0V).

Code Logic & Observations

Analyzing the handwritten Assembly provided deep insights into processor behavior:

  1. Bitmasking: Learned that GPIOs are controlled via a 32-bit word. Defining "Pin 14" requires a math operation: (1 << 14), which flips the 14th "switch" in the control register.
  2. Addressing Limits: Discovered that RISC-V sw (store word) instructions cannot jump to a 32-bit address in a single step. I had to use addi to calculate the specific register address into a temporary register first.
  3. Busy-Wait Delay: In Assembly, a "Delay" is not a command but a mathematical waste of time. The CPU counts down from millions to zero, staying 100% active just to create a visible pause.

ESP32-S3-DEV_KIT-N8R8

ESP32-S3-DEV-KIT-NxR8 is a compact-size microcontroller development board with multiple digital interfaces.

In terms of hardware, it adopts ESP32-S3-WROOM-1-NxR8 module, which is equipped with a dual-core Xtensa 32-bit LX7 processor with 240MHz running frequency, built-in 512 KB SRAM (TCM) and 8MB PSRAM. Onboard CH343 and CH334 chips for USB and UART development via USB-C port. Compatible with the pinout of ESP32-S3-DevKitC-1 development board, more convenient to use and expand a variety of peripheral modules.

Software support:

  • ESP-IDF
  • Arduino
  • MicroPython

Features

  • Adopts ESP32-S3-WROOM-1-NxR8 module with Xtensa 32-bit LX7 dual-core processor, capable of running at 240 MHz
  • Integrated 512KB SRAM, 384KB ROM, 8MB PSRAM, 8MB/16MB Flash memory
  • Integrated 2.4GHz WiFi and Bluetooth LE dual-mode wireless communication, with superior RF performance

Functional Block Diagram

image.png

Interfaces

image.png

Pinout

image.png

VSCode with PlatformIO

Development was done using Visual Studio Code with PlatformIO.

To install PlatformIO, install it from the VS Code extensions tab.

image.png

To start a new project, click on the new PlatformIO icon on the activity bar. Then click on Open in the quick access menu of PlatformIO. Using the New project option we can specify the name of project and type of board.

image.png

PlatformIO currently does not have a built-in board entry with that exact name in the official board list. However, the generic ESP32-S3 DevKitC series is a supported definition (Compatible with the pinout of ESP32-S3-DevKitC-1 development board).

That board definition assumes no PSRAM, so PSRAM needs to be enabled manually in platformio.ini. The main application code is written in src/main.cpp.

image.png

To include the Adafruit Neopixel library, search for it in the library tab on the PlatformIO quick access tab.

image.png

And then add it to your project

image.png

image.png

Code

cpp
#include <Adafruit_NeoPixel.h>

#define LED_PIN   48
#define LED_COUNT 1

Adafruit_NeoPixel led(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  led.begin();
  led.setBrightness(150);   // 0–255
  led.show();               // Initialize all pixels to OFF
}

void loop() {
  // Red
  led.setPixelColor(0, led.Color(255, 0, 0));
  led.show();
  delay(2000);

  // Green
  led.setPixelColor(0, led.Color(0, 255, 0));
  led.show();
  delay(2000);

  // Blue
  led.setPixelColor(0, led.Color(0, 0, 255));
  led.show();
  delay(2000);
}

Key points:

  • The RGB LED uses a single data pin with precise timing
  • NEO_GRB + NEO_KHZ800 matches the WS2812 protocol
  • Brightness is global and affects power consumption
  • GPIO 48 is the onboard RGB LED data pin on this board

2026-02-18_18-08.png

The RGB LED in the available dev kit was faulty, but to explore the toolchain we went through the entire process, just to check if the board was working simply blinked and external LED. using code-

cpp
#include <arduino.h>
#define LED_PIN 5

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(115200);
  delay(1000);
  Serial.println("start");
}

void loop() {
  digitalWrite(LED_PIN, HIGH);  // LED ON
  Serial.println("led on");
  delay(1000);
  digitalWrite(LED_PIN, LOW);  // LED OFF
  Serial.println("led off");
  delay(1000);
}

ATtiny44/84

Elements of the Toolchain for Programming ATtiny44/84

The embedded firmware for the ATtiny44/84 microcontroller was developed using the C programming language within the Microchip Studio 7 integrated development environment (IDE). The required device/board support packages were installed to enable proper hardware definitions and register mappings for the ATtiny family. Code compilation was performed using the AVR-GCC compiler, which translates C source files into AVR machine code. The compiled firmware was generated as a HEX file and uploaded to the microcontroller using AVRDUDE in combination with an AVR ISP hardware programmer such as USBasp or Atmel ICE.

Microchip Studio 7 (formerly Atmel Studio) provides a complete environment for writing, compiling, and debugging C/C++ and assembly code for AVR microcontrollers. After installing the IDE, we created a new AVR project by navigating to File → New → Project, selecting the target ATtiny device, and proceeding with code development.

image.png

Next, we selected the GCC C Executable Project template, assigned the project name “Blink_LED”, and clicked OK to proceed. This created a new project workspace configured for C-based firmware development using the AVR-GCC compiler.

image.png

In the next window, we searched for ATtiny84 and selected it as the target microcontroller. This automatically loaded the relevant device files, register definitions, and hardware support resources required for programming the selected chip, ensuring proper configuration of the project environment.

image.png

After selecting the device, the IDE automatically opened a main.c file (shown as main.cpp in the interface) containing a basic template to simplify program development. we began writing a simple LED blink program by including the required time delay library for timing control. During this process, we referred to my instructor Saheen Palayi’s documentation for guidance. Once the code was completed, we navigated to Build → Compile to check for any compilation errors before proceeding further.

15_abi.jpg

Compiling the program alone is not sufficient in Microchip Studio, as the firmware must be converted into a HEX file before it can be uploaded to the microcontroller. To generate this file, we navigated to Build → Build Solution, which created the compiled output file Blink_LED.hex in the project’s Debug folder.

To program the ATtiny84 using my FAB TinyISP programmer, we needed to configure an external upload tool within Microchip Studio. Since Microchip Studio primarily supports official programmers such as Atmel-ICE, we manually added a custom external tool to interface with AVRDUDE. (Download Link : https://github.com/avrdudes/avrdude/releases?utm_source=chatgpt.com)

We added a new tool by navigating to Tools → External Tools, and entered the following argument configuration:

Argument : -c usbtiny -p attiny84 -U flash:w:$(ProjectDir)Debug\$(TargetName).hex:i

Next, we connected the target board to my computer using the FAB ISP programmer. Once the connection was established, we navigated to Tools → FAB-ISP in Microchip Studio to upload (flash) the generated HEX file onto the ATtiny microcontroller. This process transferred the compiled firmware to the board’s flash memory, enabling the program to run immediately after programming. Most common installing the USBtiny driver (Download link :https://zadig.akeo.ie/)

17_abi.jpg

Click Options → List All Devices >> Select something like >> USBtinyISP

image.png

After Installing the driver we tried again and it worked! It flashed at lightening speed, it was super quick compared to Arduino and MicroPython, because it is using Embedded C.

/*

  • Blink_LED.c
  • Created: 2/16/2026 9:20:17 AM
  • Author : ADMIN */

#define F_CPU 20000000UL // clock 20 MHz #include <avr/io.h> #include <util/delay.h>

int main(void) { DDRA |=(1<<3); // Set PA3 as OUTPUT

while (1)
{
	PORTA = PORTA|(1<<3);	// Set PA3 as HIGH(On)
	_delay_ms(1000);		// 1 second delay
	PORTA = PORTA&=~(1<<3);	// Set PA3 as LOW(Off)
	_delay_ms(1000);		// 1 second delay
}

}

image.png

Now we tried a new program to control a common Anode Neo Pixel connected on PA5 PA6 and PA7 Pins of ATtiny84.

/*

  • Blink_LED.c
  • Created: 2/16/2026 9:20:17 AM
  • Author : ADMIN */

#define F_CPU 20000000UL // clock 20 MHz #include <avr/io.h> #include <util/delay.h>

int main(void) { DDRA |=(1<<5); // Set PA5 as OUTPUT DDRA |=(1<<6); // Set PA6 as OUTPUT DDRA |=(1<<7); // Set PA7 as OUTPUT

while (1)
{
	PORTA = PORTA|(1<<5);	// Set PA5 as HIGH(On)
	_delay_ms(500);			// 0.5 second delay

	PORTA = PORTA&=~(1<<5);	// Set PA5 as LOW(Off)
	PORTA = PORTA|(1<<6);	// Set PA6 as LOW(On)
	_delay_ms(500);

	PORTA = PORTA&=~(1<<6);	// Set PA6 as LOW(Off)
	PORTA = PORTA|(1<<7);	// Set PA6 as LOW(On)
	_delay_ms(500);

	PORTA = PORTA&=~(1<<7);	// Set PA7 as LOW(Off)
	PORTA = PORTA|(1<<5);	// Set PA5 as LOW(On)
	_delay_ms(500);

}

}

Once Code is ready we can click on Built>>Compile. Output will show Build succeeded. Now we can Upload the using Tool >> FAB ISP and Done! It will flash very quickly compared to Arduino and MicroPython.

image.png

Elements of the Toolchain for Programming ATtiny44/84

The embedded firmware for the ATtiny44/84 microcontroller was developed using the C programming language within the Microchip Studio 7 integrated development environment (IDE). The required device/board support packages were installed to enable proper hardware definitions and register mappings for the ATtiny family. Code compilation was performed using the AVR-GCC compiler, which translates C source files into AVR machine code. The compiled firmware was generated as a HEX file and uploaded to the microcontroller using AVRDUDE in combination with an AVR ISP hardware programmer such as USBasp or Atmel ICE.

Microchip Studio 7 (formerly Atmel Studio) provides a complete environment for writing, compiling, and debugging C/C++ and assembly code for AVR microcontrollers. After installing the IDE, we created a new AVR project by navigating to File → New → Project, selecting the target ATtiny device, and proceeding with code development.

image.png

Next, we selected the GCC C Executable Project template, assigned the project name “Blink_LED”, and clicked OK to proceed. This created a new project workspace configured for C-based firmware development using the AVR-GCC compiler.

image.png

In the next window, we searched for ATtiny84 and selected it as the target microcontroller. This automatically loaded the relevant device files, register definitions, and hardware support resources required for programming the selected chip, ensuring proper configuration of the project environment.

image.png

After selecting the device, the IDE automatically opened a main.c file (shown as main.cpp in the interface) containing a basic template to simplify program development. we began writing a simple LED blink program by including the required time delay library for timing control. During this process, we referred to my instructor Saheen Palayi’s documentation for guidance. Once the code was completed, we navigated to Build → Compile to check for any compilation errors before proceeding further.

image.png

Compiling the program alone is not sufficient in Microchip Studio, as the firmware must be converted into a HEX file before it can be uploaded to the microcontroller. To generate this file, we navigated to Build → Build Solution, which created the compiled output file Blink_LED.hex in the project’s Debug folder.

To program the ATtiny84 using my FAB TinyISP programmer, we needed to configure an external upload tool within Microchip Studio. Since Microchip Studio primarily supports official programmers such as Atmel-ICE, we manually added a custom external tool to interface with AVRDUDE. (Download Link : https://github.com/avrdudes/avrdude/releases?utm_source=chatgpt.com)

We added a new tool by navigating to Tools → External Tools, and entered the following argument configuration:

Argument : -c usbtiny -p attiny84 -U flash:w:$(ProjectDir)Debug\$(TargetName).hex:i

image.png

Next, we connected the target board to my computer using the FAB ISP programmer. Once the connection was established, we navigated to Tools → FAB-ISP in Microchip Studio to upload (flash) the generated HEX file onto the ATtiny microcontroller. This process transferred the compiled firmware to the board’s flash memory, enabling the program to run immediately after programming. Most common installing the USBtiny driver (Download link :https://zadig.akeo.ie/)

image.png

Click Options → List All Devices >> Select something like >> USBtinyISP

image.png

After Installing the driver we tried again and it worked! It flashed at lightening speed, it was super quick compared to Arduino and MicroPython, because it is using Embedded C.

/*

  • Blink_LED.c
  • Created: 2/16/2026 9:20:17 AM
  • Author : ADMIN */

#define F_CPU 20000000UL // clock 20 MHz #include <avr/io.h> #include <util/delay.h>

int main(void) { DDRA |=(1<<3); // Set PA3 as OUTPUT

while (1)
{
	PORTA = PORTA|(1<<3);	// Set PA3 as HIGH(On)
	_delay_ms(1000);		// 1 second delay
	PORTA = PORTA&=~(1<<3);	// Set PA3 as LOW(Off)
	_delay_ms(1000);		// 1 second delay
}

}

image.png

Now we tried a new program to control a common Anode Neo Pixel connected on PA5 PA6 and PA7 Pins of ATtiny84.

/*

  • Blink_LED.c
  • Created: 2/16/2026 9:20:17 AM
  • Author : ADMIN */

#define F_CPU 20000000UL // clock 20 MHz #include <avr/io.h> #include <util/delay.h>

int main(void) { DDRA |=(1<<5); // Set PA5 as OUTPUT DDRA |=(1<<6); // Set PA6 as OUTPUT DDRA |=(1<<7); // Set PA7 as OUTPUT

while (1)
{
	PORTA = PORTA|(1<<5);	// Set PA5 as HIGH(On)
	_delay_ms(500);			// 0.5 second delay

	PORTA = PORTA&=~(1<<5);	// Set PA5 as LOW(Off)
	PORTA = PORTA|(1<<6);	// Set PA6 as LOW(On)
	_delay_ms(500);

	PORTA = PORTA&=~(1<<6);	// Set PA6 as LOW(Off)
	PORTA = PORTA|(1<<7);	// Set PA6 as LOW(On)
	_delay_ms(500);

	PORTA = PORTA&=~(1<<7);	// Set PA7 as LOW(Off)
	PORTA = PORTA|(1<<5);	// Set PA5 as LOW(On)
	_delay_ms(500);

}

}

Once Code is ready we can click on Built>>Compile. Output will show Build succeeded. Now we can Upload the using Tool >> FAB ISP and Done! It will flash very quickly compared to Arduino and MicroPython.

image.png

Toolchain & LED Blink Comparison

This comparison focuses specifically on toolchain setup and LED blink implementation across four microcontroller platforms. The evaluation is based only on practical experience with development environment configuration and basic GPIO blinking.

BoardDevelopment EnvironmentProgramming LevelBuild ProcessFlashing MethodBlink Implementation StyleObserved Complexity
Arduino Q (UNO R4 WiFi)Arduino IDE / Arduino CloudHigh-level C++Automatic compile & uploadUSB (One-click)digitalWrite()Very Easy
ESP32-C6VS Code + ESP-IDFC / Assembly (RISC-V)idf.py build (manual build system)idf.py flashDirect GPIO register controlHigh
ESP32-S3-DEV-KITVS Code + PlatformIOC++ (Arduino Framework)PlatformIO build systemUSB via PlatformIOdigitalWrite() / NeoPixel libraryMedium
ATtiny44/84Microchip Studio + AVR-GCCEmbedded CCompile → Generate HEXAVRDUDE + ISP ProgrammerDirect PORT register manipulationMedium (Low-level)

Summary Observations

  • Arduino Q provided the most beginner-friendly and abstracted workflow.
  • ESP32-C6 required the most advanced configuration and exposed low-level hardware interaction.
  • ESP32-S3 offered a structured ecosystem with moderate complexity.
  • ATtiny44/84 required manual compilation and flashing, giving deeper insight into embedded C and register-level programming.

Conclusion

The comparison highlights how toolchain structure and abstraction level vary significantly between platforms. While all four boards successfully executed a basic LED blink program, the setup complexity, build process, and programming depth differed substantially. This demonstrates how architecture and ecosystem design directly influence the embedded development experience.