Nice work!
I am sharing some testing code (added to yours) that uses simulated data.
You may find that useful one day for testing or a “demo” mode.
Simulated Data
// ECG Bluetooth (Processing)
// v1.0.0
// Alexthesmeus 2020-07-08
import processing.serial.*;
Serial myPort;
int xPos = 1;
float height_old = 0;
float height_new = 0;
float inByte = 0;
int[] data = new int [10];
int step=125;
int step2=25;
int BPM = 0;
int beat_old = 0;
float[] beats = new float[5];
int beatIndex;
float threshold = 2600;
boolean belowThreshold = true;
PFont font;
int j; //GLV
int counter; //GLV
void setup () {
frameRate(50);
size(1625, 625);
printArray(Serial.list());
myPort = new Serial(this, Serial.list()[0], 115200);
myPort.bufferUntil(10);
background(0xff);
font = createFont("Arial", 40, true);
//initialize grid
stroke(255, 140, 140);
strokeWeight(1);
for (int k = 0; k <= width/step2; k++ ) {
line(k*step2, 0, k*step2, height);
line(0, k*step2, width, k*step2);
}
strokeWeight(2);
for (int k = 0; k <= width/step; k++ ) {
line(k*step, 0, k*step, height);
line(0, k*step, width, k*step);
}
}
void draw () {
//Draw BPM
stroke(255, 140, 140);
fill(255);
rect(0, 0, 250, 50);
fill(0);
textFont(font);
text("BPM: " + BPM, 15, 40);
//Read buffer
//String inString = myPort.readStringUntil('\n');
//println(inString);
//if (inString != null)
//{
// inString = trim(inString);
// data = int(split(inString, ','));
//}
//GLV Testing without serial
float angle = TAU/300;
//j += 5; //Add to end of draw()
for (int i=0; i<5; i++)
{
data[2*i] = (j+i)*4;
//data[2*i+1] = int(1024/2*sin((i+j)*angle)+512)+2000;
data[2*i+1] = int(sin((i+j)*angle*3)*(1024/2)*cos((i+j)*angle) + (1024/2))+1700;
counter = j+i;
}
println(counter);
println(data);
for (int i = 1; i< data.length; i+=2)
{
if (data[i]==-999) {
stroke(0, 0, 0xff);
inByte = 2048; //if at least one lead is disconnected, draw flat blue line
}
else {
stroke(0, 0, 0);
inByte=data[i];
}
if (inByte > threshold && belowThreshold == true) //BPM calculation
{
int beat_new = data[i-1];
int diff = beat_new - beat_old;
float currentBPM = 60000 / diff;
beats[beatIndex] = currentBPM;
float total = 0.0;
for (int j = 0; j < 5; j++) {
total += beats[j];
}
BPM = int(total / 5);
beat_old = beat_new;
beatIndex = (beatIndex + 1) % 5;
belowThreshold = false;
} else if (inByte < threshold)
{
belowThreshold = true;
}
inByte = map(inByte, 0, 4096, 0, height);
height_new = height - inByte;
line(xPos - 1, height_old, xPos, height_new);
height_old = height_new;
if (xPos >= width) {
xPos = 0; //clear graph and restart when end is reached
background(0xff);
stroke(255, 140, 140);
strokeWeight(1);
for (int k = 0; k <= width/step2; k++ ) {
line(k*step2, 0, k*step2, height);
line(0, k*step2, width, k*step2);
}
strokeWeight(2);
for (int k = 0; k <= width/step; k++ ) {
line(k*step, 0, k*step, height);
line(0, k*step, width, k*step);
}
} else {
xPos++;
}
}
j += 5; //GLV
}
void keyPressed() //print ECG
{
saveFrame(nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2)+ "_" + nf(day(), 2)+ nf(month(), 2) + nf(year(), 4) + ".tif");
}
Output of your code with simulated data:
:)