Week 9: Input Devices

Assignments

Group Assignments:

Individual assignments

Group Assignment

Group Assignment – Input Devices

What 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

Proceso 1

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.

Proceso 1

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.

Proceso 1

Testing with a Protoboard

Before testing, it’s important to know how to correctly place the electrodes on your body.

Proceso 1

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.

Downloadable Files

Zip with all the files I used this week