Hi all:
I know there have been a few threads on this topic already, but I haven't found anything that's worked for me yet.
I'm making a simple speedometer with a reed switch, and I want to send a MPH value with 2 decimal places over USB to a Processing app. So far everything works perfectly, except that what's being sent over USB seems to be an integer approximation of my float value. I've tried multiplying by 100, but I just end up with round 100's, like "800". So I'm not sure what to do. Thanks in advance for your help!
Arduino:
#define LED 13 //pin for the LED
#define SWITCH 0 //input for REED SWITCH
int rim = 2170; //circumference in mm
int val = 0; // used to store input value
int previousVal = 0; // lets not be too repetitious
unsigned long revTimer; // the last time the output pin was toggled
unsigned long serialTimer;
long debounce = 10; // the debounce time, increase if the output flickers
int cycles = 1; // total number of revolutions
float currentSpeed = 0; // current speed in MPH
void setup() {
pinMode(LED, OUTPUT); //tell arduino LED is an output
pinMode(SWITCH, INPUT); //SWITCH is input
Serial.begin(9600);
revTimer = millis();
serialTimer = millis();
}
void loop(){
val=digitalRead(SWITCH); //read input value and store it
//check whether input is HIGH (switch closed)
if (val==HIGH) {
digitalWrite(LED, HIGH); //turn LED on
previousVal = HIGH;
//if(millis()-revTimer > 2000) currentSpeed = 0;
} else{
digitalWrite(LED, LOW);
if (previousVal != LOW && millis() - revTimer > debounce) {
currentSpeed = (float) (millis() - revTimer)*0.001; // Convert time elapsed to milliseconds to seconds
currentSpeed = rim/currentSpeed; // S = d/t: Rim circumference divided by time elapsed
currentSpeed = currentSpeed*0.002237; // MPH Conversion: 1 mm/s = 0.001 m/s * 3600 s/hr * 1 mile / 1609 m = 0.002237 mi/hr
revTimer = millis(); // Keep a log of the timestamp for each reed switch pulse
cycles++; // The wheel has obviously turned another revolution
sendStats();
serialTimer = millis();
}
previousVal = LOW;
}
if (millis() - serialTimer > 1000) {
sendStats();
serialTimer = millis();
}
}
void sendStats() {
Serial.print("cycles="); Serial.print(cycles);
Serial.print("¤tSpeedx100="); Serial.print((int)currentSpeed*100);
Serial.print(10,BYTE);
}
void decimate(char test[],int dec) {
int i=0;
int length=strlen(test);
char msg[10]="";
strcpy(msg,test);
if (length <= dec) {
for(i=dec;i>(dec-length);i--) msg[i] = msg[i-(dec-length+1)];
for(i=0;i<(dec+1-length);i++) msg[i]='0';
length = strlen(msg);
}
for (i=length;i>(length-dec);i--) msg[i]=msg[i-1];
msg[length-dec]='.';
strcpy(test,msg);
}
Processing:
import processing.opengl.*;
import processing.serial.*;
Serial myPort; // Create object from Serial class
PFont fontA;
String val;
String prev;
int lf = 10; //Linefeed in ASCII
void setup()
{
size(400,400,OPENGL);
hint(ENABLE_OPENGL_4X_SMOOTH);
fontA = loadFont("HelveticaNeue-Bold-48.vlw");
textFont(fontA, 48); // Set the font and its size (in units of pixels)
String portName = Serial.list()[0];
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
myPort = new Serial(this, portName, 9600);
}
void draw()
{
background(255);
if ( myPort.available() > 0) { // If data is available,
val = myPort.readStringUntil(lf); // read it and store it in val
if(val != null) val = trim(val);
}
fill(0); textAlign(CENTER); noStroke();
if(val != null && val != prev)
{
println(val);
prev = val;
}
}
Result:
...
cycles=56¤tSpeedx100=1900
cycles=56¤tSpeedx100=1900
cycles=56¤tSpeedx100=1900
cycles=56¤tSpeedx100=1900
cycles=56¤tSpeedx100=1900
cycles=56¤tSpeedx100=1900