Problems showing ECG signal on display (Incoming signal on A1 is good)
Hello all,
I am currently working on a project where I get an ECG signal from a philips surveillance monitor coming in on pin A1 of my Arduino. The signal was initially an AC voltage that the arduino cannot read. I used a voltage divider and some capacitor to make the voltage DC voltage so that the arduino can read it. The signal I now send in on pin A1 is between 0.5v and 4v. With an oscilloscope, I checked that the signal on A1 looks neat - well clean and with clear peaks. You can see that the first curve on my screen is good and then the curve becomes less. sometimes it shows the curve 4x right and several times wrong. There is no fixed rhythm in it.
My goal is to show this ECG signal on a display, but what I get on the screen is occasionally a good ECG curve and occasionally it flips the curve. I suspect the problem is somewhere in the way I read, process or plot the analogue values on the screen.
Does anyone have an idea what this could be due to? Thinking of:
- Too slow or too fast sampling rate?
- Too little resolution or wrong scale?
- Processing of the signal?
- Error in how I control the display?
Below I post my code:
// Insert your full Arduino code here
Any tips or examples are welcome!
Thanks in advance for thinking with me
Greetings,
Quint
#include <Wire.h> // Voor I2C-communicatie
#include <Adafruit_GFX.h> // Grafische bibliotheek van Adafruit (voor basisvormen, lijnen, enz.)
#include <Adafruit_SH110X.h> // Driver voor SH1106 OLED-scherm
#define SCREEN_I2C_ADDR 0x3C // I2C-adres van het OLED-scherm
#define SCREEN_WIDTH 128 // Breedte van het scherm in pixels
#define SCREEN_HEIGHT 64 // Hoogte van het scherm in pixels
Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); // Maak een displayobject aan met opgegeven resolutie en I2C
const int IN_PIN = A0; // De analoge ingang waarop het ECG-signaal wordt gemeten
const int SAMPLE_TIME = 4; // Interval (in milliseconden) tussen metingen van het ECG-signaal
const int DISPLAY_UPDATE_TIME = 8; // Interval (in milliseconden) voor het bijwerken van het display
const float SCALE_FACTOR = 12; // Versterkingsfactor voor het signaal zodat het beter zichtbaar is op het scherm
const int middleY = SCREEN_HEIGHT / 1.25; // Verticale middenlijn voor het tekenen van het signaal (schaling voor betere positie)
unsigned long lastSampleTime = 0; // Tijdstempel van de laatste meting
unsigned long lastDisplayTime = 0; // Tijdstempel van de laatste schermupdate
int ecgData[SCREEN_WIDTH]; // Array waarin alle meetpunten van het signaal worden opgeslagen om ze te tekenen
float averageVoltage = 1.5; // Startwaarde voor de gemiddelde spanning, gebruikt voor dynamisch centreren
void setup() {
//Serial.begin(9600); // Start seriële communicatie voor debugging (voor bv. plotten via Serial Plotter)
display.begin(SCREEN_I2C_ADDR, true); // Initialiseer het scherm met het juiste I2C-adres
display.clearDisplay(); // Wis het scherm
display.display(); // Toon de lege buffer op het scherm
}
void loop() {
if (millis() - lastSampleTime >= SAMPLE_TIME) { // Controleer of het tijd is voor een nieuwe meting
analogRead(IN_PIN); // Dummy read voor ADC-stabilisatie
delayMicroseconds(1000); // Kleine delay om ADC te laten settelen
int sensorValue = analogRead(IN_PIN); // Echte meting
float voltage = (sensorValue / 1024.0) * 5.0; // Zet ADC-waarde om naar spanning (0 - 5V)
//Serial.println(voltage); // Stuur de spanning naar de seriële monitor (voor debug of plot)
averageVoltage = 0.9 * averageVoltage + 0.1 * voltage;
int y = middleY - (voltage - averageVoltage) * SCALE_FACTOR;
y = constrain(y, 5, SCREEN_HEIGHT - 5); // Zorg dat y binnen het scherm blijft
for (int i = 0; i < SCREEN_WIDTH - 1; i++) {
ecgData[i] = ecgData[i + 1];
}
ecgData[SCREEN_WIDTH - 1] = y;
lastSampleTime = millis(); // Update tijdstempel van laatste meting
}
if (millis() - lastDisplayTime >= DISPLAY_UPDATE_TIME) {
display.clearDisplay();
for (int i = 0; i < SCREEN_WIDTH - 1; i++) {
display.drawLine(i, ecgData[i], i + 1, ecgData[i + 1], 1);
}
display.display();
lastDisplayTime = millis();
}
}


