# Odometer sketch IF problem

I have made a simple Odometer that to simulate speed uses an analog read with a pot.

My timer part of the sketch returns the trip time nicely (TripTime) but when I use that trip time with speed to calculate distance the trip time doesnt seem to be ‘available’ although it serial prints fine.

The sketch has other code that manages the RFID etc. which all work. powerpinState is from the RFID.

I must be missing something in the IF’s?

related variables are;

int MPHour;
int waterSenderPin = A4;
int distanceMiles;
boolean Running = false;
unsigned long StartTime = 0;
unsigned long TripTime = 0;
unsigned long StopTime = 0;
unsigned long currentTime;
void odoMeter ()
{

MPHour = analogRead(waterSenderPin); //test pot to simulate speed//(KMHour/1.60934);test add maths back later

currentTime = (millis() / 1000);
if (! Running && powerpinState == HIGH && MPHour > 700)
{
StartTime = currentTime;
Running = true;
}

if (Running && powerpinState == LOW)
{
TripTime = currentTime - StartTime;
Running = false;
}

if (Running)
{

Serial.print(currentTime - StartTime);
Serial.print ("  Trip time");
Serial.println("");
}
else
{
Serial.print(TripTime);
Serial.print ("  Trip time  ");
Serial.println("");
}

int cormph = (MPHour - 700);// corrected analog read to sim miles
Serial.print(cormph);
Serial.print("  cormph");
Serial.println("");
distanceMiles = (((TripTime)/60)/60)*(MPHour-700);
Serial.print(distanceMiles);
Serial.print("  distanceMiles");
Serial.println("");

}

What in the code tells if You use the trip time alone and when You use it for the calculation going wrong?
One suspect is the speed measurement. A reliable trip time multiplied by speed > bad data....

Sorry, I dont quite understand what you are trying to say.....Could you please give me a bit more info?

You're confident that trip time works well. Okey? Then there is a speed measurement. Are You confident with that? Did You verify it?
You calculat time multiplied by speed and the result is nor what You want.
X times Y gives a bad result. Where is the fault? In X or in Y?

The fault is with trip time.

Within the IF's it serial prints OK but in the speed calc, if I add another serial print before the speed calc then triptime reports a zero. So triptime is somehow getting reset to zero during the If's??

kpg:
The fault is with trip time.

Within the IF's it serial prints OK but in the speed calc, if I add another serial print before the speed calc then triptime reports a zero. So triptime is somehow getting reset to zero during the If's??

No, it’s not TripTime, it’s your calculation here:

distanceMiles = (((TripTime)/60)/60)*(MPHour-700);

What do you think TripTime is divided by 3600 is when it is less than 3600 and it is an integer? It’s zero.

You need to stop dividing millis() by 1000 and you might have chance at make this work.

In general, you need to read up on variable types and understand integer based math. Please don’t just throw floats at this, learn how to make it work with integers.

Oh, and please get rid of the magic number 700. That’s a sure sign you’re attempting to fix problems you don’t understand. Maybe you don’t know the analogy but when you find the hole you’re digging just keeps getting deeper, the solution is to stop digging. Same thing with programming. When it doesn’t work, don’t just try random ideas. You have to understand it before you can fix it.

PS: next time, use control-T before pasting code. And paste the whole program, not fragments. You should know that with 253 posts.

If the pot is at the top end and ADC result was 1023, what would the speed in MPH be?

Thanks for the pointer and yes stupid mistake on the integer maths, result will be zero until triptime is big.

The 700 is just a quick way of getting a usable (but variable) MPH number to play with. The analog input with its resistor bridge and with the pot I had handy hovered around 700 at mid range so the -700 gave me a usable MPH.

If I dont convert Millis to seconds at some point, how do I find distance and if I ideally would like distance in decimal (100.23 etc.), dont I need to use Floats?

I made some simple test code to play with data types to help me fully understand them.

Understanding that Int only works with reasonable small numbers (-32,768 to 32,767) and in my sketch I need to use a division of Millis() to find distance in miles, so need to use bigger numbers, so a float seems logical given I also need decimals?

I also know that if I use floats but the product is an integer then only the integer part is stored .

If I divide a float (MPH) by an Int (the corrected time to hours) and then the product is a float then the decimal value wont be calculated.

So my test code is;

unsigned long time;//. Set as a test number. In my real sketch time = millis()
float  distanceMili;// as this will be a product of millis and speed (MPH) and will be decimal
float MPH = 50;//Set as a test number. Float used to calculate distanceMili and to increase accuracy. I do not need to use the decimal in the value (50.0) for it to be recognised as it is declared as a float here.

void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Time: ");
time = (3600000ul);//simulation of millis() time and equals 1 hour in this case. The number 3600000 needs to be declared as an long as far as I can see for the maths to work? (it is too big as an Int). I wouldn't normally use a ul as millis() already returns a ul in the real sketch.
distanceMili = (MPH*(time / 3600000.00));//3600000 converts time to hours and must be made a float for the maths to work (by adding .00), then multiplies by MPH (which is a float), with the product being a float. If I had left 36000000 as a ul then the division with time would be a ul also and I would not get the decimal result.

Serial.println(distanceMili,2);//print to 2 decimal places

delay(1000);          // wait a second so as not to send massive amounts of data
}

Have I understood all this? It seems to work…

You can use unsigned int, 0 - 65535, but using millis, go for unsigned long. Float is no good, only gives 5 digit precision. Leave it for the final display maybe.

But if i set all variables to unsigned long how will the calculation of miles have the decimal accuracy I need?

If I just cast the answer at the end, will I get the decimal accuracy back?

Looks like I am getting there with the knowledge but still have holes..... Thanks for the help

Just ran a test on the range of a float.It counted up to 16777216! Sorry for my totaly wrong reply in #9. Where did that figure come from?

So as in my post #10. If I dont use floats, how can I get the decimal accuracy I need and how do I later convert to a float to display?

JCA34F:
If the pot is at the top end and ADC result was 1023, what would the speed in MPH be?

float endresult = 1.0 * ulong1 / ulong2;
display( endresult );