Hi, I'm working on an mini ECG project with a OLED SPI display.
Including :
An arduino NANO
A AD8232 ECG board from SPARKFUN
A SH1106 SPI OLED display 128x64
The project is wired as follow :
OLED SPI
CLK -> Pin J13
MOSI -> Pin D11
RES -> Pin D7
DC -> Pin D8
CS -> Pin D10
AD8232
LO+ -> Pin D5
LO- -> Pin D6
Output -> Pin A0
Buzzer -> D9
The program I did is inspired by a program I found on github.
Here is the Code :
#include <Adafruit_SH1106.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
int BPMT=0;
int T=1;
int D=0;
int E=0;
int F=0;
int G=0;
int x=0;
int lastx=0;
int lasty=0;
int LastTime=0;
bool BPMTiming=false;
bool BeatComplete=false;
int BPM=0;
const int buzzer = 9;
#define UpperThreshold 490
#define LowerThreshold 470
#define OLED_MOSI 11
#define OLED_CLK 13
#define OLED_DC 8
#define OLED_CS 10
#define OLED_RESET 7
Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
void setup() {
Serial.begin(9600);
pinMode(5, INPUT); // Setup for leads off detection LO +
pinMode(6, INPUT); // Setup for leads off detection LO -
pinMode(buzzer, OUTPUT);
display.begin(SH1106_SWITCHCAPVCC);
display.clearDisplay();
display.setTextSize(1);
display.display();
}
void loop() {
Serial.println(analogRead(A0));
if(x>127)
{
display.clearDisplay();
x=0;
lastx=x;
}
// Take the analog value and print it on the screen by using lines drawing
int value=analogRead(A0);
display.setTextColor(WHITE);
int y=60-(value/14);
display.writeLine(lastx,lasty,x,y,WHITE);
lasty=y;
lastx=x;
// calcul bpm
if(value>UpperThreshold)
{
if(BeatComplete)
{
BPM=millis()-LastTime;
BPM=int(60/(float(BPM)/1000));
BPMTiming=false;
BeatComplete=false;
tone(buzzer, 4000,5);
// Do a average of BPM with the 4 last values
if(T==4)
{
G=BPM ;
BPMT=int((D+E+F+G)/4) ;
T=1 ;
}
if(T==3)
{
F=BPM ;
T++;
}
if(T==2)
{
E=BPM ;
T++;
}
if(T==1)
{
D=BPM ;
T++;
}
}
if(BPMTiming==false)
{
LastTime=millis();
BPMTiming=true;
}
}
if((value<LowerThreshold)&(BPMTiming))
{
BeatComplete=true;
}
// display BPM value
display.writeFillRect(0,50,90,16,BLACK);
display.setCursor(50,55);
//display.print(BPM);
display.print(BPMT);
display.print(" BPM");
display.display();
noTone(buzzer);
x++;
}
The thing is when I use à simple programme to display the ECG waves on the IDE serial plotter like this:
void setup() {
Serial.begin(9600);
pinMode(5, INPUT); // Setup for leads off detection LO +
pinMode(6, INPUT); // Setup for leads off detection LO -
}
void loop() {
if((digitalRead(5) == 1)||(digitalRead(6) == 1)){
Serial.println('!');
}
else{
// send the value of analog input 0:
Serial.println(analogRead(A0));
}
delay(1);
}
I've got a nice and smooth ECG line.
But when I use the OLED display program the ECG graph is not as good because of either the time calculation of drawing lines or the time for displaying pixels is to high, and then, when the loop comes back to "int value=analogRead(A0);" after printing on screen the last line, it has missed a lot of analog values.
It results in a less readable curve (but still acceptable), sometimes it misses QRS (wich are 100ms long).
I tried to increase the clock value in the SPI.h library unsuccessfully (I may have did it wrong), I tried to change the SPI pins to the arduino unsuccessfully, I tried to modify the SH1106 library unsuccessfully, I tried to display pixels instead of lines : same results in term of speed...
I also tried to get rid of all the BPM calculation part in the program and the result is still the same.
My Loop should execute in less than 10-30 ms to be sure not to miss any important data is it possible with OLED SPI dipays and arduino nano?
My question is : is it possible to optimise either the program or libraries to get a result on OLED more similar to what i've got one the serial plotter? Or do i need to buy a chip with a better clockrate and throw my nano away?
I join you pictures of the serial plotter in the two situation (OLED program and simple Serial program)
Thank you!

