I’m using 7 serial ports with 7 sensors required to be plotted in rela time without any delays. I have used separate thread functions to plot the data. However, after 5 minutes of plotting I have observed there is a delay of real time plots. How can I get rid of this delay?
import processing.serial.*;
import grafica.*;
import controlP5.*;
import g4p_controls.*;
import signal.library.*;
PrintWriter output; // save into a file
PrintWriter output2; // save into a file
PrintWriter output3; // save into a file
PrintWriter output4; // save into a file
PrintWriter output5; // save into a file
PrintWriter output6; // save into a file
PrintWriter output7; // save into a file
PrintWriter output8; // save into a file
PrintWriter output9; // save into a file
PrintWriter output10; // save into a file
Serial Port1; // create a serial port object
String val; // Serial port reading
Serial Port2; // create a serial port object
String val2; // Serial port reading
Serial Port3; // create a serial port object
String val3; // Serial port reading
Serial Port4; // create a serial port object
String val4; // Serial port reading
Serial Port5; // create a serial port object
String val5; // Serial port reading
Serial Port6; // create a serial port object
String val6; // Serial port reading
Serial Port7; // create a serial port object
String val7; // Serial port reading
int nPoints = 60000;
public String timestamp = str(hour()) + str(minute()) + str(second());
public float i=0, j=0, k=0, m=0, ic=0, jc=0, kc=0, mc=0;
public float ii=0,jj=0,kk=0,mm=0,iic=0,jjc=0,kkc=0,mmc=0;
public GPlot plot1, plot2, plot3, plot4;
public GPointsArray points = new GPointsArray(nPoints); // create output saving array
public GPointsArray points1 = new GPointsArray(nPoints);
public GPointsArray points2 = new GPointsArray(nPoints);
public GPointsArray points3 = new GPointsArray(nPoints);
public GPointsArray points4 = new GPointsArray(nPoints);
public GPointsArray points5 = new GPointsArray(nPoints);
public GPointsArray points6 = new GPointsArray(nPoints);
public GPointsArray points7 = new GPointsArray(nPoints);
public GPointsArray points8 = new GPointsArray(nPoints);
public GPointsArray points9 = new GPointsArray(nPoints);
public GPointsArray points10 = new GPointsArray(nPoints);
public GPointsArray points11 = new GPointsArray(nPoints);
public GPointsArray points12 = new GPointsArray(nPoints);
public GPointsArray points13 = new GPointsArray(nPoints);
ControlP5 cp5; //create controller object
PFont font; //create font object
SignalFilter myFilter; // Create the filter
SignalFilter myFilter2; // Create the filter
// Main OneEuroFilter parameters
float freq =120;
float minCutoff = 3.0; // decrease this to get rid of slow speed jitter
float beta = 0.007; // increase this to get rid of high speed lag
float filteredSignal,filteredSignal2;
String signal,signal2;
int numReadings = 5;
float [] readings= new float[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
float total = 0; // the running total
float average = 0; // the average
float [] readings2= new float[numReadings]; // the readings from the analog input
int readIndex2 = 0; // the index of the current reading
float total2 = 0; // the running total
float average2 = 0; // the average
// Start of void setup
void setup(){
size(1500, 1000); // canvas size
smooth();
noStroke();
background(50);
frameRate(100);
output = createWriter( "ReadingIMP.csv" ); // data saving file name
output2 = createWriter( "ReadingSPO2.csv" ); // data saving file name
output3=createWriter("Indexlist.csv");
output4 = createWriter( "ReadingTemp.csv" ); // data saving file name
output5 = createWriter( "ReadingPAT.csv" ); // data saving file name
output6 = createWriter( "ReadingIMPC.csv" ); // data saving file name
output7 = createWriter( "ReadingSPO2C.csv" ); // data saving file name
output8=createWriter("IndexlistC.csv");
output9 = createWriter( "ReadingTempC.csv" ); // data saving file name
output10 = createWriter( "ReadingPATC.csv" ); // data saving file name
String ports[]=Serial.list(); // finding available serial ports
for (String port : ports) {
println(port);
}
Port1=new Serial(this,ports[0], 250000); // Open the serial port
Port1.bufferUntil('\n');
Port2=new Serial(this, ports[4], 250000); // Open the serial port
Port2.bufferUntil('\n');
Port3=new Serial(this, ports[6], 250000); // Open the serial port
Port3.bufferUntil('\n');
Port4=new Serial(this, ports[1],250000); // Open the serial port
Port4.bufferUntil('\n');
Port5=new Serial(this, ports[3], 250000); // Open the serial port
Port5.bufferUntil('\n');
Port6=new Serial(this, ports[5], 250000); // Open the serial port
Port6.bufferUntil('\n');
Port7=new Serial(this, ports[2],250000); // Open the serial port
Port7.bufferUntil('\n');
cp5= new ControlP5(this);
font =createFont("calibri light", 18);
cp5.addButton ("Start") //label the button
.setPosition(1300, 50) //position of the button
.setSize(100, 80) //width and height
.setFont(font)
.setColorBackground(color(50, 50, 255))
.setColorForeground(color(50, 100, 200))
// .setColorValue(color(255,255,0))
.setColorActive(color(50, 150, 150));
cp5.addButton ("Baseline") //label the button
.setPosition(1300, 150) //position of the button
.setSize(100, 80) //width and height
.setFont(font)
.setColorBackground(color(255, 150, 50))
.setColorForeground(color(200, 150, 50))
.setColorActive(color(150, 100, 150));
cp5.addButton ("Occlusion") //label the button
.setPosition(1300, 250) //position of the button
.setSize(100, 80) //width and height
.setFont(font)
.setColorBackground(color(255, 0, 0))
.setColorForeground(color(200, 50, 50))
.setColorActive(color(150, 100, 150));
cp5.addButton ("Release") //label the button
.setPosition(1300, 350) //position of the button
.setSize(100, 80) //width and height
.setFont(font)
.setColorBackground(color(0, 255, 50))
.setColorForeground(color(50, 200, 50))
.setColorActive(color(50, 150, 150));
cp5.addButton ("Stop") //label the button
.setPosition(1300, 450) //position of the button
.setSize(100, 80) //width and height
.setFont(font)
.setColorBackground(color(100, 50, 255))
.setColorForeground(color(50, 100, 200))
.setColorActive(color(50, 150, 150));
// Initialize the filter
myFilter = new SignalFilter(this,1);
myFilter.setFrequency(freq);
myFilter.setMinCutoff(minCutoff);
myFilter.setBeta(beta);
// Initialize the filter
myFilter2 = new SignalFilter(this,1);
myFilter2.setFrequency(freq);
myFilter2.setMinCutoff(minCutoff);
myFilter2.setBeta(beta);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
for (int thisReading2 = 0; thisReading2 < numReadings; thisReading2++) {
readings2[thisReading2] = 0;
}
plot1 = new GPlot(this); // ploting the graph for Impedance 5 kHz
plot1.setPos(50, 50);
plot1.setDim(400, 250);
plot1.setAxesOffset(0);
plot1.getTitle().setText("Impedance @ 5 kHz and 50 kHz");
plot1.getXAxis().getAxisLabel().setText("Number of Samples");
plot1.getYAxis().getAxisLabel().setText("Ohms");
plot1.setYLim(300, 3000);
plot1.setFixedYLim(true);
plot1.setLineColor(color(0, 0, 255));
plot2 = new GPlot(this); // ploting the graph for SPO2
plot2.setPos(700, 50);
plot2.setDim(400, 250);
plot2.setAxesOffset(0);
plot2.getTitle().setText("IR and Red Raw signal");
plot2.getXAxis().getAxisLabel().setText("Number of Samples");
plot2.getYAxis().getAxisLabel().setText("Absorption Value");
// plot2.setYLim(60000, 120000);
// plot2.setFixedYLim(true);
plot2.setLineColor(color(0, 0, 255));
plot3 = new GPlot(this); // ploting the graph for Body Temperature
plot3.setPos(50, 450);
plot3.setDim(400, 250);
plot3.setAxesOffset(0);
plot3.getTitle().setText("Body Temperature and Ambient Temperature");
plot3.getXAxis().getAxisLabel().setText("Number of Samples");
plot3.getYAxis().getAxisLabel().setText("Celcius");
plot3.setYLim(25, 37);
plot3.setFixedYLim(true);
plot3.setLineColor(color(255, 0, 0));
plot4 = new GPlot(this); // ploting the graph for Arterial Pressure
plot4.setPos(700, 450);
plot4.setDim(400, 250);
plot4.setAxesOffset(0);
plot4.getTitle().setText("Arterial Pressure");
plot4.getXAxis().getAxisLabel().setText("Number of Samples");
plot4.getYAxis().getAxisLabel().setText("mmHg");
plot4.setYLim(60, 90);
plot4.setFixedYLim(true);
plot4.setLineColor(color(255, 0, 255));
}
void draw() {
plot1.setPoints(points); // ploting the graph for Impedance 5 kHz
plot1.addLayer("layer 4", points1);
plot1.getLayer("layer 4").setLineColor(color(0, 200, 0));
plot1.getLayer("layer 4").setLineWidth(3);
plot1.addLayer("layer 5", points7);
plot1.getLayer("layer 5").setLineColor(color(0, 50, 200));
plot1.getLayer("layer 5").setLineWidth(3);
plot1.addLayer("layer 6", points8);
plot1.getLayer("layer 6").setLineColor(color(0, 200, 50));
plot1.getLayer("layer 6").setLineWidth(3);
plot1.beginDraw();
plot1.drawBackground();
plot1.drawXAxis();
plot1.drawYAxis();
plot1.drawTitle();
plot1.drawGridLines(GPlot.BOTH);
plot1.drawLines();
plot1.setLineColor(color(0, 0, 255));
plot1.setLineWidth(3);
plot1.activatePanning();
plot1.activateZooming(2, CENTER, CENTER);
plot1.endDraw();
plot1.removeLayer("layer 4");
plot1.removeLayer("layer 5");
plot1.removeLayer("layer 6");
plot2.setPoints(points2); // ploting the graph for SPO2
plot2.addLayer("layer 2", points3);
plot2.getLayer("layer 2").setLineColor(color(100, 100, 200));
plot2.getLayer("layer 2").setLineWidth(3);
plot2.addLayer("layer 7", points9);
plot2.getLayer("layer 7").setLineColor(color(200, 0, 100));
plot2.getLayer("layer 7").setLineWidth(3);
plot2.addLayer("layer 8", points10);
plot2.getLayer("layer 8").setLineColor(color(100, 0, 200));
plot2.getLayer("layer 8").setLineWidth(3);
plot2.beginDraw();
plot2.drawBackground();
plot2.drawXAxis();
plot2.drawYAxis();
plot2.drawTitle();
plot2.drawGridLines(GPlot.BOTH);
plot2.drawLines();
plot2.setLineColor(color(255, 0, 0));
plot2.setLineWidth(3);
plot2.activatePanning();
plot2.activateZooming(2, CENTER, CENTER);
plot2.endDraw();
plot2.removeLayer("layer 2");
plot2.removeLayer("layer 7");
plot2.removeLayer("layer 8");
plot3.setPoints(points4); // ploting the graph for Temperature
plot3.addLayer("layer 3", points5);
plot3.getLayer("layer 3").setLineColor(color(100, 100, 200));
plot3.getLayer("layer 3").setLineWidth(3);
plot3.beginDraw();
plot3.drawBackground();
plot3.drawXAxis();
plot3.drawYAxis();
plot3.drawTitle();
plot3.drawGridLines(GPlot.BOTH);
plot3.drawLines();
plot3.setLineColor(color(255, 0, 0));
plot3.setLineWidth(3);
plot3.activatePanning();
plot3.activateZooming(2, CENTER, CENTER);
plot3.endDraw();
plot3.removeLayer("layer 3");
plot4.setPoints(points6); // ploting the graph for Arterial Pressure
plot4.addLayer("layer 9", points13);
plot4.getLayer("layer 9").setLineColor(color(150, 100, 150));
plot4.getLayer("layer 9").setLineWidth(3);
plot4.beginDraw();
plot4.drawBackground();
plot4.drawXAxis();
plot4.drawYAxis();
plot4.drawTitle();
plot4.drawGridLines(GPlot.BOTH);
plot4.drawLines();
plot4.setLineColor(color(255, 0, 255));
plot4.setLineWidth(3);
plot4.activatePanning();
plot4.activateZooming(2, CENTER, CENTER);
plot4.endDraw();
plot4.removeLayer("layer 9");
thread("Impedance");
thread("ImpedanceC");
thread("SPO2");
thread("SPO2C");
thread("Temperature");
thread("PAT");
thread("PATC");
}
void Impedance() {
if (Port1.available()>0) {
// delay(1);
val=Port1.readStringUntil('\n');
ii=ii+1;
if (val!=null && ii<=5){
//println("ok");
//println(j);
println(val);
}
if (val!=null && ii>5 ) {
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list=split(val, ',');
i=i+1;
points.add(i/(24*60), float(list[0]));
points1.add(i/(24*60), float(list[9]));
output.println(timestamp + ", " + list[0]+ ", " + list[1]+", " + list[2]+", " + list[3]+", " + list[4]+", " + list[5]+
", " + list[6]+", " + list[7]+", " + list[8]+", " + list[9]+", " + list[10]+", " + list[11]);
}
}
}
void ImpedanceC() {
if (Port5.available()>0) {
// delay(1);
val5=Port5.readStringUntil('\n');
iic=iic+1;
if (val5!=null && iic<=5){
//println("ok");
//println(j);
println(val5);
}
if (val5!=null && iic>5 ) {
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list=split(val5, ',');
ic=ic+1;
points7.add(ic/(24*60), float(list[0]));
points8.add(ic/(24*60), float(list[9]));
output6.println(timestamp + ", " + list[0]+ ", " + list[1]+", " + list[2]+", " + list[3]+", " + list[4]+", " + list[5]+
", " + list[6]+", " + list[7]+", " + list[8]+", " + list[9]+", " + list[10]+", " + list[11]);
}
}
}
void SPO2() {
if (Port2.available()>0) {
//delay(50);
val2=Port2.readStringUntil('\n');
jj=jj+1;
if (val2!=null && jj<=1){
//println("ok");
//println(j);
println(val2);
}
if (val2!=null && jj>=2) {
val2 = trim(val2);
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list=split(val2, ',');
j=j+1;
points2.add(j/(25*60), float(list[0]));
points3.add(j/(25*60), float(list[1]));
output2.println(timestamp + ", " + list[0]+ ", " + list[1]);
}
}
}
void SPO2C() {
if (Port6.available()>0) {
//delay(50);
val6=Port6.readStringUntil('\n');
jjc=jjc+1;
if (val6!=null && jjc<=1){
//println("ok");
//println(j);
println(val6);
}
if (val6!=null && jjc>=2) {
val6 = trim(val6);
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list=split(val6, ',');
jc=jc+1;
points9.add(jc/(25*60), float(list[0]));
points10.add(jc/(25*60), float(list[1]));
output7.println(timestamp + ", " + list[0]+ ", " + list[1]);
}
}
}
void Temperature() {
if (Port3.available()>0) {
//delay(50);
val3=Port3.readStringUntil('\n');
kk=kk+1;
if (val3!=null && kk<=1){
//println("ok");
//println(j);
println(val3);
}
if (val3!=null && kk>=2) { // Temperature reading
// val3=Port3.readStringUntil('\n');
if (val3!=null) {
val3 = trim(val3);
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list=split(val3, ',');
k=k+1;
points4.add(k/(10*60), float(list[0]));
points5.add(k/(10*60), float(list[1]));
output4.println(timestamp + ", " + list[0]+ ", " +list[1]);
}
}
}
}
void PAT() {
while(Port4.available()>0) { // PAT signal reading
//delay(1);
val4=Port4.readStringUntil('\n');
if (val4!=null && val4.charAt(0)=='#') {
val4 = trim(val4);
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list1=split(val4, '#');
//String list1=val4;
// println(timestamp);
// println(list1[1]);
m=m+1;
//filteredSignal = myFilter.filterUnitFloat(float(list1[1]));
float y=Movavg(float(list1[1]));
//points6.add(m, filteredSignal);
//signal=nf(filteredSignal,0,0);
//points6.add(m, filteredSignal);
//points6.add(m, float(list1[1]));
points6.add(m/(92*60), y);
output5.println(timestamp +", " + list1[1]);
}
}
}
void PATC() {
while(Port7.available()>0) { // PAT signal reading
//delay(1);
val7=Port7.readStringUntil('\n');
if (val7!=null && val7.charAt(0)=='#') {
val7 = trim(val7);
String timestamp = str(hour()) + str(minute()) + str(second());
String[] list1=split(val7, '#');
//String list1=val4;
// println(timestamp);
// println(list1[1]);
mc=mc+1;
// filteredSignal2 = myFilter2.filterUnitFloat(float(list1[1]));
float yc=Movavg2(float(list1[1]));
//points6.add(m, filteredSignal);
//signal=nf(filteredSignal,0,0);
//points6.add(m, filteredSignal);
//points6.add(m, float(list1[1]));
points13.add(mc/(92*60), yc);
output9.println(timestamp +", " + list1[1]);
}
}
}
float Movavg(float input){
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = input;
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
return average = total / numReadings;
// send it to the computer as ASCII digits
}
float Movavg2(float input){
// subtract the last reading:
total2 = total2 - readings2[readIndex2];
// read from the sensor:
readings2[readIndex2] = input;
// add the reading to the total:
total2 = total2 + readings2[readIndex2];
// advance to the next position in the array:
readIndex2 = readIndex2 + 1;
// if we're at the end of the array...
if (readIndex2 >= numReadings) {
// ...wrap around to the beginning:
readIndex2 = 0;
}
// calculate the average:
return average2 = total2 / numReadings;
// send it to the computer as ASCII digits
}
void Start() {
Port1.write('%');
Port2.write('%');
Port3.write('%');
Port4.write('%');
Port5.write('%');
Port6.write('%');
Port7.write('%');
}
void Baseline() {
String timestamp = str(hour()) + str(minute()) + str(second());
output3.println(timestamp + ","+ i+ ","+ j+ ","+ k+ ","+ m);
output10.println(timestamp + ","+ ic+ ","+ jc+ ","+ kc+ ","+ mc);
// output1.println(timestamp + ","+ i+ ","+ j+ ","+ k+ ","+ m);
}
void Occlusion() {
String timestamp = str(hour()) + str(minute()) + str(second());
output3.println(timestamp +","+ i+ ","+ j+ ","+ k+ ","+ m);
output10.println(timestamp + ","+ ic+ ","+ jc+ ","+ kc+ ","+ mc);
// output1.println(timestamp + ","+ i+ ","+ j+ ","+ k+ ","+ m);
}
void Release() {
String timestamp = str(hour()) + str(minute()) + str(second());
output3.println(timestamp +","+ i+ ","+ j+ ","+ k+ ","+ m);
output10.println(timestamp + ","+ ic+ ","+ jc+ ","+ kc+ ","+ mc);
//output1.println(timestamp + ","+ i+ ","+ j+ ","+ k+ ","+ m);
}
void Stop () {
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
output2.flush(); // Writes the remaining data to the file
output2.close(); // Finishes the file
output3.flush(); // Writes the remaining data to the file
output3.close(); // Finishes the file
output4.flush(); // Writes the remaining data to the file
output4.close(); // Finishes the file
output5.flush(); // Writes the remaining data to the file
output5.close(); // Finishes the file
output6.flush(); // Writes the remaining data to the file
output6.close(); // Finishes the file
output7.flush(); // Writes the remaining data to the file
output7.close(); // Finishes the file
output8.flush(); // Writes the remaining data to the file
output8.close(); // Finishes the file
output9.flush(); // Writes the remaining data to the file
output9.close(); // Finishes the file
output10.flush(); // Writes the remaining data to the file
output10.close(); // Finishes the file
exit(); // Stops the program
}