Input Devices

So I'm still not entirely sure what my final project will be, but I know that even if I don't make it the most advanced electric skateboard man has ever seen, I do want one, and I WILL have one, preferrably by Christmas.  Therefore I have decided to use the same type of force sensors I'd probably use in my board, the Flexiforce.  Their manufacturer recommends an excitation circuit which I plan on building, and which would give a clean 0-5V signal over the range of forces the sensor is rated for.  This is convenient for use with the Arduino.  However, the parts I needed to make the circuit haven't come in yet; neither am I certain of how I'm going to supply bipolar voltage to the op-amp in the excitation circuit, which calls for +-9V.  I could do this with a pair of batteries, but I'd like to stay away from bunch of separate batteries, let alone a separate pair of batteries for each sensor (I'm thinking I'd have between 4 and 8 on my board, probably 6).   So I'm thinking I'm going to have to play around with step-down dc-dc transformers (36->9, 36->5), and voltage inverters (+5->-5, +9->-9).  That can come later.  For now, I had the parts to build a simple RC circuit using the Flexiforce, out of which I can back out the resistance, in real time, with some constraining factors (i.e. frequency of measurement cannot be greater than the time constant for the given capacitor and state of the Flexiforce (which is a variable resistor, like a potentiometer)).  Also, the capacitor I had (0.1uF) resulted in fast enough time constants that the millisecond clock I was using to calculate the time constant couldn't take me below 250 kOhm, whereas I should be able to go down to about 75 kOhm with enough force.  No-load resistance was sufficiently high that I never calculated it, though it should be between 10 and 50 MOhm. 

I used the Arduino here because I wanted to get better with it, because I'd like to code my project upon it, and there's a good code base.  For instance, I adapted my graph from one of Arduino's tutorials (Graph).  To get Arduino to report data back to the computer, I used a serial protocol called Firmata, in conjunction with Processing, a separate piece of software with an IDE much like Arduino's.  I loaded the Arduino with Firmata_Standard, which allowed it to interface with Processing, into which I had already installed an arduino library.  (Refer to http://www.arduino.cc/playground/Interfacing/Processing for detailed instructions).  Processing read in the analogRead() pin I setup on the Arduino and processed the data into a graph.  Supposedly Arduino has it's own Serial library to do similar stuff, but most people who did any visual data representation I could find ended up using Processing instead.  Note: I had trouble with the current (Nov 2008) Arduino, the 0012 Alpha, and Firmata.  I had to use 0011.  Also, I couldn't get Firmata v2 to work, and had to use v1 instead.  For what it's worth.

Below I have pictured the simple RC circuit:

Schematic

And here's a picture of my setup:

Setup

This is the code I adapted (mainly from the Graph and CapacitanceMeter tutorials on the Arduino site).



/*This code should be run in Processing, not Arduino (hence the separate Arduino object
Follow the instructions at http://www.arduino.cc/playground/Interfacing/Processing
Note that I couldn't get Arduino 0012 to work properly with Firmata and had to load Firmata_Standard to the Arduino
using 0011 (you have to have Firmata running on your Arduino to get Processing to work)
*/

import processing.serial.*;
import cc.arduino.*;

Arduino arduino;

float[] xvals;
float val;
int forcePin=0;          // analog pin for measuring capacitor voltage
int chargePin=13;         // pin to charge the capacitor - connected to one end of the charging resistor
int dischargePin=11;         // pin to discharge the capacitor
float resistorValue;   // Flexiforce
                                
float capacitorValue = 10E-7;  //.1 uF, which ends up being a bit sensitive
long startTime;
long elapsedTime;

void setup()
{
  size(512, 512);
  xvals = new float[width];
  smooth();
  arduino = new Arduino(this, Arduino.list()[2], 57600);  //Baud rate 57600 for Firmata v1, 112500 for Firmata v2 (I couldn't get v2 to work)
  PFont font;
  font = loadFont("SansSerif.plain-24.vlw");  //You may have to create this font in Tools -> Create Font
  textFont(font);
 
  arduino.pinMode(chargePin, Arduino.OUTPUT);     // set chargePin to output
  arduino.digitalWrite(chargePin, Arduino.LOW); 
 
  //println(Arduino.list());  //Use this command to see if the argument for Arduino.list()[x] is correct
 }


void draw()
{
  background(0);
 
  // shift array left by one
  for(int i=1; i<width; i++) {
    xvals[i-1] = xvals[i];
  }
 
  arduino.digitalWrite(chargePin, Arduino.HIGH);  // set chargePin HIGH and capacitor charging
  startTime = millis();
 
  while(arduino.analogRead(forcePin) < 648){       // 647 is 63.2% of 1023, which corresponds to full-scale voltage
    }
 
  elapsedTime= millis() - startTime;
 
  resistorValue = ((float)elapsedTime / capacitorValue) * 10E-3;  //convert from ms to sec, tau = RC  -->  R = tau/C
 
  // dicharge the capacitor 
  arduino.digitalWrite(chargePin, Arduino.LOW);             // set charge pin to  LOW
  arduino.pinMode(dischargePin, Arduino.OUTPUT);            // set discharge pin to output
  arduino.digitalWrite(dischargePin, Arduino.LOW);          // set discharge pin LOW
  while(arduino.analogRead(forcePin) > 0){         // wait until capacitor is completely discharged
  }
 
  arduino.pinMode(dischargePin, Arduino.INPUT);            // set discharge pin back to input
 
  val = resistorValue/1000; //convert to kOhm
  xvals[width-1] = val;

  // draw the array
  for(int i=1; i<width-1; i++) {
    stroke(255);
    float yscale = 255 * (xvals[i]/2E4);  //empiric value for 2E4 to get decent range in window over forces input to 25lb Flexiforce w/fingers
    float yscale2 = 255 * (xvals[i+1]/2E4); //we're going to draw lines
    if (yscale > 255)
      yscale = 255;
    if (yscale2 > 255)
      yscale2 = 255;
    int yscale_int = round(yscale);
    int yscale2_int = round(yscale2);
    line(i, 255 - yscale_int, i+1, 255 - yscale2_int);  //flip y coordinate so 0 is below
    //point(i, 255-yscale_int); //flip y coordinate so 0 is below
  }
  textAlign(RIGHT);
  text((xvals[width-1])+" kOhm",200,60);
}

Running this code yields the following output.  The response is rather high frequency because of the anemic capacitor I used, but it was all I had at that moment.  I will update it with a larger capacitor to come.

Graph

Graph