Analog Data Acquisition from USB Microcontroller using the “Processing” Language

Posted by – March 25, 2009

Building on the previous two mini-projects, I have a mini-graphical data acquisition project now running under the Processing language, getting real-world signals from the USB microcontroller (which is a Microchip PIC on a UBW Board from Sparkfun).  Source code below the screenshot.

USB microcontroller sends data to Processing application, which graphs the data

USB microcontroller sends data to Processing application, which graphs the data

The sampling rate runs at the frame rate (maximum unknown, perhaps depends on my Macbook’s speed of running Java) and microcontroller timer update rate (minimum 1 millisecond).  With a little more work this could be turned into a low-rent (really low rent) oscilloscope as well.

// UBW Microcontroller Analog Data Acquisition #1; jcline 2009-03
import processing.serial.*;
Serial ubw; // USB microcontroller communication
int loops = 0;
int[] xvals;

void setup() {
  String ubwVersion;
  boolean found;
  float tdelay;
  found = false;
  size(400,100);
  background(0); // black
  frameRate(120); // sets draw rate
  stroke(255); // white
  xvals = new int[width];

  try {
    println(Serial.list());
    ubw = new Serial(this, Serial.list()[0], 9600); // serial rate doesnt matter
    tdelay=millis() + 5000;
    // Read firmware version from connected UBW Microcontroller; jcline 2009-03
    for (int i=0; millis() < tdelay ; i++) {
        // Get+Verify UBW version string, print to console
        ubw.write("v\n");
        delay(100);
        ubwVersion = ubw.readStringUntil('\n');
        if (ubwVersion != null) {
          if (ubwVersion.startsWith("UBW", 0)) {
            println("Found UBW attached to USB:\n");
            println(ubwVersion);
            found = true;
            break;
          }
        }
    }
  }
  catch (Exception e) {
    println("device access error\n");
  }

  if (found != true) {
    println("exit\n");
    exit();
  }
  else {
    ubw.write("C,255,255,255,1\n");
    ubw.write("CU,1,0\n");
    ubw.write("T,100,1\n"); // set timered update in millisec, A=1
    ubw.clear(); // flush
  }
}

// Microchip's firmware uses %4u output for output of analog data values
// Convert "0023" string to Int 23
Integer string4uToInt(String s) {
   char a[] = s.toCharArray();
   Integer i = 0;
   Integer v;
   // char array into positional math based on ASCII value
   v = byte(a[0]) - 48;
   i += v * 1000;
   v = byte(a[1]) - 48;
   i += v * 100;
   v = byte(a[2]) - 48;
   i += v * 10;
   v = byte(a[3]) - 48;
   i += v;
   return (i);
}

// Read analog data depending on framerate & draw graphical level indicator
void draw() {
  String cmd;
  String data;
  Integer val;

  loops++;
  if (loops > 20000) {
    noLoop();
    ubw.write("T,0,1\n"); // Turn off timered updates
    println("done\n");
    ubw.stop();
  }

  data = ubw.readStringUntil('\n'); // read timered update
  if (data == null) {
    return; // no periodic data yet
  }
  if (data.startsWith("A,", 0) == false) {
    println("bad input: "+data+"\n");
    return;
  }
  val = string4uToInt(data.substring(2, data.length()));
  background(0);
  for(int i=1; i<width; i++) {
    xvals[i-1] = xvals[i];
  }

  stroke(255);
  xvals[width-1] = height - val;
  for(int i=1; i<width; i++) {
    point(i, xvals[i]); // See processing.org's example "mouse signals"
  }
}

One bug is the exit handling of the application, which doesn’t disable the analog timer, so I think the USB/serial buffer becomes overrun; anyway, the microcontroller needs resetting between runs if the Processing application is prematurely terminated.  It’s something to clean up for next time.  Right after I figure out who is & is not a cylon.

3 Comments on Analog Data Acquisition from USB Microcontroller using the “Processing” Language

  1. Norman says:

    Hey Jonathan, I used to code processing quite a bit for data visualization at work…. now coding up the stuff but for Arduino instead (it’s based on Processing). It’s quite fun acquiring real world data, currently I got it hooked up to a CO2 sensor and building a bioreactor control system. I’d recommend using Eclipse as IDE eventually as your code gets more complex.

  2. Norman –
    What’s the part #s for the sensors you are using?

  3. […] Labview is quite expensive, and industrial-grade high voltage switching boards are also quite expensive.  So I built my own hardware and the Processing.org language is an easy way to test things.  The Processing.org language is a free, open source graphics/media/IO layer on top of Java (as posted pre…. […]