Embedded Programming¶
This week was my introduction to embedded programming, so this was the first contact with the logic inside electronic devices.
The core idea I took from the lectures is simple. An embedded system is a small computer inside a device. It is designed for a specific task and often needs to react in real time. Unlike a laptop or phone, which can run many programs, an embedded system usually does one thing, but does it reliably and immediately.
GLobal Class¶
Microprocessors and microcontrollers¶
One of the first distinctions we discussed was the difference between a microprocessor and a microcontroller.
A microprocessor is only the CPU and needs external memory and peripherals to function.
A microcontroller includes the CPU, memory, and peripherals in a single chip.
Most of the boards we use in the lab are based on microcontrollers. They are small, inexpensive, and designed to interact directly with sensors, motors, lights, and other components.
Processor families¶
Choosing a processor was described as something similar to choosing a CAD tool. It is partly technical, and partly personal preference. The choice depends on cost, power, connectivity, and ecosystem.
Some of the main families we discussed were:
- AVR: simple, low cost, and very common in classic Arduino boards.
- ARM: modern 32-bit architecture used in many powerful microcontrollers.
- ESP32: microcontroller with built-in Wi-Fi and Bluetooth, designed for connected devices.
- RISC-V: open-source processor architecture.
- Raspberry Pi: not a microcontroller, but a full single-board computer that runs an operating system.
Languages in embedded systems¶
Two main languages were discussed.
C - The most common language in embedded systems. - Efficient and fast. - Good for real-time control. - Used in the Arduino ecosystem.
Python - Higher-level language. - Used for logic, AI, and more complex systems. - Often combined with C.
For example, on a Raspberry Pi: - C may control hardware and peripherals. - Python may handle logic or AI tasks.
We were also reminded that AI tools are useful, but they make mistakes, so the datasheet and testing remain essential.
Local class — practical concepts¶
In the local session, we focused more on the practical side.

Compiled code¶
We worked with C, which is a compiled language. This means we write the code, the Arduino IDE compiles it into machine code, and then that machine code is uploaded to the microcontroller.
Pinout¶
One of the most important concepts is the pinout. A pinout diagram shows:
- Power pins
- Ground pins
- Digital input/output
- Analog inputs
- Communication pins
- Programming pins
Understanding the pinout is essential before wiring or programming a board.
We looked at the ATTiny pinout from the datasheet and identified the different types of pins.
From this, I learned: - Pins are grouped by ports such as PA and PB. - Some pins are analog-capable. - Some pins are dedicated to programming or reset functions.

Development workflow¶
A few basic concepts were introduced.
In-system programming - Uploading the program directly into the device, often via USB.
Development environment - The software used to write and upload code. - In our case, mainly the Arduino IDE.
Simulation - We used Wokwi to emulate boards and test circuits and code without physical hardware.

Comparing microcontrollers¶

To simplify the landscape, we used analogies.
| Microcontroller | Analogy | Main characteristic |
|---|---|---|
| ATTiny | Moped | Very small, simple tasks, minimal resources |
| CH32 | Scooter | Very cheap 32-bit option for basic applications |
| ATSAMD | Golf | Balanced, reliable, good general-purpose MCU |
| RP2040 | Sports car | Fast, powerful, suited for demanding tasks |
| ESP32 | Chinese electric car | Built-in Wi-Fi and Bluetooth connectivity |
Simple component: resistor¶
A resistor: - Limits or controls electric current. - Measured in ohms. - Commonly used to protect LEDs.

Basic LED, serial, and buzzer test¶
In the first program, I printed messages to the serial monitor, turned an LED on and off, and played a tone on a buzzer.
This helped me understand:
- The structure of setup() and loop().
- How digital outputs work.
- How serial communication helps with debugging.

void setup() {
Serial.begin(115200);
Serial.println("Hello, buddy!");
pinMode(2, OUTPUT);
}
void loop() {
digitalWrite(2, HIGH);
delay(400);
Serial.println("Hello, buddy!");
digitalWrite(2, LOW);
delay(400);
Serial.println("bye!");
tone(40, 440, 500);
}
Morse code experiment¶
We also ran a simple Morse code example. The program uses tone durations and delays to create the pattern.
void setup() {
}
void loop() {
tone(46, 440, 600);
delay(800);
tone(46, 440, 600);
delay(800);
tone(46, 440, 600);
delay(800);
tone(46, 440, 200);
delay(400);
tone(46, 440, 200);
delay(400);
tone(46, 440, 200);
delay(400);
tone(46, 440, 600);
delay(800);
tone(46, 440, 600);
delay(800);
tone(46, 440, 600);
delay(800);
}

Datasheets¶
Microcontroller selection for Asfalt¶
For the datasheet assignment, I decided to analyze the microcontroller that would make the most sense for the Asfalt project.
The main functional requirement of this system is simple:
- Read temperature from a sensor.
- Control a heating element.
- Remain stable, predictable, and safe over long periods.
From the microcontrollers reviewed in class, I compared the main options using practical criteria: functionality, price, power, pins, memory, speed, and development experience.
Selection criteria¶
The microcontroller for Asfalt should:
- Read analog or digital temperature sensors.
- Control a heater through PWM or digital output.
- Have enough memory for control logic and future features.
- Be affordable for small-scale production.
- Be easy to program and debug.
Decision¶
Based on these criteria, I selected the Seeed XIAO SAMD21 as the best overall fit.
Reasoning table¶
| Factor | Why Seeed XIAO SAMD21 is a strong choice |
|---|---|
| Functionality | Multiple ADC channels and PWM timers make it ideal for temperature sensing and heater control. |
| Price | Around €5–€6 for a complete board with USB, which is a good balance between cost and capability. |
| Power consumption | Efficient 32-bit Cortex-M0+ core, suitable for long-running embedded systems. |
| Pins and expandability | Enough GPIO for sensors, heater control, and future UI elements like buttons or displays. |
| Memory and speed | 48 MHz CPU, about 256 KB Flash and 32 KB SRAM, giving comfortable space for control logic and future features. |
| Developer experience | Native USB and full Arduino compatibility allow fast iteration and simple debugging. |
| Toolchain and ecosystem | Well supported in Arduino IDE and PlatformIO with many available libraries. |
| Prototype to product path | Stable, widely used MCU family, making it easier to move from prototype to production. |

Data Sheet¶
The next step was to review the SAMD21 datasheet and extract the specific sections related to the feature I need for Asfalt and make sure its a good fit.

Even though the document is extremely long, it was well structural and not too technical language, and with the help of AI, I could come up with the following table:
SAMD21 features relevant to the Asfalt cooking system¶
| Feature from datasheet | What it means | How it fits Asfalt |
|---|---|---|
| 32-bit Cortex-M0+ at 48 MHz | Modern, efficient processor | Enough power for temperature control, safety logic, and user interface |
| Up to 256 KB Flash, 32 KB SRAM | Program and data memory | Space for control algorithms, cooking profiles, and future features |
| Up to 52 programmable I/O pins | Many input/output connections | Connect sensors, heater control, buttons, LEDs, and displays |
| 12-bit ADC (up to 20 channels) | Reads analog signals | Accurate temperature sensing from thermistors or analog sensors |
| 10-bit DAC | Analog output capability | Optional analog control or feedback features |
| Timer/Counters (TC, TCC) | Precise timing and waveform generation | PWM control of heating element or motors |
| Timers optimized for control | Specialized control timers | Smooth and efficient heater power regulation |
| Real-Time Clock (RTC) | Internal timekeeping | Cooking timers and duration tracking |
| Peripheral Touch Controller | Capacitive touch buttons, sliders, wheels | Touch-based interface for temperature or time selection |
| SERCOM communication modules | UART, SPI, I2C communication | Connect digital sensors, displays, or expansion modules |
| USB 2.0 interface | Native USB connection | Easy programming and firmware updates |
| Watchdog timer + brown-out detector | Safety and reset features | Protects against crashes and unstable power conditions |
| Event system | Peripherals communicate without CPU | Faster and more reliable control behavior |
| Sleep modes (Idle, Stand-by) | Low power operation | Energy saving when idle or maintaining temperature |
| SleepWalking | Peripheral-based wake-up | Efficient temperature monitoring without full CPU activity |
| DMA controller | Moves data without CPU load | Smooth sensor reading or display updates |
The SAMD21 fits Asfalt because it can read temperature, control heater power, includes built-in safety and timing features, supports modern touch interfaces, and leaves room for future features without increasing cost or complexity.
Simulation of Final Project¶
I decided to do an simulation exercise of Wokwi to start getting familiar with SAMD21. I noticed that the microcontroller isn’t supported. So I checked with ChatGPT which option would the most suitable and recommended Raspberry Pi Pico Simulator within Wokwi.
Then I realized that SAMD21 doesn’t not use MicroPython, which was my language choice for its ease of use.
Choosing programming language vs microcontroller¶
For the simulation phase, I decided to prioritize ease of learning and fast iteration. MicroPython offers a simpler syntax and quicker feedback, which makes it more suitable for early exploration.
Since the SAMD21 is mainly used with C/C++ and has limited MicroPython support, the simulation in Wokwi will use the RP2040 microcontroller, which was designed to work well with MicroPython.
Wokwi simulation: Asfalt temperature controller¶
To complete the embedded programming assignment, I built a simple temperature control system in Wokwi using a Raspberry Pi Pico. The goal was to understand the basic logic of an embedded control loop: read inputs, make a decision, drive outputs, and implement safety.
The simulated system includes:
- NTC temperature sensor (analog input)
- Potentiometer as temperature setpoint
- LED as heater output (PWM)
- Buzzer as alarm
- Serial output for communication and debugging

Individual component tests¶
Before assembling the full system, each component was wired and tested independently to confirm that both the connections and the code were working correctly.
-
The NTC temperature sensor was first connected to an analog pin, and a simple program was used to read and print the ADC values to the Serial monitor. The readings changed as the temperature slider was adjusted, confirming proper analog input behavior.
-
Next, the setpoint potentiometer was connected to a second analog pin. The program read both the temperature sensor and the potentiometer simultaneously.
-
The heater LED was then wired in series with a resistor to a digital output pin. A simple blinking program was uploaded to verify the output.
-
Finally, the buzzer was connected to a digital pin and tested using a tone function, producing a repeating sound, to confirm correct wiring and output control.
Testing each component individually made it easier to detect wiring mistakes and verify the behavior of inputs and outputs before integrating the full control system.

Final integrated simulation¶
After verifying each component, the full control program was uploaded.
The system performs the following logic:
- Reads temperature from the NTC sensor.
- Reads the desired setpoint from the potentiometer.
- Compares the two values.
- Turns the heater (LED) on or off with PWM based on the error.
- Applies hysteresis to prevent rapid switching.
-
Cuts off the heater if:
- Temperature exceeds a safety limit.
- Heater remains on too long.
-
Emits a buzzer sound:
- When entering the target temperature band.
- When a safety condition occurs.
-
Prints system status to the Serial monitor.
Control logic summary¶
The program acts as a simple thermostat:
- If temperature is below the setpoint → heater turns on.
- As temperature approaches the setpoint → heater power decreases.
- If temperature is above the setpoint → heater turns off.
- Safety logic overrides everything if limits are exceeded.
Full control program¶
// ASfalt Wokwi exercise (Pi Pico / RP2040 - Arduino C++)
// NTC -> GP26
// Potentiometer -> GP27
// Heater LED -> GP15
// Buzzer -> GP5
const int PIN_TEMP = 26;
const int PIN_SET = 27;
const int PIN_HEAT = 15;
const int PIN_BUZZ = 5;
const float TEMP_MIN_C = 0.0;
const float TEMP_MAX_C = 80.0;
const float SET_MIN_C = 40.0;
const float SET_MAX_C = 80.0;
const float HYST_C = 1.5;
const float OVER_C = 78.0;
const unsigned long MAX_ON_MS = 20000;
bool heaterOn = false;
unsigned long heaterOnSince = 0;
bool reachedBeeped = false;
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
if (x < in_min) x = in_min;
if (x > in_max) x = in_max;
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void beep(int freq, int ms) {
tone(PIN_BUZZ, freq, ms);
delay(ms + 10);
}
void setup() {
Serial.begin(115200);
pinMode(PIN_HEAT, OUTPUT);
pinMode(PIN_BUZZ, OUTPUT);
}
void loop() {
int rawTemp = analogRead(PIN_TEMP);
int rawSet = analogRead(PIN_SET);
float tempC = mapFloat(rawTemp, 0, 1023, TEMP_MIN_C, TEMP_MAX_C);
float setC = mapFloat(rawSet, 0, 1023, SET_MIN_C, SET_MAX_C);
// Safety: over-temperature
if (tempC >= OVER_C) {
analogWrite(PIN_HEAT, 0);
heaterOn = false;
reachedBeeped = false;
beep(1200, 200);
delay(200);
return;
}
// Bang-bang control with hysteresis
if (!heaterOn && tempC <= (setC - HYST_C)) {
heaterOn = true;
heaterOnSince = millis();
reachedBeeped = false;
} else if (heaterOn && tempC >= (setC + HYST_C)) {
heaterOn = false;
}
// Safety: max continuous ON time
if (heaterOn && (millis() - heaterOnSince > MAX_ON_MS)) {
heaterOn = false;
beep(900, 150);
beep(900, 150);
}
// Heater PWM
int pwm = 0;
if (heaterOn) {
float error = setC - tempC;
float pct = mapFloat(error, 0, 25, 0.20, 1.0);
pwm = (int)(pct * 255);
if (pwm < 0) pwm = 0;
if (pwm > 255) pwm = 255;
}
analogWrite(PIN_HEAT, pwm);
// Feedback beep when in target band
bool inBand = (tempC >= (setC - HYST_C)) && (tempC <= (setC + HYST_C));
if (inBand && !reachedBeeped) {
beep(700, 80);
reachedBeeped = true;
}
if (!inBand) reachedBeeped = false;
delay(250);
}
Learning outcomes and reflection¶
This week was about simulating the basic structure of an embedded system by wiring and testing both analog and digital components. I tried to apply the concepts for my final project, which with my experience of the logic of a cooking system, I could apply to a step by step sequence of the different components.
As I am familiar with sensors, leds, temperature control, thermostats, etc. from the commercial and user side, it made it easier to understand the back-end and use AI to aid on the coding of the desired result.
This exercise made it clearer how a microcontroller manages a real-time control task similar to the core function required for the Asfalt cooking system. The logic of sensing, deciding, and acting became more tangible once it was connected to a concrete use case.
This was my first real step into helping me understand what I need the equipment to do and how to acheive it, with the possiblity of changing, improving, adding features along the way based on feedback from users. It is powerful to know I can potentially modify all of this.
Use of AI Tools¶
I want to choose the ideal microcontoller that would potentially wrokd best for Asfalt project. So first, help me choose the optimal microcontroller from the ones we reviewed previously to decide which one would be the best fit in terms of funcionality, price, power, pins, memory, speed, etc (please choose variables from standard sources). The specifis for theis priject are: read temperature and control heating element. Explain reasoning so I can understand decision first. Then we can would move forward into analyzing datasheet of this particular micocontroller.
From the general description section of the SAMD21 datasheet, identify and extract the features that are relevant for a cooking control system like Asfalt. Focus on characteristics useful for temperature sensing, heater control, user interfaces (such as touch buttons or wheels), timing functions, lighting or motor control, and power management features like sleep or idle modes. Explain how each feature could be used in this specific application.
Write an Arduino C++ program for a Raspberry Pi Pico that simulates a cooking control system.
The system should read temperature from an analog NTC sensor, read a setpoint from a potentiometer, and control a heater output (LED) using PWM.
Include hysteresis to prevent rapid switching, a safety cutoff for over-temperature, a maximum heater on-time, and a buzzer for feedback.
The program should also print system status to the Serial monitor.
The generated code was then:
- Reviewed and simplified.
- Tested module by module.
- Adapted to match the wiring in the Wokwi simulation.
- Documented and integrated into the final system.
AI was used as a support tool for structuring the logic and syntax, while the wiring, testing, and integration decisions were made manually.