Hello beginners want to ask, I want to make an interactive graph of the incoming data array. I have three types of data which are rpm, torque and power. I send all the data via the Arduino serial. I created the graph using “class”. My current problem, I’m confused to save the Arduino serial data as an array or something and make it as a line. I did an exploration with several arrays that I initialized myself, the results were like this, but for the data from the Arduino serial I was still confused.
here is the class graph
/* =================================================================================
The Graph class contains functions and variables that have been created to draw
graphs. Here is a quick list of functions within the graph class:
Graph(int x, int y, int w, int h,color k)
DrawAxis()
Bar([])
smoothLine([][])
DotGraph([][])
LineGraph([][])
=================================================================================*/
class Graph
{
boolean Dot=true; // Draw dots at each data point if true
boolean RightAxis; // Draw the next graph using the right axis if true
boolean ErrorFlag=false; // If the time array isn't in ascending order, make true
boolean ShowMouseLines=true; // Draw lines and give values of the mouse position
int xDiv=10,yDiv=5; // Number of sub divisions
int xPos,yPos; // location of the top left corner of the graph
int Width,Height; // Width and height of the graph
color GraphColor;
color BackgroundColor=color(255);
color StrokeColor=color(180);
String Title="Title"; // Default titles
String xLabel="x - Label";
String yLabel="y - Label";
float yMax=1024, yMin=0; // Default axis dimensions
float xMax=10, xMin=0;
float yMaxRight=1024,yMinRight=0;
PFont Font; // Selected font used for text
// int Peakcounter=0,nPeakcounter=0;
Graph(int x, int y, int w, int h,color k) { // The main declaration function
xPos = x;
yPos = y;
Width = w;
Height = h;
GraphColor = k;
}
void DrawAxis(){
/* =========================================================================================
Main axes Lines, Graph Labels, Graph Background
========================================================================================== */
fill(BackgroundColor); color(0);stroke(StrokeColor);strokeWeight(1);
int t=60;
rect(xPos-t*1.6,yPos-t,Width+t*2.5,Height+t*2); // outline
textAlign(CENTER);textSize(18);
float c=textWidth(Title);
fill(BackgroundColor); color(0);stroke(0);strokeWeight(1);
rect(xPos+Width/2-c/2,yPos-35,c,0); // Heading Rectangle
fill(0);
text(Title,xPos+Width/2,yPos-37); // Heading Title
textAlign(CENTER);textSize(14);
text(xLabel,xPos+Width/2,yPos+Height+t/1.5); // x-axis Label
rotate(-PI/2); // rotate -90 degrees
text(yLabel,-yPos-Height/2,xPos-t*1.6+20); // y-axis Label
rotate(PI/2); // rotate back
textSize(10); noFill(); stroke(0); smooth();strokeWeight(1);
//Edges
line(xPos-3,yPos+Height,xPos-3,yPos); // y-axis line
line(xPos-3,yPos+Height,xPos+Width+5,yPos+Height); // x-axis line
stroke(200);
if(yMin<0){
line(xPos-7, // zero line
yPos+Height-(abs(yMin)/(yMax-yMin))*Height, //
xPos+Width,
yPos+Height-(abs(yMin)/(yMax-yMin))*Height
);
}
if(RightAxis){ // Right-axis line
stroke(0);
line(xPos+Width+3,yPos+Height,xPos+Width+3,yPos);
}
/* =========================================================================================
Sub-devisions for both axes, left and right
========================================================================================== */
stroke(0);
for(int x=0; x<=xDiv; x++){
/* =========================================================================================
x-axis
========================================================================================== */
line(float(x)/xDiv*Width+xPos-3,yPos+Height, // x-axis Sub devisions
float(x)/xDiv*Width+xPos-3,yPos+Height+5);
textSize(10); // x-axis Labels
String xAxis=str(xMin+float(x)/xDiv*(xMax-xMin)); // the only way to get a specific number of decimals
String[] xAxisMS=split(xAxis,'.'); // is to split the float into strings
text(xAxisMS[0]+"."+xAxisMS[1].charAt(0), // ...
float(x)/xDiv*Width+xPos-3,yPos+Height+15); // x-axis Labels
}
/* =========================================================================================
left y-axis
========================================================================================== */
for(int y=0; y<=yDiv; y++){
line(xPos-3,float(y)/yDiv*Height+yPos, // ...
xPos-7,float(y)/yDiv*Height+yPos); // y-axis lines
textAlign(RIGHT);fill(20);
String yAxis=str(yMin+float(y)/yDiv*(yMax-yMin)); // Make y Label a string
String[] yAxisMS=split(yAxis,'.'); // Split string
text(yAxisMS[0]+"."+yAxisMS[1].charAt(0), // ...
xPos-15,float(yDiv-y)/yDiv*Height+yPos+3); // y-axis Labels
/* =========================================================================================
right y-axis
========================================================================================== */
if(RightAxis){
color(GraphColor); stroke(GraphColor);fill(20);
line(xPos+Width+3,float(y)/yDiv*Height+yPos, // ...
xPos+Width+7,float(y)/yDiv*Height+yPos); // Right Y axis sub devisions
textAlign(LEFT);
String yAxisRight=str(yMinRight+float(y)/ // ...
yDiv*(yMaxRight-yMinRight)); // convert axis values into string
String[] yAxisRightMS=split(yAxisRight,'.'); //
text(yAxisRightMS[0]+"."+yAxisRightMS[1].charAt(0), // Right Y axis text
xPos+Width+15,float(yDiv-y)/yDiv*Height+yPos+3); // it's x,y location
noFill();
}stroke(0);
}
}
/* =========================================================================================
Bar graph
========================================================================================== */
void Bar(float[] a ,int from, int to) {
stroke(GraphColor);
fill(GraphColor);
if(from<0){ // If the From or To value is out of bounds
for (int x=0; x<a.length; x++){ // of the array, adjust them
rect(int(xPos+x*float(Width)/(a.length)),
yPos+Height-2,
Width/a.length-2,
-a[x]/(yMax-yMin)*Height);
}
}
else {
for (int x=from; x<to; x++){
rect(int(xPos+(x-from)*float(Width)/(to-from)),
yPos+Height-2,
Width/(to-from)-2,
-a[x]/(yMax-yMin)*Height);
}
}
}
void Bar(float[] a ) {
stroke(GraphColor);
fill(GraphColor);
for (int x=0; x<a.length; x++){ // of the array, adjust them
rect(int(xPos+x*float(Width)/(a.length)),
yPos+Height-2,
Width/a.length-2,
-a[x]/(yMax-yMin)*Height);
}
}
/* =========================================================================================
Dot graph
========================================================================================== */
void DotGraph(float[] x ,float[] y) {
for (int i=0; i<x.length; i++){
strokeWeight(2);stroke(GraphColor);noFill();smooth();
ellipse(
xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height,
2,2
);
}
}
/* =========================================================================================
Streight line graph
========================================================================================== */
void LineGraph(float[] x ,float[] y) {
for (int i=0; i<(x.length-1); i++){
strokeWeight(2);stroke(GraphColor);noFill();smooth();
line(xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height,
xPos+(x[i+1]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i+1]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height);
}
}
/* =========================================================================================
smoothLine
========================================================================================== */
void smoothLine(float[] x ,float[] y) {
float tempyMax=yMax, tempyMin=yMin;
if(RightAxis){yMax=yMaxRight;yMin=yMinRight;}
int counter=0;
int xlocation=0,ylocation=0;
// if(!ErrorFlag |true ){ // sort out later!
beginShape(); strokeWeight(2);stroke(GraphColor);noFill();smooth();
for (int i=0; i<x.length; i++){
/* ===========================================================================
Check for errors-> Make sure time array doesn't decrease (go back in time)
===========================================================================*/
if(i<x.length-1){
if(x[i]>x[i+1]){
ErrorFlag=true;
}
}
/* =================================================================================
First and last bits can't be part of the curve, no points before first bit,
none after last bit. So a streight line is drawn instead
================================================================================= */
if(i==0 || i==x.length-2)line(xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height,
xPos+(x[i+1]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i+1]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height);
/* =================================================================================
For the rest of the array a curve (spline curve) can be created making the graph
smooth.
================================================================================= */
curveVertex( xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height);
/* =================================================================================
If the Dot option is true, Place a dot at each data point.
================================================================================= */
if(Dot)ellipse(
xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width,
yPos+Height-(y[i]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height,
2,2
);
/* =================================================================================
Highlights points closest to Mouse X position
=================================================================================*/
if( abs(mouseX-(xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width))<5 ){
float yLinePosition = yPos+Height-(y[i]/(yMax-yMin)*Height)+(yMin)/(yMax-yMin)*Height;
float xLinePosition = xPos+(x[i]-x[0])/(x[x.length-1]-x[0])*Width;
strokeWeight(1);stroke(240);
// line(xPos,yLinePosition,xPos+Width,yLinePosition);
strokeWeight(2);stroke(GraphColor);
ellipse(xLinePosition,yLinePosition,4,4);
}
}
endShape();
yMax=tempyMax; yMin=tempyMin;
float xAxisTitleWidth=textWidth(str(map(xlocation,xPos,xPos+Width,x[0],x[x.length-1])));
if((mouseX>xPos&mouseX<(xPos+Width))&(mouseY>yPos&mouseY<(yPos+Height))){
if(ShowMouseLines){
// if(mouseX<xPos)xlocation=xPos;
if(mouseX>xPos+Width)xlocation=xPos+Width;
else xlocation=mouseX;
stroke(200); strokeWeight(0.5);fill(255);color(50);
// Rectangle and x position
line(xlocation,yPos,xlocation,yPos+Height);
rect(xlocation-xAxisTitleWidth/2-10,yPos+Height-16,xAxisTitleWidth+20,12);
textAlign(CENTER); fill(160);
text(map(xlocation,xPos,xPos+Width,x[0],x[x.length-1]),xlocation,yPos+Height-6);
// if(mouseY<yPos)ylocation=yPos;
if(mouseY>yPos+Height)ylocation=yPos+Height;
else ylocation=mouseY;
// Rectangle and y position
stroke(200); strokeWeight(0.5);fill(255);color(50);
line(xPos,ylocation,xPos+Width,ylocation);
int yAxisTitleWidth=int(textWidth(str(map(ylocation,yPos,yPos+Height,y[0],y[y.length-1]))) );
rect(xPos-15+3,ylocation-6, -60 ,12);
textAlign(RIGHT); fill(GraphColor);//StrokeColor
// text(map(ylocation,yPos+Height,yPos,yMin,yMax),xPos+Width+3,yPos+Height+4);
text(map(ylocation,yPos+Height,yPos,yMin,yMax),xPos -15,ylocation+4);
if(RightAxis){
stroke(200); strokeWeight(0.5);fill(255);color(50);
rect(xPos+Width+15-3,ylocation-6, 60 ,12);
textAlign(LEFT); fill(160);
text(map(ylocation,yPos+Height,yPos,yMinRight,yMaxRight),xPos+Width+15,ylocation+4);
}
noStroke();noFill();
}
}
}
void smoothLine(float[] x ,float[] y, float[] z, float[] a ) {
GraphColor=color(188,53,53);
smoothLine(x ,y);
GraphColor=color(193-100,216-100,16);
smoothLine(z ,a);
}
}
Here my processing code
// import libraries
import java.awt.Frame;
import java.awt.BorderLayout;
import controlP5.*;
import processing.serial.*;
Serial serial;
ControlP5 cp5;
//define baudrate & port
int speed = 9600;
String portName;
String val;
// make graph
Graph MyFirstGraph = new Graph(120, 100, 600, 200, color (200, 20, 20));
//value for each line
float Rpm;
float Power;
float Torque;
float [] ArrayRpm;
float [] ArrayTorque;
float [] ArrayPower;
float [] Array1 = {1, 2, 3, 4, 5, 10, 12};
void setup() {
surface.setTitle("Realtime plotter");
size(800, 400);
cp5 = new ControlP5(this);
cp5.addButton("refresh")
.setPosition(110, 0)
.setSize(50, 30);
cp5.addButton("openPort")
.setPosition(170, 0)
.setSize(50, 30);
cp5.addButton("closePort")
.setPosition(230, 0)
.setSize(60, 30);
cp5.addScrollableList("comlist")
.setPosition(0, 0)
.setSize(100, 150)
.setBarHeight(30)
.setItemHeight(30).close();
MyFirstGraph.xLabel=" RPM (x1000)";
MyFirstGraph.yLabel="Torque(Nm)/Power(HP)";
MyFirstGraph.Title=" Torque & HP ";
// MyFirstGraph.xMax=int( max(ArrayRpm));
MyFirstGraph.yMax=20;
MyFirstGraph.yMin=0;
}
void draw() {
background(255);
//Check Serial Communication
if (serial != null) {
if (serial.available() > 0)
{
String val = serial.readStringUntil('\n');
if (val != null)
{
val = val.trim();
String [] data = split(val, ',');
print("data : ");
if (data.length >= 2)
{
printArray (data);
}
//Pickup data
Rpm = float (data[0]);
Torque = float (data[1]);
Power = float(data[2]);
MyFirstGraph.yMax=int (max(Array1)); // This re-adjusts the maximum y-Axis value
MyFirstGraph.xMax=int (max(ArrayRpm)); // to the biggest value in the array.
MyFirstGraph.DrawAxis();
//For smoothLine ([][]) ,If the function takes more than 1 array, both MUST be the same size
MyFirstGraph.GraphColor=color(200, 40, 40);
MyFirstGraph.smoothLine(ArrayTorque, ArrayRpm);
MyFirstGraph.GraphColor=color(40, 40, 200);
MyFirstGraph.smoothLine(ArrayPower, ArrayRpm);
}
}
}
}
void refresh() {
String list[] = Serial.list();
cp5.get(ScrollableList.class, "comlist").addItems(list);
}
void comlist(int n) {
portName = Serial.list()[n];
}
void openPort() {
serial = new Serial(this, portName, speed);
}
void closePort() {
serial.stop();
}