Week 9: Input Devices
Assignments
Group Assignments:
- Characterize the design rules for your in-house PCB production process: document the settings for your machine.
- Document your work on the group work page and reflect on your individual page what you learned
Individual assignments
- Measure something: add a sensor to a microcontroller board that you have designed and read it.
Group Assignment
Group Assignment – Input DevicesWhat I Learned from the Group Assignment
From the group assignment, I mainly reinforced concepts I had already learned, such as the difference between analog and digital signals. I also reviewed how I2C communication works, including the roles of SDA and SCL. One of the most useful parts was using an oscilloscope to visualize real sensor signals, which helped me confirm how these concepts apply in practice. Overall, this assignment helped me solidify my understanding and gave me more confidence when working with sensors beyond just the code.
Individual Assignment
Max30102
First I wanted tu used the Max30102, that is a heart rate and oxymeter sensor, but I had problems connecting it to my XIAO2350, because all the hardware was correctly wired but still the XIAO could not detect the sensor
I will continue trying to use this sensor because of its potential application to my final project and if this continues to fail I will have to search for another microcontroller or sensor
AD8232 Heart Monitor
After running into issues with the Max30102, I decided to try the AD8232 Heart Monitor instead. This sensor probably won’t fit into my final project because of its size, but I still wanted to use it to get familiar with reading heart rate signals.
The first thing I did was look up the pinout to understand how to connect it properly.
I connected GND to the XIAO’s GND, 3.3V to 3.3V, and the output pin to D0 (any analog pin works). Finally, I connected LO- and LO+ to D1 and D2 respectively (any digital pins work).
I used D0 to read the analog signal from the sensor, which the XIAO converts into a digital value that can be processed. The LO- and LO+ pins are connected to digital pins so the XIAO can detect whether the electrodes are properly attached.
Testing with a Protoboard
Before testing, it’s important to know how to correctly place the electrodes on your body.
Making the PCB
Note: I didn’t have pin headers available, so I improvised using jumper wires that I cut, stripped, and soldered.
After assembling the PCB, I tested it again to make sure everything was still working correctly.
Code
#include <avr/io.h>
const int ECG_PIN = A0; //Analog pin used to read the ECG sensor signal (continuous voltage values)
const int LO_MAS = 2; //Digital pin that detects if the positive electrode is disconnected
const int LO_MENOS = 3; //Digital pin that detects if the negative electrode is disconnected
const int LED_PIN = D6; //Output pin used to control the LED
int threshold = 550;
//Signal threshold used to detect a heartbeat.
//If the ECG signal rises above this value, it is considered a potential beat.
bool lastBeat = false;
//Stores whether a beat was already detected.
//Prevents counting the same heartbeat multiple times.
unsigned long lastBeatTime = 0;
//Stores the time (in milliseconds) of the last detected beat.
//Used to calculate the time interval between beats (for BPM).
//Array used to store the last 5 BPM values.
//This allows calculating a more stable average instead of relying on a single reading.
int bpmArray[5] = {0,0,0,0,0};
int bpmIndex = 0;
int baselineBPM = 75; //Estimated resting heart rate (baseline for comparison)
int aumento= 10; //Threshold above baseline to detect a significant increase in heart rate
bool alerta = false; //Flag that indicates whether a high heart rate condition has been detected
//Variables used to control LED blinking without blocking the program
unsigned long lastBlink = 0;
bool ledState = false;
void setup() {
Serial.begin(115200); //Initializes serial communication for monitoring BPM values
//Set electrode detection pins as inputs and set LED pin as output
pinMode(LO_MAS, INPUT);
pinMode(LO_MENOS, INPUT);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
//Check if electrodes are properly connected
if (digitalRead(LO_MAS) == 1 || digitalRead(LO_MENOS) == 1) {
Serial.println("Electrodos desconectados");
digitalWrite(LED_PIN, LOW);
return; //Exit loop early if signal is not reliable
}
int signal = analogRead(ECG_PIN); //Read ECG signal (value between 0–1023)
//Detect heartbeat
if (signal > threshold && !lastBeat) {
unsigned long currentTime = millis();
//Time filter to avoid false detections (noise)
if (currentTime - lastBeatTime > 600) {
if (lastBeatTime != 0) {
int bpm = 60000 / (currentTime - lastBeatTime); //BPM calculation based on time difference between beats
//Filter unrealistic BPM values
if (bpm > 40 && bpm < 100) {
bpmArray[bpmIndex] = bpm;
bpmIndex = (bpmIndex + 1) % 5; //Circular buffer to store last 5 BPM values
//Calculate average BPM
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += bpmArray[i];
}
int avgBPM = sum / 5;
Serial.print("BPM promedio: ");
Serial.println(avgBPM);
//Detect increase relative to baseline
if (avgBPM > baselineBPM + aumento) {
alerta = true;
Serial.println("AUMENTO DETECTADO");
} else {
alerta = false;
}
}
}
lastBeatTime = currentTime;
}
lastBeat = true;
}
//Reset detection when signal goes below threshold
if (signal < threshold) {
lastBeat = false;
}
//LED blinking behavior during alert condition
if (alerta) {
if (millis() - lastBlink > 500) { // velocidad del parpadeo
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
lastBlink = millis();
}
} else {
digitalWrite(LED_PIN, LOW);
}
delay(5);
}
Mistakes and How I Solved Them
Incorrect pin
At first, I defined the LED pin in my code like this: const int LED_PIN = 6; or const int LED_PIN = D7;.
To fix this, I checked the XIAO pinout and explicitly defined the pin as D6 in the code instead of just using the number. This helped avoid confusion and made sure the correct pin was used.
Incorrect BPM values
At the beginning, the BPM values were not accurate because of an issue with how I was calculating the time difference between beats. I fixed this by making sure the time was handled in milliseconds and that the BPM calculation was done correctly.
LED didn’t stop blinking
Because the BPM calculation was wrong, the system kept detecting a high heart rate, so the LED never stopped blinking.
To fix this, I implemented an array to store the last 5 BPM values and calculate an average. I also adjusted the baseline heart rate, which made the detection much more stable.