MAD Burster Processing.pde

From meaning
Jump to: navigation, search
// MAD Burster Strip Chart Display for Processing 1.1
// Copyright 2010 Glenn Powers <glennpowers@gmail.com>
// http://meaning.com/wiki/MAD_Burster

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 3 of the License.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

/* Includes "stripchart recorder" class by J David Eisenberg
 * http://www.openprocessing.org/visuals/?visualID=6789
 */
 
import java.text.DecimalFormat;
 
/**
 * Draws a stripchart recorder.
 */
class Stripchart {
  int x;           // horizontal position of chart
  int y;           // vertical position of chart
  int nSamples;    // number of samples to display (affects width)
  int h;           // height of chart
  color colour;    // color of dots to plot
  int dataPos;     // where does next data point go?
  int startPos;    // where do we start plotting?
  int nPoints;     // number of points currently in the array
  int period;      // how often to draw a gray line
  float minValue;  // minimum value to display
  float maxValue;  // maximum value to display
  float [ ] points;  // the data points to plot
   
  private DecimalFormat d = new DecimalFormat("0.#");
  private String minString;  // minimum value as a string
  private String maxString;  // maximum value as a string
   
  //private PFont legendFont = loadFont("ArialMT-10.vlw");
  private float prevX;    // remember previous point
  private float prevY;
 
  /*
    rightSpace tells how much room there is for the chart
    legend. VSPACE and HSPACE give the spacing from the border
    of the stripchart to the point plotting area.
  */
  private int rightSpace = 0;
  final static int VSPACE = 2;
  final static int HSPACE = 2;
 
  Stripchart( int x, int y, int nSamples, int h, int period, color c,
  float minValue, float maxValue)
  {
    this.x = x;
    this.y = y;
    this.nSamples = nSamples;
    this.h = h;
    this.period = period;
    this.colour = c;
    // make sure minimum and max are in proper order
    this.minValue = min(minValue, maxValue);
    this.maxValue = max(minValue, maxValue);
     
    // and convert them to a string with minimal numbr of decimal places
    this.minString = d.format(minValue);
    this.maxString = d.format(maxValue);
    nPoints = 0;
    dataPos = 0;
    startPos = 0;
    points = new float[nSamples];
  }
 
  Stripchart( int x, int y, int w, int h, int period, color c)
  {
    this(x, y, w, h, period, c, h/2.0, -h/2.0);
  }
 
  /**
   * Add a data point to be plotted.
   * At this point you may be wondering why I am using an array
   * instead of an ArrayList. Although programmaticaly it may
   * be easier to add a new value to the list and remove the
   * first one, it takes much less compute time to calculate
   * a mod and keep track of where the oldest data is.
   *
   * @param value the value to plot
   */
  void addData(float value)
  {
    value = constrain(value, minValue, maxValue);
    points[dataPos] = value;   
    dataPos = (dataPos + 1) % nSamples; // wrap around when array fills
 
    /*
     * If the array isn't full yet, add to the end of the array
     * Otherwise, the start point for plotting moves through
     * the array.
     */
    if (nPoints < nSamples)
    {
      nPoints++;
    }
    else
    {
      startPos = (startPos + 1) % nSamples;
    }
  }
   
  void display()
  {
    int arrayPos;
    float yPos;
    stroke(0);
    fill(255);
    pushMatrix();
    translate(x, y);
    //textFont(legendFont);
     
    // reserve space for the max/min value legend
    rightSpace = max(int(textWidth(minString)), int(textWidth(maxString)));
    rect(0, 0, nSamples + rightSpace + 2 * HSPACE, h + 2 * VSPACE);
    stroke(192);
    line(HSPACE, VSPACE + h / 2, nSamples + rightSpace - HSPACE, VSPACE + h / 2);
    line(nSamples + 1, VSPACE, nSamples + 1, h - VSPACE);
     
    // draw max and min values
    //textFont(legendFont);
    fill(0);
    stroke(0);
    text(minString, nSamples + 2, h - VSPACE);
    text(maxString, nSamples + 2, VSPACE + 8);
    
    for(int i = 0; i < nPoints; i++)
    {
      arrayPos = (startPos + i) % nSamples;
      if (period > 0 && arrayPos % period == 0)
      {
        stroke(192);
        line(nSamples - nPoints + i, VSPACE, nSamples - nPoints + i, h - VSPACE);
      }
      stroke(colour);
      yPos = VSPACE + h * (1.0 - (points[arrayPos] - minValue) / (maxValue - minValue));
       
      // Draw a point for the first item, then connect all the other points with lines
      if (i == 0)
      {
        point(nSamples - nPoints + i, yPos);
      }
      else
      {
        line(prevX, prevY, nSamples - nPoints + i, yPos);
      }
      prevX = nSamples - nPoints + i;
      prevY = yPos;
    }
    popMatrix();
  }
 
  /**
   * Add a data value and re-display the strip chart.
   * The addData() and display() methods are decoupled;
   * this lets you "speed up" the chart by adding
   * several points before displaying the chart.
   * This method is a convenience method that does
   * both actions.
   *
   *  @param value the value to add and display
   */
  void plot(float value)
  {
    addData(value);
    display();
  }
}
 
Stripchart s1;
Stripchart s2;
Stripchart s3;
int n = 0;

import processing.serial.*;

int lf = 10;    // Linefeed in ASCII
String myString = null;
Serial myPort;  // The serial port 
 
void setup() {
  size(400, 500, P2D); // animation is much smoother in P2D; text looks better with JAVA2D
  background(255);
  
  myPort = new Serial(this, "/dev/tty.usbserial-A800csXo", 115200);
  myPort.clear();
  
  // Throw out the first reading, in case we started reading 
  // in the middle of a string from the sender.
  myString = myPort.readStringUntil(lf);
  myString = null;
   
  /* Stripchart setup
   *
   * Parameters to constructor are:
   * x position, y position
   * number of data points to display at any time
   * height of "recording" area
   * interval at which to draw the gray vertical bar; set to zero for no bar
   * color of stripchart plot
   * minimum and maximum values to plot (will constrain to those values)
   *
   * The actual height of the stripchart includes some extra vertical space
   * above and below the recording area. The actual width of the stripchart
   * includes room for the minimum and maximum values.
   */
  s1 = new Stripchart(10, 50, 300, 100, 45, color(0, 128, 0), -4000, 4000);
  s2 = new Stripchart(10, 160, 300, 100, 45, color(255, 0, 0), -4000, 4000);
  s3 = new Stripchart(10, 270, 300, 100, 45, color(0, 128, 128), -4000, 4000);
  frameRate(60);
}
 
void draw() {

  int sensor = 0;
  int value = 0;
  int time = 0;
  
  myString = myPort.readStringUntil(lf);
    if (myString != null) {
      //print(myString);
    
    String[] pieces = split( myString, ',');
    sensor = int(pieces[0]);
    value = int(pieces[1]);
    time = int(pieces[1]);

    if (sensor == 0) {}
    if (sensor == 1) { s1.plot(value); }
    if (sensor == 2) { s2.plot(value); }
    if (sensor == 3) { s3.plot(value); }
    }
}

Site Information
Personal tools