This week focused on embedded programming fundamentals. Our group compared different microcontroller toolchains, while individually I explored the ESP-WROOM-32 architecture and implemented both local I/O interactions and wireless communication.
As part of the group assignment, I collaborated with Lauri Hallman and Shahmeer Adnan Rana to explore these microcontrollers specifically.
Platform | Arduino Nano | ESP-WROOM-32 |
---|---|---|
Development Environment | Arduino IDE | Arduino/Thorny IDE |
Language | C | C/MicroPython |
Architecture | AVR | RISC |
Processor | 8-bit AVR | 32-bit RISC |
Multi-core Support | Single-core | Dual-core |
I physically programmed my ESP-32S, with my already installed Arduino IDE installed on my system, as this is not my first rodeo, but I’ll walk you through the setup stage and let’s experience it again together.
Since I had Arduino already installed on my system, I clicked the Windows start menu and typed "Arduino" to access it. Arduino can also be installed from their website: https://www.arduino.cc/en/software
See below the default screen or sketch you would see on Arduino IDE, then go to File > Preferences:
Add ESP32 board URL in the “Additional boards manager URLs” (you can obtain the URL by searching on Arduino page for the GitHub link):
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Install ESP32 board support via Tools > Board > Boards Manager:
Select "ESP32 Dev Module" from Tools > Board:
void setup() {
// Initialization code
// Runs once at startup
}
void loop() {
// Main program code
// Runs repeatedly
}
I explored programming the LED on the board with the following program. This program is a modification of the LED blinking code given to us by Toni (my local instructor). This program will:
// Pin definitions
#define LED_PIN 2 // Onboard LED
#define BUTTON_PIN 0 // Boot button
void setup() {
pinMode(LED_PIN, OUTPUT);
ledcSetup(0, 5000, 8); // Channel 0, 5KHz, 8-bit resolution
ledcAttachPin(LED_PIN, 0); // Attach LED pin to channel 0
}
void loop() {
// Dramatic fade in
for(int i = 0; i < 255; i++) {
ledcWrite(0, i);
delay(5); // Slow, dramatic rise
}
delay(200); // Dramatic pause at peak brightness
// Quick flash sequence
for(int j = 0; j < 3; j++) {
ledcWrite(0, 0);
delay(50);
ledcWrite(0, 255);
delay(50);
}
// Dramatic fade out
for(int i = 255; i >= 0; i--) {
ledcWrite(0, i);
delay(10); // Slower, more dramatic fall
}
delay(500); // Dramatic pause in darkness
}
An example of WiFi implementation in a microcontroller was done during my summer internship at FabLab Oulu, where we (interns) designed an ioT freashers course at the University of Oulu, on “measurement of humidity and temperature” using the DHT22 and the PICO-W. See code snippet below:
#include
#define DHTPIN 14
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
}
void loop() {
delay(2000);
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from the sensor");
return;
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°C ");
Serial.println();
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.print("g/kg ");
Serial.println();
}
Using Wokwi online simulator to validate program logic before deployment:
In embedded systems development, managing memory constraints, ensuring power-efficient communication, and using simulation are key to creating reliable, efficient devices. This week I observed a trade off, in terms of usability (micropython) and language friendly implementation of programming micro-controllers, against efficiency using C programming (which is less friendly). Optimization, memory usage efficiency, power-efficient and extra features like Wi-Fi has become a norm. A delicate balance of these mix should be aimed at in order for example not to drain resources like battery life. Simulation platforms also helps in testing system behavior in various conditions, identifying issues early and ensuring robust performance. These practices are essential for building functional and optimized embedded systems.