Output Devices
So my output device was pretty obvious given my final project. I
want to drive a dc motor, and I've already built the force sensor /
Arduino / Processing interface. So my task was to integrate the
force sensors with the motor control. The arduino makes this
fairly easy with the PWM analogWrite() function. The only hard
part of this exercise was wiring up the OSMC motor controller (a beefy,
well protected, open source controller) and figuring out how I'm going
to variable brake and provide current limitation. I'm thinking
I'll make a board with a comparator and shunt resistor for the current
limitation, maybe one from the battery and from the motor,
depending. The MOSFETS on the OSMC, as I have them configured,
are supposed to be good to 80A (half of the 160 it's capable of,
because I left off half the FETs), but this is a bit of a lie, as it
varies with temperature, and I have neither fan nor heat sinks (I'll be
drawing between 10 and 20A for most of the duration of a ride).
The variable brake is provided by a modulated signal to the DISABLE pin
on the H-bridge driver, but if you do this all at once, you get a huge
surge of current if you're traveling at higher speed and higher
inertial loads. So the modulation factor is important, but I
really want to get my board current limited before I try messing around
with braking.
Here's a picture of the setup. There's an arduino, echoing debug
and graph back to my computer via processing, hooked into a board I
made which is a bunch of voltage dividers in parallel (which will read
six independent force sensors), hooked into the OSMC motor controller,
which is itself hooked into my skateboard motor (the truck has been
removed so that I could insert a thin metal plate to provide an even
pressure transmission surface to the force sensors, which will fit
between the trucks and board.

Here's a picture of the voltage divider board:

Here's a picture of me mapping input to output. Note: I used
conductance as a measure instead of resistance, because resistance is
roughly hyperbolic while conductance is more or less linear.
Refer to the FlexiForce mapping of force to resistance below.


I also tried hooking up a speaker to the Arduino, and making Neil's
speaker board. The arduino delay(milliseconds) command doesn't
seem to give very good pulse lengths for low values of milliseconds,
because I basically got a bunch of clicking for 1000Hz (the highest
theoretic frequency you can get using delay(), as opposed to
delayMicroseconds(), which is not included in the Processing Arduino
library). In the loop, it seemed to be moving at more like 20Hz,
though that might have something to do with the println statement I was
using to test. I was in the process of trying to code Neil's
board in C (as only assembly has been provided for all of the I/O
devices), but I didn't really see the point, as I'm doing everything
off the Arduino anyway.
Here's my Processing code:
/*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;
int motorPin = 11;
int speakerOut = 10;
int forcePin1 = 0;
int forcePin2 = 1;
float[] xvals;
float val_1;
float val_2;
float resistor_FF_1;
float resistor_FF_2;
float resistor_oth = 100E3;
float Vin = 5;
int mtest=0;
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(motorPin, Arduino.OUTPUT);
arduino.pinMode(speakerOut, Arduino.OUTPUT);
/*for (int i=0; i<3000; i++) { //mimic startup
calibration routine (tone)
arduino.digitalWrite(speakerOut, Arduino.HIGH);
delay(1);
arduino.digitalWrite(speakerOut, Arduino.LOW);
delay(1);
//println(i);
}*/
//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];
}
val_1 = (float)arduino.analogRead(forcePin1)*5/1023; //convert
to 5V scale
val_2 = (float)arduino.analogRead(forcePin2)*5/1023;
println("val_1: " + val_1 + " val_2: " + val_2);
resistor_FF_1 = (resistor_oth*(Vin/val_1) - resistor_oth)/1000;
if (resistor_FF_1 > 10E3) //greater than 10 MOhm
resistor_FF_1 = 10E3;
resistor_FF_2 = (resistor_oth*(Vin/val_2) - resistor_oth)/1000;
if (resistor_FF_2 > 10E3)
resistor_FF_2 = 10E3;
xvals[width-1] = (1/resistor_FF_1) - (1/resistor_FF_2);
//xvals[width-1] = resistor_FF_1 - resistor_FF_2;
delay(200);
if (xvals[width-1] < 0)
mtest = 0;
else mtest = round(255*xvals[width-1]*50);
println("mtest: " + mtest);
arduino.analogWrite(motorPin, mtest);
// draw the array
for(int i=1; i<width-1; i++) {
stroke(255);
float yscale = 255 * (xvals[i]*50);
///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]
*50); ///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])+" (1/kOhms)",300,60);
}