Week 4: Embedded Programming

Assignments

Group Assignments:

Individual assignments

Group Assignment

This week, during the group assignment, I reinforced something important: the architecture of a microcontroller really does affect performance, power consumption, and even the way you approach development. It’s not just about picking a board that works. The internal structure actually shapes how the whole system behaves

I also understood that the datasheet isn’t optional. It’s not just extra documentation. It’s the real manual of the device, and if you want to truly understand what you’re doing, you have to read it.

Another key lesson was about programming languages. Choosing a language is similar to choosing a microcontroller. There isn’t a “best” option. The right choice depends on what your project needs, how much performance it requires, and how you plan to develop it.

Group Assignment – Embedded Programming

Individual Assignment

Datasheet

For my project I checked many microcontrollers to see which one would be best suited for my needs. I looked at their specifications, power consumption, and available features to make an informed decision, I decided to use the ESP32 because it has built-in Wi-Fi and Bluetooth

Here is the link for the data sheet: ESP32 Datasheet

Electrical Characteristics

Sleep Modes

ADC (Analog-to-Digital Converter)

PWM (LEDC – Hardware PWM)

Bluetooth Low Energy (BLE)

Piano

For one of my classes, I was asked to build a piano using an ATmega328P. By configuring the PWM correctly, I had to generate different frequencies so the buzzer could reproduce the musical notes being played.

The system also needed to adjust both the volume and the octave using different potentiometers, which were read through the ADC.

First, I assembled the hardware connections. I wanted the protoboard to resemble a small piano layout. After completing the circuit, I programmed the microcontroller in C to manage the inputs, ADC readings, and PWM signal generation.

Proceso 1

My first attempt at programming the piano failed because I did not configure the PWM settings correctly. As a result, the buzzer was not generating the correct frequency, and the notes sounded distorted and out of tune.

I tested the piano using an oscilloscope to verify that I was generating the correct frequency and duty cycle.

After many attempts, I was finally able to achieve the correct frequency and duty cycle for each note. A friend helped me test the piano while I was recording the final result.

Here is the final code I used for the piano:

#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);
}

void ADC1(){
ADMUX=(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}

uint16_t valor_adc(uint8_t ch){
ch&=0b111;
ADMUX=(ADMUX&0b11111000)|ch;
ADCSRA|=(1<<ADSC);
while(ADCSRA&(1<<ADSC));
return ADC;
}

int main(){
ADC1();
interrupcion();
DDRD=0x00;
DDRB|=(1<<PB7);

while(1){

if(modo==0){
PORTB|=(1<<PB7);
}

valor=valor_adc(0);
valor2=valor_adc(1);

while(modo==1){

if(valor<408){octava=1;}
if((valor>512)&&(valor<717)){octava=2;}
if(valor>921){octava=4;}

if(valor2<408){volumen=0.3;}
if((valor2>409)&&(valor2<614)){volumen=0.5;}
if((valor2>615)&&(valor2<818)){volumen=0.7;}
if((valor2>819)&&(valor2<1023)){volumen=0.9;}

if(PIND&(1<<PIND0)){nota=1;}
if(PIND&(1<<PIND1)){nota=2;}
if(PIND&(1<<PIND2)){nota=3;}
if(PIND&(1<<PIND3)){nota=4;}
if(PIND&(1<<PIND4)){nota=5;}
if(PIND&(1<<PIND5)){nota=6;}
if(PIND&(1<<PIND6)){nota=7;}
if(PIND&(1<<PIND7)){nota=8;}

switch(nota){

case 1: PWM1(); Top=119/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 2: PWM1(); Top=106/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 3: PWM1(); Top=95/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 4: PWM1(); Top=90/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 5: PWM1(); Top=80/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 6: PWM1(); Top=71/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 7: PWM1(); Top=63/octava; OCR1A=Top*volumen; ICR1=Top; break;
case 8: PWM1(); Top=60/octava; OCR1A=Top*volumen; ICR1=Top; break;

default: break;
}

_delay_ms(400);
nota=0;
}
}
}
}

Connection Between This Week and My Final Project

This week’s work will directly support the development of my final project. Building the piano helped me understand how important it is to properly configure the PWM and ADC. That experience gave me a better understanding of how timers and signal generation work at the hardware level.

While reviewing the ESP32 datasheet, I focused on specifications that relate directly to my wearable. I analyzed the operating voltage and sleep modes to understand power consumption and battery life. I also reviewed the ADC for sensor readings and the PWM features to control the vibration motor.

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