Problem with moving the zero of the graph

Hello good night, I am working on a project where I am using several sensors, but I only have to graph one of them the air sensor or “inByte [2]”, the problem is that the zero of this sensor is very down in the graph and it is not seen when graphing zero and I do not know how to raise the graph to be able to visualize when the graph is zero, in addition how it could do once the zero is achieved to limit the graph to the white rectangle and that its maximum value does not go out of that rectangle?

This is how my graph looks.

The zero is well below the visible screen.
The zero should look like a continuous line.

This is the code in processing:

import processing.serial.*;

Serial puerto; // se declara una variable para la com. serial
boolean newData = false;
int xPos = 0;         // posición horizontal del gráfico
// Variables para dibujar una línea continua de la gráfica. 
int lastxPos=1;
int lastheight=0;
float inByte[] = {0,0,0,0,0,0,0}; // Datos seriales entrantes

void serialEvent (Serial myPort) { //Datos de la gráfica. 
  // obtener la cadena ASCII:
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    inString = trim(inString);                // recortar espacios en blanco.
    inByte = float(split(inString, ',')); 
    inByte[0] = float(inString);           // convertir a un número.
    inByte[0] = map(inByte[2], 0, 1023, 0, height); //mapa a la altura de la pantalla.
    newData = true; 
    
    
  }
}

public void setup(){
   size(1000, 600, JAVA2D); //Tamaño de la ventana principal
   background(17,34,51); 
   rect(-1, 95, 1001, 330,1); // Tamaño del rectángulo blanco donde se grafican los datos
   puerto = new Serial(this,Serial.list()[0], 9600); //Busca puerto serie conectado automáticamente.
   puerto.clear();
   puerto.bufferUntil('\n');
}

public void draw(){
   println(inByte[0],inByte[1],inByte[2],inByte[3],inByte[4]);
  if (newData) {
    stroke(17,34,51);     //Color de la línea graficadora. 
    strokeWeight(1);        //Grosor de la línea graficadora.
    line(lastxPos, lastheight, xPos, height - inByte[0]); 
    lastxPos= xPos;
    lastheight= int(height-inByte[0]);
    
     // Dibujando una línea desde Last inByte hasta la nueva.
     // en el borde de la ventana, regrese al principio:
    if (xPos >= width) {
      xPos = 0;
      lastxPos= 0;
      saveFrame( "Pantallazos Automáticos cada 30s"+"/"+day()+"-"+month()+"-"+year()+" a las "+hour()+"_"+minute() +" con "+ second()+"s"+ ".png") ; //dar nombre de fecha a los pantallazos
     // background(17,34,51);  //Clear the screen.
      rect(0, 95, 999, 355,1); // Tamaño del rectángulo blanco donde se grafican los datos
      stroke(196,196,196); // Color de la línea del cuadriculado

    } 
    else {
      // Incrementa la posición horizontal.
      xPos++;
    }
   newData =false;
 }
}

And in Arduino the data is sent like this:

  Serial.print(",");
  Serial.print( t );          
  Serial.print(",");
  Serial.print( grafAire);         
  Serial.print(",");
  Serial.print( h ); 
  Serial.print(",");
  Serial.println(mmHg); 
  delay(30);

In the arduino serial plotter the data is well plotted but I need to graph it in processing.

On line 43 I modified these values and managed to visualize the zero but changing the resolution of the graph by modifying the “1023” which does not help me because I need to work with the resolution to “1020”

  void serialEvent (Serial myPort) { //Datos de la gráfica. 
  // obtener la cadena ASCII:
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    inString = trim(inString);                // recortar espacios en blanco.
    inByte = float(split(inString, ',')); 
    inByte[0] = float(inString);           // convertir a un número.
    inByte[0] = map(inByte[2], 0, 1023, 0, height); //mapa a la altura de la pantalla.
    newData = true;

I appreciate all the help and any comments if I am making a basic mistake in the method of sending data, if you know a better method, I would appreciate it if you could teach it to me.

Is the zero from your sensor actually 0, or is it a negative value?
Your zero will appear right on the bottom of the window, due to this line:

line(lastxPos, lastheight, xPos, height - inByte[0]);

If you want to lift the graph up, add an offset (50px, or whatever you wish):

int offset = 50;
// ...
line(lastxPos, lastheight - offset, xPos, height - inByte[0] - offset);

If you want to shift everything that you draw up, you could instead do it with translate:

void draw() {
  translate(0, -50);
  // ...

Hello, thank you very much for your response, well, I tried to try your suggestion and add the offset:

int offset = 50;
// ...
line(lastxPos, lastheight - offset, xPos, height - inByte[0] - offset);

The zero does not rise and this also happens.

And yes, the zero of my graph is zero, it is not a negative number.

And when trying to use the “translate” what happens is this:

What happens is that the graph is starting at the top of my complete window, I need it to start at the bottom of the white rectangle and also stay only in that space and not leave the margin. How could I do it?
Thanks for your help :slight_smile:

1 Like

Excuse me, you were right that was the solution to raise the zero, thank you very much for your help :), excuse me just one more question, how could I do to delimit my graph to the white rectangle and not leave that box?

1 Like

It looks like you are drawing big banner regions on the top and bottom of the screen – and it looks like you are drawing them after (on top of) your graph content. They would hide the zero of the canvas area. Those didn’t appear in your example code. Is that what is happening?

Edit – oops, I see that you answered while I answered. Glad it worked!

1 Like

There are lots of ways – it depends on what you are doing. One way is to draw onto a PGraphics, then display the results with image() – this will clip to a drawn surface. Another is to just draw the controls on top – I think you are already doing this? If the question is how to scale to an available area, take you maximum and minim expected y values and center your available region on this. You can use map() for this:

yPos = map(dataVal, minVal, maxVal, minY, maxY);

I’d suggest playing around with a bare-minimum mockup sketch using random data to explore these ideas about layout, rather than first attempting them in what looks like a very complex sketch.

int xPos = 0;
float lastYPos=0;

void setup() {
  size(400, 400);
}

void draw() {
  
  // central graph
  pushMatrix();
  translate(0,height/2.0);
  if(xPos==0){
    background(192);
    line(0,0,width,0);
  }
  float yPos = random(-height/3.0, height/3.0);
  line(xPos-1, lastYPos, xPos, yPos);
  xPos = (xPos+1)%width;
  lastYPos = yPos;
  popMatrix();
  
  // controls
  rect(0,0,width,height/6.0);
  rect(0,height*5/6.0,width,height*1/6.0);
}

So, what if your random value range was something else – how would you map it to the available layout here?

1 Like