Go Down

Topic: Need help refining...lots of floats & oddities (Read 1 time)previous topic - next topic

NH

Jan 16, 2011, 01:49 am
I have written a sketch for my mobile platform, to determine total distance travelled.  I'll save you the detail on how this is all setup...my main concern is the program/sketch.  I have three questions:

1. Since I have to have very accurate data for this calculation to work, I have lots of "float"ing data.  Any suggestions on a better way?

2. The final function (running total), is returning gibberish...any idea whats wrong?

3. How does this smoothing function (array) look?, any alternative (better) methods?

Thanks in advance! I'm still learning the Arduino, but enjoying every second.

Code: [Select]
`const int analogpinP1 = 1;  // Analog input at pin 1 is "P1", StartPointconst int analogpinP2 = 2;  // Analog input at pin 2 is "P2", FinishPointfloat StartPoint; //start pointfloat FinishPoint; //finish pointfloat factor; //calculation (estimation) factorfloat speed; //estimated speedfloat time; //current time since program started runningfloat elapsedtime; //elapsed time between iterationfloat CurrentDistance; //distance traveled during this iterationfloat TotalDistance; //total distance traveled since program started//all of the following variables are used for smoothing analog input dataint sptotal;int sparray[16];int fptotal;int fparray[16];int i;int count = 0;void setup(){ Serial.begin(9600);   // initialize serial communications at 9600 bps:}void loop(){StartPoint = analogRead(analogpinP1);sparray[count] = StartPoint;count ++;if (count == 16){  count=0;}sptotal = 0;for (i=0; i <=15; i ++){  sptotal = sptotal + sparray[i];}StartPoint = (sptotal/16);FinishPoint = analogRead(analogpinP2);fparray[count] = FinishPoint;count ++;if (count == 16){  count=0;}fptotal = 0;for (i=0; i <=15; i ++){  fptotal = fptotal + fparray[i];}FinishPoint = (fptotal/16);float factor = ((StartPoint+(FinishPoint/3.248+101.486)))/250*1000000;  //need to divide by 1000000, did this to maintain accuracy and not drop off digitsfloat speed =((2.57814*pow((StartPoint/3),.5))*pow(((2*(StartPoint/8.24))/((factor/1000000)*(1-pow((FinishPoint),3)))),2)); // calculate estimated totalelapsedtime = micros() - time; // how long since the last time something was stored in timetime = micros()/1000000;  // store the new value;CurrentDistance = speed * (elapsedtime/1000000)/3600; //distance traveled this iteration TotalDistance = TotalDistance + CurrentDistance; //running total of distance}`

PaulS

#1
Jan 16, 2011, 02:24 am
What is connected to analog pins 1 and 2?

Code: [Select]
`float factor = ((StartPoint+(FinishPoint/3.248+101.486)))/250*1000000;  //need to divide by 1000000, did this to maintain accuracy and not drop off digits`
First divide by 250 then multiply by 1000000. This doesn't make sense. Just multiply by 4000.

If you want floating point arithmetic to be performed, you must use floating point values. 250 and 1000000 are not floating point values.

What do those other magic numbers mean?

Code: [Select]
`time = micros()/1000000;  // store the new value;`
Absent indications to the contrary, constants are treated as ints. 1000000 is not an int value. You need to suffix this value with L or UL.

Code: [Select]
`elapsedtime = micros() - time; // how long since the last time something was stored in timetime = micros()/1000000;  // store the new value;`
micros() returns a value in microseconds. time will have a value in seconds. Subtracting time in seconds from millis()'s value in microseconds is meaningless, like subtracting amps from feet.

Quote
The final function (running total), is returning gibberish...any idea whats wrong?

There are no functions besides setup() and loop() defined, so that makes loop() the final function. How this relates to running total is unclear.

NH

#2
Jan 16, 2011, 05:16 pm
Analog pins 1 and 2 are connected to rotary pots.

I'm not completely familiar with floats, all I (think I) know is that if I need decimal precision, I need to use floating point arithmetic, right?  To make an equation float, does each number need to have a decimal and a certain number of digits behind it?

Those other "magic numbers" are from an equation I derived from sample data.  It all works to create an estimation factor for what I need.  But it only works if several decimal places are stored...the value may be 32.5968294 or something like this.

For the running total, maybe if I fix the micros() error, it will work.

dafid

#3
Jan 16, 2011, 06:12 pm
NH,

The count variable is incremented twice in loop(), so only you are only storing samples every second index in the arrays sparray and fparray.

If you want more precision, delay the /16 until the floating point calculation.

Also, in the floating point calculation make sure all the constants that you would like to be floats, are floats, by putting a '.0' on the end if they are integers.

Also - the average only works properly once you have 16 samples...

I changed your code a bit to fix the above issues
Code: [Select]
`{StartPoint = analogRead(analogpinP1);sparray[count] = StartPoint;// count ++; (after reading FinishPoint//FinishPoint = analogRead(analogpinP2);fparray[count] = FinishPoint;count ++;// the first few times through loop() do not have enough samples to average...if (count != 16)  return ;if (count == 16){  count=0;} sptotal = 0;for (i=0; i <=15; i ++){  sptotal = sptotal + sparray[i];}StartPoint = sptotal; // remember to divide by 16 laterfptotal = 0;for (i=0; i <=15; i ++){  fptotal = fptotal + fparray[i];}FinishPoint = fptotal;float factor = (((StartPoint/16.0)+((FinishPoint/16.0)/3.248+101.486)))/250.0*1000000.0; //need to divide by 1000000, did this to maintain accuracy and not drop off digits`

I don't understand the intent of your code below where you calculate the average, so I can not comment on it at all.

Also, do not worry about combining constants like 250.0*1000000.0 as the compiler does that for you:)

D

Go Up