Posts

  • Journey and Rhythms
    Sunday, December 13, 2009

Events

Deadlines

  • I have no upcoming deadlines worth mentioning. Other then some grad school bills.

Projects

  • I'm working on some top secret projects. Can't talk about them.
Processing Visualization of Analog Values

Processing Visualization of Analog Values

Sometimes you need to test the Analog values that you are receiving from the Arduino Board. It’s good to have a sketch that plots the values for you. I’ve written this sketch so that it adjust for the screen height and width. The Arduino code to get the Analog Values can be found here.

import processing.serial.*;
import processing.opengl.*;

Serial port;                         // Setup a Serial Object
String message = null;               // Stores Incomming messages
String elements[] = null;            // Stores String Values from Incoming Message
int values[] = { 0,0,0,0,0,0 };      // Holds Values of the current Analog Inputs      

int numOfSensors = 4;   // Total number of pins being used
int buffHistSize = 120; // Array size that hold history of Analog pin reading 

int[][] sensorValues = new int[numOfSensors][buffHistSize];       // Range(0-1024)
int[][] avgAdjSensorValues = new int[numOfSensors][buffHistSize]; // Adjust Avg

void setup() {
  smooth();
  frameRate(22);
  size(640,480, OPENGL);    

  // INTIATE SERIAL CONNECTION
  println(Serial.list());
  println("Opening Serial: "+Serial.list()[2]);
  port = new Serial(this, Serial.list()[2], 1000000);
  println("...Opening the Serial port forces the Diecimila to reboot...");
  println("...so wait till the Arduino boots and send out a message...");
  // Wait till Arduino boots
  while (port.available() == 0 ) { };
  println("...Arduino has Completed Booting...");
}

void draw() {
  background(0);

  readSerialAndParse(); // Load our Array with values from the Serial Port

  for(int p = 0; p < numOfSensors; p++) {
    updateAbsValueHistory(p, sensorValues[p]); // Calculate Adj Values
    drawSensorReadings(p);  // Graph Analog Input Values
    drawAverageLine(p);     // Draw the running Average of the Analog Input
  }
}

/**************************************************************
 * Check Serial Port and Read in Message, and Parse Info
 ***************************************************************/
void readSerialAndParse(){
  while (port.available() > 0) {
    message = port.readStringUntil(10); // Read message until a newline return
    if (message != null) {
      // println(message); // DEBUG LINE
      elements = splitTokens(message);
      for (int i =0; i < elements.length && i < 6; i++ ) {
        values[i] = int(elements[i]);
      }
    }
  }

  // Shift Values Over One, Before we Store the incomingBuffer
  // [0][1][2][3] Before Values Move Over, Don't Move the Last One
  // [1][2][3][3] After
  for( int j = 0; j < numOfSensors; j++ ) {
    for (int k = 0; k < buffHistSize - 1; k++) {
      sensorValues[j][k] = sensorValues[j][k + 1];
    }
  }

  // Stores the incomingBuffer in the last indexed position
  // [1][2][3][3] Make sure you replace the Index Value
  // [1][2][3][x] With the latest value, represented with 'x'
  for( int a = 0; a < numOfSensors; a++ ) {
    sensorValues[a][buffHistSize - 1] = values[a];
  }
}

/**************************************************************
 * Uses drawGraph to draw all SensorReadings
 * Auto Generates Color Value Based on HSB Color Map
 * COLOR MAPPING ONLY APPLIES TO 4 SENSORS
 * int k represents the index of the sensor Array
 *
 * PIN
 * 1 = Red, index = 0
 * 2 = Green, index = 1
 * 3 = Cyan, index = 2
 * 4 = Purple, index = 3
 ***************************************************************/
void drawSensorReadings(int k) {
  // We are gonna Change the Color Mode Here
  colorMode(HSB,100);

  pushMatrix();
  strokeWeight(2);
  stroke( k*(100/numOfSensors), 100, 100, 60);
  drawGraph(sensorValues[k]);
  //drawGraph(avgAdjSensorValues[k]);
  popMatrix();

  colorMode(RGB,255);
}

/**************************************************************
 * Takes an Array of Values and Plots it out
 * Function Adjust for Sketch Size
 * Porportionally Maps Range of Analog Values (0-1024) to Height of Sketch
 ***************************************************************/
void drawGraph(int[] plotData) {
  // Adjust for Canvas Size
  // Analog input Range is from 0 -
  float hRatio = height / 1024.0;

  for (int i = 0; i < plotData.length - 1; i++) {
    float plotValueCur = plotData[i] * hRatio;
    float plotValueNext = plotData[i + 1] * hRatio;
    float lineLenght = float(width) / ( plotData.length - 1 );
    line(i * lineLenght, plotValueCur, (i + 1) * lineLenght, plotValueNext);
    ellipse( (i + 1) * lineLenght, plotValueNext, 3, 3);
  }
}

/**************************************************************
* plotData holds a history of the Analog pin Readings
* Make room for the latest by shifting the array from right to left
* Take the raw SensorValue, and calculate it's absolute value from
* the average.  Store that number in 'avgAdjSensorValues'
***************************************************************/
void updateAbsValueHistory(int x, int[] plotData) {
  // Shift Array values from Right to Left
  // Before we find out curent Absolute Value
  for (int k = 0; k < plotData.length - 1; k++) {
    avgAdjSensorValues[x][k] = avgAdjSensorValues[x][k + 1];
  }

  int runningAvg = calcAverage(sensorValues[x]); 

  // Load the last element in Our Array with the Adjusted Value
  // It's a Relative Increment from the Average
  avgAdjSensorValues[x][plotData.length - 1] = abs(runningAvg - sensorValues[x][plotData.length - 1]);
  // println("avgAdjSensor:"+x+" "+avgAdjSensorValues[x][buffHistSize - 1]); // DEBUG LINE
}

/**************************************************************
 * Returns the Average Value from a Group of Numbers
 * PlotData Values Correlate with Analog Readings Range: (0-1023)
 ***************************************************************/
int calcAverage(int[] plotData) {
  int total = 0;
  int average = 0;

  for (int i = 0; i < plotData.length - 1; i++) {
    total = total + plotData[i];
  } 

  average = int(total/plotData.length);
  // println("Avg: "+average); // DEBUGLINE
  return average;
}

/**************************************************************
 * Draws a line that indicates the Average Value
 * 'x' parameter is the index of an array that correlates to the Pin
 * Drawn line is adjusted for Height Ratio of Sketch
 * Line Color Matches Analog Graph
 ***************************************************************/
void drawAverageLine(int x) {
  // We are gonna Change the Color Mode Here
  colorMode(HSB,100);

  float hRatio = height / 1024.0;
  int adjAnalogAvg = calcAverage(sensorValues[x]);
  stroke( x*(100/numOfSensors), 100, 100, 60);
  line( 0, adjAnalogAvg * hRatio, width, adjAnalogAvg * hRatio);  

  colorMode(RGB,255);
}
blog comments powered by Disqus