Fab Academy 2026

Week 9: Input Devices

Reading biometric data using heart rate sensors and integrating them with a custom microcontroller workflow.

Main Sensors

MAX30102 and AD8232 heart monitor

Main Board

Seeed Studio XIAO RP2350

Main Goal

Read heart rate data and detect BPM changes for my final wearable project.

Assignments

Group Assignment

Individual Assignment

Group Assignment

Group Assignment – Input Devices

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.

Initial Sensor Exploration

MAX30102

First, I wanted to use the MAX30102 because it is a heart rate and pulse oximeter sensor that could be very useful for my final project.

However, I had problems connecting it to my XIAO RP2350.

Even though the hardware connections were correct, the XIAO was unable to detect the sensor through I2C communication.

I will continue experimenting with this sensor because of its potential integration into my wearable device.

If the issue continues, I may need to switch either the sensor or the microcontroller.

MAX30102 prototype

AD8232 Heart Monitor

After running into issues with the MAX30102, I decided to work with the AD8232 Heart Monitor instead.

This sensor is larger and probably will not fit into my final wearable design, but it still allowed me to learn how ECG signals are captured and processed.

The first step was understanding the pinout and how to correctly wire the module.

AD8232 pinout

I connected GND to the XIAO ground pin, 3.3V to the 3.3V supply, and the signal output to D0.

The LO+ and LO- pins were connected to digital pins D1 and D2 to detect whether the electrodes were properly attached.

XIAO RP2350 pinout

Analog Signal

D0 reads the ECG waveform generated by the sensor.

Electrode Detection

LO+ and LO- detect if the electrodes become disconnected.

Main Objective

Detect heartbeats and monitor BPM changes in real time.

Testing with a Protoboard

Before testing the circuit, it is important to correctly place the electrodes on the body.

Electrode placement

Once everything was connected, I tested the sensor using a protoboard and monitored the ECG signal through the Serial Monitor.

Making the PCB

After validating the circuit on the protoboard, I created a simple PCB to make the setup more stable and compact.

Since I did not have pin headers available, I improvised by cutting, stripping and soldering jumper wires directly onto the PCB.

After assembling the PCB, I tested the system again to verify that the sensor and microcontroller still worked correctly.

Programming the Sensor

The code reads the ECG signal, calculates BPM values and detects significant increases relative to a baseline heart rate.

If the BPM rises above the defined threshold, an LED starts blinking as an alert indicator.


#include <avr/io.h>

const int ECG_PIN = A0;
const int LO_MAS = 2;
const int LO_MENOS = 3;
const int LED_PIN = D6;

int threshold = 550;

bool lastBeat = false;

unsigned long lastBeatTime = 0;

int bpmArray[5] = {0,0,0,0,0};

int bpmIndex = 0;

int baselineBPM = 75;

int aumento = 10;

bool alerta = false;

unsigned long lastBlink = 0;

bool ledState = false;

void setup() {

  Serial.begin(115200);

  pinMode(LO_MAS, INPUT);

  pinMode(LO_MENOS, INPUT);

  pinMode(LED_PIN, OUTPUT);

}

void loop() {

  if (digitalRead(LO_MAS) == 1 ||
      digitalRead(LO_MENOS) == 1) {

    Serial.println("Electrodos desconectados");

    digitalWrite(LED_PIN, LOW);

    return;

  }

  int signal = analogRead(ECG_PIN);

  if (signal > threshold && !lastBeat) {

    unsigned long currentTime = millis();

    if (currentTime - lastBeatTime > 600) {

      if (lastBeatTime != 0) {

        int bpm =
        60000 / (currentTime - lastBeatTime);

        if (bpm > 40 && bpm < 100) {

          bpmArray[bpmIndex] = bpm;

          bpmIndex = (bpmIndex + 1) % 5;

          int sum = 0;

          for (int i = 0; i < 5; i++) {

            sum += bpmArray[i];

          }

          int avgBPM = sum / 5;

          Serial.print("BPM promedio: ");

          Serial.println(avgBPM);

          if (avgBPM > baselineBPM + aumento) {

            alerta = true;

            Serial.println("AUMENTO DETECTADO");

          }

          else {

            alerta = false;

          }

        }

      }

      lastBeatTime = currentTime;

    }

    lastBeat = true;

  }

  if (signal < threshold) {

    lastBeat = false;

  }

  if (alerta) {

    if (millis() - lastBlink > 500) {

      ledState = !ledState;

      digitalWrite(LED_PIN, ledState);

      lastBlink = millis();

    }

  }

  else {

    digitalWrite(LED_PIN, LOW);

  }

  delay(5);

}

Debugging and Problems

Incorrect Pin Definition

Initially, I used the wrong LED pin definition, which caused the LED to not behave correctly.

Incorrect BPM Values

BPM calculations were unstable until I corrected the timing logic and filtering process.

Continuous LED Blinking

The LED stayed on because the BPM threshold logic was too sensitive before averaging the readings.

Connection to My Final Project

This assignment is directly related to my final wearable project because heart rate monitoring is one of the core functionalities I want to integrate.

The goal is to detect changes in BPM and eventually trigger calming feedback systems such as vibration or breathing guidance.

Even though the AD8232 is not ideal for the final version, this week helped me better understand biometric signal acquisition and sensor integration.

Sensor Integration

Learning how to read biometric signals from real sensors.

BPM Detection

Implementing heartbeat detection and BPM calculations in real time.

Future Development

Continue improving sensor accuracy and miniaturization for wearable integration.