Sep 21, 2013

graphing in the arduino serial monitor using text

After you get numerical values to display on the Serial Monitor in the Arduino IDE, you may wish to see the number pattern. This can be hard if the data is not just an incrementing variable. Here is a technique I use all the time. I plot the data on the screen, with the time axis vertical.

In this example, I am generating a repeating waveform in main loop and plotting the result to the monitor. Also, I am using one of the ways to format a number so that the width is consistent (using a function to convert to a formatted string).

// dtostrf(FLOAT,WIDTH,PRECISION,BUFFER); gist.github.com/2343665 

The simple version looks like this:

Simple Graph

void loop(void) {
...
  v = 2048*(1.2 + .5*sin(6.2832*1.0*t)+0.2*sin(13*t+7)-.3*cos(37*t));
 
  v_scaled = map(v,0,4096,1,100); // scale to fit Monitor window: set wide (~ 100)
  dotgraph(v_scaled); // simplest 
...
}


// mini ascii "dot" graph
byte dotgraph(byte n) {
  int i;
  spc(n);
  Serial.print("*\r\n");
}

//--- print n spaces
byte spc(byte n) {
  int i;
  if (n > 0){  
    for (i=0; i < n; i++){  
      Serial.print(' ');
    }
  }
}

A slightly more advanced version takes x and y as inputs, and has a mode option to update the graph on a single line (like and LED bar graph). For single-line mode, the output must be directed to an actual terminal program that distinguishes between 'carriage return' and 'linefeed' (such as OS X: Terminal, Win: Teraterm).



...
  v = 2048*(1.2 + .5*sin(6.2832*1.0*t)+0.2*sin(13*t+7)-.3*cos(37*t));
 
  v_scaled = map(v,0,4096,1,100); // scale to fit Monitor window: set wide (~ 100)
  graph(t,v_scaled,1); 
...
} 

// ------------------------------------------------------------------------------------
int graph (float x, float y, int mode) { // draw a text-based vertical graph to monitor
  int i;
  int k;
  int maxWidth = 100;     // width of the graph "column"
  char linechar = '-';
  char plot[maxWidth+1] ;

  k = int(y);
  for (i=0; i= maxWidth) plot[maxWidth] = ']';
  else  plot[maxWidth] = '|';
  if (k < 1) plot[0] = '[';

  // print a row of the graph
  dtostrf(x,6, 2, xbuf);  // -nnnnnn.nn 
  Serial.print(xbuf); 
  Serial.print(" ");
  dtostrf(y,8, 1, xbuf);  // -nnnnnn.nn 
  Serial.print(xbuf); 
  Serial.print(" | ");
  for (i=0; i<=maxWidth; i++) {  // print array to make a graph
    Serial.print(plot[i]);
  }
  if (mode == 0) Serial.print("\r");   // single line refresh won't work using built-in monitor; needs terminal
  if (mode >= 1) Serial.print("\r\n"); // \r\n for apple/unix terminal 
}

  

No comments: