Hey everyone.
I'm programming a bike computer.. most of the snags i'm hitting i'm able to figure out, but this one has me particularly stumped.
In calculating the distance traveled, I divide the total number of mm counted by the number of mm in a mile, then need to output the floating point calculation to a serial display.
I'm trying to use the suggestion i saw somewhere else to change the whole number from the float to a long, then change the decimal to a long and multiply by 100 to get the precision, then print the text. However, I'm running into an issue.
When I dump the output from the multiplication, instead of multiplying dist2 times 100, it's squaring dist2. This happens when dist2 is a long/unsigned long. If it's an int, the calculation works fine. If dist2 is defined prior to the calculation with a single number, it works fine. It doesn't work when calculated out after setting it with the prior equation.
I've talked to some people on IRC about this, but we haven't been able to come up with a reason why it's doing this. They've compiled the offending code into C on a computer and it works fine, but the Arduino doesn't seem to be doing the work properly.
Here's the code, if anyone would like to actively discuss it I'm on AIM most of the time as Chorca1, a bit faster to test code and such that way. The offending calculation is " dist2 = (unsigned long)((unsigned long)dist2 * (unsigned long)(100));" in the display() function.
//Tire circumference in millimeters
const unsigned long circ = 2095;
const byte SensorPin = 2; //Input pin for speed sensor
unsigned long time; //last time sensor was tripped
unsigned int milsecs; //this will overflow after 64 seconds or so between hits, but that doesn't matter, only need it for sub-second timings
unsigned long time2; //time before last sensor was tripped
unsigned int count; //number of revs
unsigned long total; //total mm
float mph = 0.0; //calculated mph
unsigned int avg[4]; //array for averaging speed
unsigned int outspeed; //speed output to screen
volatile boolean state = false; //check for if sensor has been tripped
float miles = 0;
unsigned long dist1;
unsigned long dist2;
void setup()
{
pinMode (SensorPin,INPUT); //enable input sensor
digitalWrite (SensorPin, HIGH); //turn on pull up resistor
/*
Serial.begin(9600); //Code for setting LCD to 38400 baud. LCD stores speed in EEPROM, so reconfig shouldn't be necessary.
Serial.print(124, BYTE);
Serial.print(16, BYTE);
delay(500);
*/
Serial.begin(38400);
Serial.print(0xFE, BYTE); //Command byte
Serial.print(0x01, BYTE); //Clear screen
attachInterrupt(0,sense,LOW);
}
void loop()
{
if(state == true && (millis() - time) > 40) //check if the thing's been tripped, and also debounce the input (40ms = approx 250mph).
{
time = millis(); //set the time the interrupt occured
count = count + 1; //update the count number
display(); //run the display routine to throw stuff up onto the screen
}
if(state == true) //if it's still true...
{
state = false; //falsify state
}
}
//----------------------------------------------------------------------------
void display()
{
milsecs = time - time2; //calculate the difference between the current time and the last time it was tripped
time2 = time; //reset the tripped time
total = (total + circ); //add the circumference to the current total..
mph = (circ / milsecs) * 2.2369; //calculate the speed
//miles = (total / 1609344);
dist1 = (unsigned long)(total / 16093);
dist2 = (unsigned long)(total / 16093);
dist2 = (unsigned long)((unsigned long)dist2 * (unsigned long)(100));
avg[0] = avg[1]; //shift storage array
avg[1] = avg[2]; // "
avg[2] = avg[3]; // "
avg[3] = int(mph); //insert current calculated mph
outspeed = ((avg[0] + avg[1] + avg[2] + avg[3]) / 4); //average the speed over the last four readings (mean)
Serial.print(0xFE, BYTE); //Command byte
Serial.print(0x01, BYTE); //Clear screen
Serial.print("Dist: "); //Show time
//Serial.print(total); // "
Serial.print(dist1);
Serial.print(".");
Serial.print(dist2);
Serial.print(0xFE, BYTE); //Command byte
Serial.print(192, BYTE); //Move to 2nd line
//Serial.print("MPH: "); //Show speed
//Serial.print(outspeed); // "
Serial.print(total);
}
//----------------------------------------------------------------------------
void sense()
{
state = true;
}