# Make a realtime serial plotter

**URL:** https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438
**Category:** Electronics (Arduino, etc.)
**Tags:** homework
**Created:** [November 10, 2021, 11:04am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438 "2021-11-10T11:04:15Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 10, 2021, 11:04am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/1 "2021-11-10T11:04:15Z")

</div>

Hello, I want to ask about the real time serial plotter, I have downloaded it from Sebastian Nilsson’s github, and have modified it as needed. But I’m confused to make my serial value as input update in the graph I created.  
I have serial values for Power, Torque and engine RPM. Of the three values I want the engine RPM value on the X axis, Power and Torque on the Y axis. Here’s the picture I attached, please help my bro.  
Thanks in Advance…

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/e614c47ced782a824e2bed778d59d2443a7931fe.png)

---

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 10, 2021, 11:06am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/2 "2021-11-10T11:06:12Z")

</div>

Actually i still cannot re formated my code, so i’ll give my code here

````auto
// import libraries "all library is OK" 
import java.awt.Frame;
import java.awt.BorderLayout;
import controlP5.*; // http://www.sojamo.de/libraries/controlP5/
import processing.serial.*;

/* SETTINGS BEGIN */

// Serial port to connect to
String serialPortName = "COM9"; //Ok

// If you want to debug the plotter without using a real serial port set this to true
boolean mockupSerial = true; //Ok

/* SETTINGS END */

Serial serialPort; // Serial port object (OK)

// interface stuff
ControlP5 cp5; //(OK)

// Settings for the plotter are saved in this file
JSONObject plotterConfigJSON;

Graph LineGraph = new Graph(150, 100, 600, 200, color (200, 20, 20));
float[][] lineGraphValues = new float[6][100]; //??
float[] lineGraphSampleNumbers = new float[100]; //??
color[] graphColors = new color[6]; //

// helper for saving the executing path
String topSketchPath = "";

void setup() {
  surface.setTitle("EECL Dynotest");
  size(890, 500);

  // set line graph colors
  graphColors[0] = color(255, 0, 0);
  graphColors[1] = color(0, 255, 0);
 
  // settings save file
  topSketchPath = sketchPath();
  plotterConfigJSON = loadJSONObject(topSketchPath+"/plotter_config.json");

  // gui
  cp5 = new ControlP5(this);
  
  // init charts
  setChartSettings();
  // build x axis values for the line graph
  for (int i=0; i<lineGraphValues.length; i++) {
    for (int k=0; k<lineGraphValues[0].length; k++) {
      lineGraphValues[i][k] = 0;
      if (i==0)
        lineGraphSampleNumbers[k] = k;
    }
  }
  
  // start serial communication
  if (!mockupSerial) {
    //String serialPortName = Serial.list()[3];
    serialPort = new Serial(this, serialPortName, 115200);
  }
  else
    serialPort = null;
  }
  
byte[] inBuffer = new byte[100]; // holds serial message
int i = 0; // loop variable
void draw() {
  /* Read serial and update values */
  if (mockupSerial || serialPort.available() > 0) {
    String myString = "";
    if (!mockupSerial) {
      try {
        serialPort.readBytesUntil('\r', inBuffer);
      }
      catch (Exception e) {
      }
      myString = new String(inBuffer);
    }
    else {
      myString = mockupSerialFunction();
    }

    //println(myString);

    // split the string at delimiter (space)
    String[] nums = split(myString, ' ');
    
    int numberOfInvisibleLineGraphs = 0;
    for (i=0; i<6; i++) {
      if (int(getPlotterConfigString("lgVisible"+(i+1))) == 0) {
        numberOfInvisibleLineGraphs++;
      }
    }
    // build a new array to fit the data to show
    //barChartValues = new float[6-numberOfInvisibleBars];

    // build the arrays for bar charts and line graphs
    int barchartIndex = 0;
    for (i=0; i<nums.length; i++) {

      // update barchart
      try {
        if (int(getPlotterConfigString("bcVisible"+(i+1))) == 1) {
          //if (barchartIndex < barChartValues.length)
           // barChartValues[barchartIndex++] = float(nums[i])*float(getPlotterConfigString("bcMultiplier"+(i+1)));
        }
        else {
        }
      }
      catch (Exception e) {
      }

      // update line graph
      try {
        if (i<lineGraphValues.length) {
          for (int k=0; k<lineGraphValues[i].length-1; k++) {
            lineGraphValues[i][k] = lineGraphValues[i][k+1];
          }

          lineGraphValues[i][lineGraphValues[i].length-1] = float(nums[i])*float(getPlotterConfigString("lgMultiplier"+(i+1)));
        }
      }
      catch (Exception e) {
      }
    }
  }

  // draw the bar chart
  background(255); //bukan background tabel grafik 
   // draw the line graphs
  LineGraph.DrawAxis();
  for (int i=0;i<lineGraphValues.length; i++) {
    LineGraph.GraphColor = graphColors[i];
    if (int(getPlotterConfigString("lgVisible"+(i+1))) == 1)
      LineGraph.LineGraph(lineGraphSampleNumbers, lineGraphValues[i]);
  }
}

// called each time the chart settings are changed by the user 
void setChartSettings() {
  LineGraph.xLabel=" Engine RPM (x1000) ";
  LineGraph.yLabel="Torque (Nm)/Power (HP)";
  LineGraph.Title="";  
  LineGraph.xDiv=10;  
  LineGraph.xMax=10; 
  LineGraph.xMin=0;  
  LineGraph.yMax=int(getPlotterConfigString("lgMaxY")); 
  LineGraph.yMin=int(getPlotterConfigString("lgMinY"));
}

// handle gui actions
void controlEvent(ControlEvent theEvent) {
  if (theEvent.isAssignableFrom(Textfield.class) || theEvent.isAssignableFrom(Toggle.class) || theEvent.isAssignableFrom(Button.class)) {
    String parameter = theEvent.getName();
    String value = "";
    if (theEvent.isAssignableFrom(Textfield.class))
      value = theEvent.getStringValue();
    else if (theEvent.isAssignableFrom(Toggle.class) || theEvent.isAssignableFrom(Button.class))
      value = theEvent.getValue()+"";

    plotterConfigJSON.setString(parameter, value);
    saveJSONObject(plotterConfigJSON, topSketchPath+"/plotter_config.json");
  }
  setChartSettings();
}

// get gui settings from settings file
String getPlotterConfigString(String id) {
  String r = "";
  try {
    r = plotterConfigJSON.getString(id);
  } 
  catch (Exception e) {
    r = "";
  }
  return r;
}```
````

---

<div class="post-metadata">

### Author: ![RichardDL](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@RichardDL](https://discourse.processing.org/u/RichardDL)
#### Post date: [November 10, 2021, 7:55pm UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/3 "2021-11-10T19:55:16Z")

</div>

Hi @anwar05, Your sketch doesn’t run for me, are there other tabs? Can you post the code for each please?

---

<div class="post-metadata">

### Author: ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)
#### Post date: [November 11, 2021, 12:31am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/4 "2021-11-11T00:31:47Z")

</div>

Hello,

I explored the Realtime Plotter:

> **[GitHub - sebnil/RealtimePlotter: Plots live data from a serial port....](https://github.com/sebnil/RealtimePlotter)**
>
> Plots live data from a serial port. Multiplatform and written in Processing. - GitHub - sebnil/RealtimePlotter: Plots live data from a serial port. Multiplatform and written in Processing.

but will not be investing any more time into this.

I found the grafica library simple and easy to work with.

I modified the MultiplePlots example:

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/a2525c063378dfffe2a029ef0946ba87dd8d62bf.png)

To give a real time plot (the red one):

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/358d5e46c457a49ffaeb9bc1e44d8f0a0fece554.png)

Modifications (some) to Plot 2:

```auto
  // Add a new point to the second plot if the mouse moves significantly
  GPoint lastPoint = plot2.getPointsRef().getLastPoint();

  int x = frameCount%100;
  float y = 30+20*sin(frameCount*TAU/100);

  if (lastPoint == null) 
    {
    plot2.addPoint(x, y);
    } 
  else if (!lastPoint.isValid() || frameCount > 0) 
    {
    plot2.addPoint(x, y);
    }

  // Reset the points if the user pressed the space bar
  //if (keyPressed && key == ' ') 
    if(frameCount%100 == 99)
    {
    plot2.setPoints(new GPointsArray());
    }

```

Some other modifications were necessary (x and y limits and drawing points) and I gleaned those from the other examples.

I was able to replace the `frameCount` generated data with incoming serial data for real time plots.

With some effort you can make this work (hit the play icon on the animation below):

![test.mov](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/71b844dc7e3d805cccada34620c036d4c4c6481f.gif)

I am just sharing…  
This is your project so you make all the decisions.

`:)`

---

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 11, 2021, 3:58am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/5 "2021-11-11T03:58:48Z")

</div>

Hello @RichardDL , yes that’s right, there are still other tabs & arduino code. Do you have arduino around you?  
below I attach another tab.

```auto
  
/* =================================================================================       
     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=5,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);
   
       }
       
       
       
    }
    
 

```

---

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 11, 2021, 4:01am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/6 "2021-11-11T04:01:12Z")

</div>

Thank You @glv for replying again.  
yes, I just saw it yesterday maybe this is another option for me, and I’m trying to modify it.

I apologize in advance because my knowledge in programming is very limited, because I am taking a mechanical course. But it doesn’t matter I’m ready to learn more for this.  
My initial goal was to create two values that move respect to the value on the X axis (Engine RPM). I’ve tried modifying the grafica library but the results are not what I expected,  
here is an example of my results

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/8/84a4113cefb1c84949d500bb033ac189b19bc673.png)

and the code i’m using is here

```auto
import grafica.*;
import java.util.Random;

GPlot plot1;

 void setup(){
  size (600, 350);
  
  // Leave empty the points for the first plot. We will fill them in draw()
  // Setup for the first plot 
  plot1 = new GPlot(this);
  plot1.setPos(20, 10);
  plot1.setDim(450, 200);
  plot1.getTitle().setText("Grafik Torsi dan Daya");
  plot1.getXAxis().getAxisLabel().setText("Engine RPM (x1000)");
  plot1.getYAxis().getAxisLabel().setText("Torsi (Nm) / Daya (HP)");
}
  
 void draw(){
  background(255);
  
  
  // Add a new point to the first plot (will be from serial port)
  GPoint lastPoint1 = plot1.getPointsRef().getLastPoint();
  GPoint lastPoint2 = plot1.getPointsRef().getLastPoint();
  

  int x = frameCount%100;
  float y1 = 30+20*sin(frameCount*TAU/100);
  float y2 = 30+20*cos(frameCount*TAU/10);

  if (lastPoint1 == null) 
    {
    plot1.addPoint(x, y1);
    } 
  else if (!lastPoint1.isValid() || frameCount > 0) 
    {
    plot1.addPoint(x, y1);
    }
    
    if (lastPoint2 == null) 
    {
    plot1.addPoint(x, y2);
    } 
  else if (!lastPoint2.isValid() || frameCount > 0) 
    {
    plot1.addPoint(x, y2);
    }

  // Reset the points if the user pressed the space bar
  //if (keyPressed && key == ' ') 
    if(frameCount%100 == 99)
    {
    plot1.setPoints(new GPointsArray());
    }
  // Draw the second plot  
  plot1.beginDraw();
  plot1.drawBackground();
  plot1.drawBox();
  plot1.drawXAxis();
  plot1.drawYAxis();
  plot1.drawTitle();
  plot1.drawGridLines(GPlot.BOTH);
  plot1.drawLines();
  plot1.endDraw();

}

```

---

<div class="post-metadata">

### Author: ![RichardDL](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@RichardDL](https://discourse.processing.org/u/RichardDL)
#### Post date: [November 11, 2021, 9:47am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/7 "2021-11-11T09:47:50Z")

</div>

@anwar05 Your last plot may be suffering from [aliasing](https://en.wikipedia.org/wiki/Aliasing). Yes I have a few Arduino. Never used Graphica, don’t know why not, looks good. If you want me to run your code please post the json file.

---

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 11, 2021, 10:17am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/8 "2021-11-11T10:17:16Z")

</div>

do you mean the mockupserial?  
So there is 3 tabs i download from [astiannilsson.com/project/realtime-plotter/realtime-data-plotter/](http://astiannilsson.com/project/realtime-plotter/realtime-data-plotter/). which is Realtimebasicplotter, graphclass and mockupserial. And i modify the realtimebasiplotter. Here is the mockup serial, for realtimeplotter and graphclass i’ve posted before. Thank you @RichardDL . I’m also still doing with grafica library but still not works.

```auto
// If you want to debug the plotter without using a real serial port

int mockupValue = 0;
int mockupDirection = 10;
String mockupSerialFunction() {
  mockupValue = (mockupValue + mockupDirection);
  if (mockupValue > 100)
    mockupDirection = -10;
  else if (mockupValue < -100)
    mockupDirection = 10;
  String r = "";
  for (int i = 0; i<6; i++) {
    switch (i) {
    case 0:
      r += mockupValue+" ";
      break;
    case 1:
      r += 100*cos(mockupValue*(2*3.14)/1000)+" ";
      break;
    case 2:
      r += mockupValue/4+" ";
      break;
    case 3:
      r += mockupValue/8+" ";
      break;
    case 4:
      r += mockupValue/16+" ";
      break;
    case 5:
      r += mockupValue/32+" ";
      break;
    }
    if (i < 7)
      r += '\r';
  }
  delay(10);
  return r;
}

```

---

<div class="post-metadata">

### Author: ![RichardDL](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@RichardDL](https://discourse.processing.org/u/RichardDL)
#### Post date: [November 11, 2021, 10:20am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/9 "2021-11-11T10:20:31Z")

</div>

More working now. Still need “plotter\_config.json”

---

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 11, 2021, 11:17am UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/10 "2021-11-11T11:17:30Z")

</div>

Processing: plotter\_config.json…  
here is the plotter\_config @RichardDL

```auto
{
  "bcMultiplier1": "1",
  "bcMaxY": "100",
  "lgMaxY": "10",
  "lgVisible1": "0.0",
  "lgVisible2": "0.0",
  "lgVisible5": "1.0",
  "lgVisible6": "1.0",
  "lgVisible3": "0.0",
  "lgVisible4": "0.0",
  "bcMultiplier6": "1",
  "bcMultiplier3": "1",
  "bcMultiplier2": "1",
  "bcMultiplier5": "0.3",
  "bcMultiplier4": "1",
  "lgMultiplier2": "1",
  "lgMultiplier3": "1",
  "lgMultiplier1": "1",
  "lgMultiplier6": "1",
  "lgMultiplier4": "1",
  "lgMultiplier5": "0.1",
  "bcVisible3": "1.0",
  "bcVisible4": "1.0",
  "lgMinY": "-8",
  "bcMinY": "0",
  "bcVisible1": "1.0",
  "bcVisible2": "0.0",
  "bcVisible5": "1.0",
  "bcVisible6": "1.0"
}

```

---

<div class="post-metadata">

### Author: ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)
#### Post date: [November 11, 2021, 12:05pm UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/11 "2021-11-11T12:05:05Z")

</div>

Hello @anwar05,

> [@glv](#):
>
> Some other modifications were necessary (x and y limits and drawing points) and I gleaned those from the other examples.

You did not set limits on your axes.  
Try one graph at at time for starters; you are combining data and plotting it.  
I used `%100`… % is the modulo operator; look this up and try to understand how it is used and how I used it in my example.

It took some effort for me to get this going…

Keep at it!

`:)`

---

<div class="post-metadata">

### Author: ![anwar05](https://avatars.discourse-cdn.com/v4/letter/a/3ab097/32.png) [@anwar05](https://discourse.processing.org/u/anwar05)
#### Post date: [November 11, 2021, 3:32pm UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/12 "2021-11-11T15:32:56Z")

</div>

@glv,aaaa i see friend  
I just combining data and plotting it. i’ll try and read some example again and again.

---

<div class="post-metadata">

### Author: ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)
#### Post date: [November 11, 2021, 9:31pm UTC](https://discourse.processing.org/t/make-a-realtime-serial-plotter/33438/13 "2021-11-11T21:31:32Z")

</div>

> [@anwar05](#):
>
> i’ll try and read some example again and again

I have never used the grafica library and had to do some work to get this working the first time.

I saw this as a challenge in this post:

> [@Use Processing to make continuous graph using CSV](https://discourse.processing.org/t/use-processing-to-make-continuous-graph-using-csv/16898/14):
>
> Hello @henry67, Take a look at some of the other grafica examples for insight. I modified the one plotting mouse co-ordinates for a real-time plot: [test.mov] slight_smile

Each step gets you closer to your destination.

`:)`
