Fab Academy 2026

Week 4: Embedded Programming

Exploring microcontrollers, datasheets, PWM, ADC and embedded programming using the ATmega328P and ESP32.

Assignments

Group Assignment

Individual Assignment

Microcontrollers

ESP32 and ATmega328P.

Concepts

PWM, ADC, timers, interrupts and embedded systems.

Main Project

A programmable electronic piano using PWM sound generation.

Group Assignment

This week, during the group assignment, I reinforced something important: the architecture of a microcontroller really affects performance, power consumption and even the way you approach development.

It’s not only about choosing a board that works. The internal structure shapes how the entire system behaves.

I also understood that the datasheet is not optional. It is the real manual of the device, and if you want to truly understand what you are doing, you have to read it carefully.

Another important lesson was about programming languages. Choosing a language is similar to choosing a microcontroller: there is no universal “best” option. The correct choice depends on the project requirements and development goals.

Group Assignment – Embedded Programming

ESP32 Datasheet Research

For my final project, I evaluated several microcontrollers to determine which one best suited my needs.

I analyzed specifications, power consumption and available features before deciding to use the ESP32 because of its integrated Wi-Fi and Bluetooth capabilities.

ESP32 Datasheet

Operating Voltage

3.0V – 3.6V with 3.3V logic levels.

Wireless Features

Built-in Wi-Fi and Bluetooth Low Energy support.

Low Power

Deep sleep current in the microamp range.

Important ESP32 Features

Electrical Characteristics

  • Operating Voltage: 3.0V - 3.6V
  • Logic Level: 3.3V
  • Active mode current: tens of mA
  • Deep sleep current: ~5 µA typical

Sleep Modes

  • Active mode
  • Modem sleep
  • Light sleep
  • Deep sleep

ADC

  • 1 ADC unit
  • Up to 6 channels
  • 12-bit resolution

PWM

  • Up to 6 PWM channels
  • Adjustable frequency
  • Adjustable resolution

Bluetooth LE

  • Bluetooth 5 LE support
  • Low power communication
  • Central or peripheral mode

Piano Project

For one of my classes, I was asked to build a piano using an ATmega328P.

By configuring PWM correctly, I generated different frequencies so the buzzer could reproduce musical notes.

The system also adjusted both volume and octave using potentiometers connected to the ADC.

First, I assembled the hardware connections and arranged the protoboard to resemble a small piano layout.

Piano protoboard assembly

First Attempt

My first attempt failed because the PWM configuration was incorrect, so the generated frequencies sounded distorted and out of tune.

Oscilloscope Testing

I used an oscilloscope to verify the generated frequency and duty cycle.

Final Result

After many iterations, I finally achieved the correct frequency and duty cycle for each musical note.

A friend helped me test the piano while I recorded the final demonstration.

Final Piano Code

Here is the final code used for the piano project:


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

uint8_t Top=0;
uint8_t nota=0;
uint16_t valor=0;
uint16_t octava=1;
uint16_t valor2=0;
float volumen=0.5;
int modo=0;
int matriz[10][1];
int i=0;

void interrupcion(){
PCICR|=(1<<PCIE0);
PCMSK0|=(1<<PCINT3)|(1<<PCINT4);
DDRB&=~((1<<PB3)|(1<<PB4));
sei();
}

ISR(PCINT0_vect){

if(PINB&(1<<PINB3)){
modo++;
_delay_ms(200);
}

if(modo==1){
PORTB&=~(1<<PB7);
TCCR1A&=~(1<<COM1B1);
}

if(modo==2){
PORTB|=(1<<PB7);
TCCR1A&=~(1<<COM1A1);
}

if(modo==3){
modo=0;
PORTB&=~(1<<PB7);
TCCR1A&=~(1<<COM1A1);
TCCR1A&=~(1<<COM1B1);

for(i=0;i<10;i++){
matriz[i][0]=0;
}
}

if(PINB&(1<<PINB4)){
i++;
matriz[i][0]=nota;
_delay_ms(100);

if(i>=10){
i=0;
}
}
}

void PWM1(){
TCCR1A|=(1<<COM1A1)|(1<<COM1B1);
TCCR1B|=(1<<CS11);
TCCR1A|=(1<<WGM11);
TCCR1B|=(1<<WGM12)|(1<<WGM13);
DDRB|=(1<<PB1)|(1<<PB2);
}

The full program manages ADC readings, interrupts and PWM signal generation to create different musical notes and volume levels.

Connection to My Final Project

This week’s work directly supports the development of my final project.

Building the piano helped me understand how important PWM and ADC configuration are in embedded systems.

That experience gave me a better understanding of timers, signal generation and hardware-level programming.

While reviewing the ESP32 datasheet, I focused on specifications related to my wearable device.

Power Consumption

Sleep modes are important for battery life optimization.

Sensor Readings

ADC functionality will be used for heart rate sensor integration.

Vibration Motor

PWM control will allow smooth vibration feedback for the wearable.

Overall, this week helped me move from simply programming to making informed technical decisions for my final project.