Pages: [1]   Go Down
Author Topic: Need help refining...lots of floats & oddities  (Read 792 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
const int analogpinP1 = 1;  // Analog input at pin 1 is "P1", StartPoint
const int analogpinP2 = 2;  // Analog input at pin 2 is "P2", FinishPoint

float StartPoint; //start point
float FinishPoint; //finish point
float factor; //calculation (estimation) factor
float speed; //estimated speed
float time; //current time since program started running
float elapsedtime; //elapsed time between iteration
float CurrentDistance; //distance traveled during this iteration
float TotalDistance; //total distance traveled since program started

//all of the following variables are used for smoothing analog input data
int 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 digits
float speed =((2.57814*pow((StartPoint/3),.5))*pow(((2*(StartPoint/8.24))/((factor/1000000)*(1-pow((FinishPoint),3)))),2)); // calculate estimated total

elapsedtime = micros() - time; // how long since the last time something was stored in time
time = micros()/1000000;  // store the new value;

CurrentDistance = speed * (elapsedtime/1000000)/3600; //distance traveled this iteration
TotalDistance = TotalDistance + CurrentDistance; //running total of distance
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What is connected to analog pins 1 and 2?

Code:
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:
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:
elapsedtime = micros() - time; // how long since the last time something was stored in time
time = 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.

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 14
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

UK
Offline Offline
Full Member
***
Karma: 2
Posts: 110
Kittens eat Arduinos
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
{
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 later

fptotal = 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
Logged

Pages: [1]   Go Up
Jump to: