Go Down

Topic: Arduino Capabilities - Lengthy equations? (Read 1 time) previous topic - next topic

NH

I wondering if the Arduino platform is capable of what I need, I think it is, but I want to check.

I need to take 3 inputs from sensors, put them through a rather long equation, then multiply by time, and arrive at a final value.  Is the Arduino capable of processing a long equation, over and over again, to display a value?  

When I say "long equation", I mean something like this (or longer):
((((X/Y+Z)^2)/((M+N/P)^3))^(1/2)+((5-G/H)/(B*H))^2)/(1-(X+Y)/Z)+(1425+R/M*C*A)^2/(((B*C*100/D)*2)^(1/2)))*T

Thanks (I'm still new to this, so please excuse my ignorance)

cubemike99

#1
Jan 04, 2011, 12:37 am Last Edit: Jan 04, 2011, 12:38 am by cubemike99 Reason: 1
Hey there. As far as I know, it should be fine. What you will have to make sure of though, is to use the right data type. For example, an unsigned int takes relatively little memory to store, but it also only has a range of 0 to about 32000. A float, on the other hand is between 3.4028235E+38 and -3.4028235E+38 and has 6-7 digits of resolution, including decimals but uses significantly more room.

What you also might encounter is a pause or slowdown in your code due to the intensive math you have to do. So if you are sampling data only, say, once every 30 min, you should be fine.

In conclusion, a dog can dig, but a backhoe is much faster. The Arduino will do it, but thats not to say it wont break a sweat.


retrolefty

#2
Jan 04, 2011, 12:45 am Last Edit: Jan 04, 2011, 12:47 am by retrolefty Reason: 1
You also have to try and avoid mixing of data types in the formula. I see lots of constant numbers being used and I believe these will default to 16 bit integer types. Also things like ^(1/2) will not give the results you would expect unless first changed to floats ^(1.0/2.0)

Anyway I'm sure it can be accomplished but lots of bear traps both large and small lie ahead for you I think.  ;)

Lefty

NH

Cool, thats good news.

Now, how fast do you think it could process this equation?  You mentioned once every 30 min is reasonable, but I'm looking for much faster.  Is once a second reasonable?  

retrolefty

#4
Jan 04, 2011, 12:48 am Last Edit: Jan 04, 2011, 12:49 am by retrolefty Reason: 1
Quote
Is once a second reasonable?


I would guess yes, a 8 bit processor running at 16mhz is not fast by todays standards, but it's not a mechanical adding machine.  ;)

cubemike99

#5
Jan 04, 2011, 01:11 am Last Edit: Jan 04, 2011, 01:11 am by cubemike99 Reason: 1
By the way, mind telling us what you're working on?  ;D

NH

Thanks a lot for the replies so far, this is looking like it may work...

I'm trying to take a couple pressure measurements and a potentiometer measurement in, then put these results through a "long equation" to get a result, which is an estimate of the next potentiometer position.  I think I can learn the basics of this code, but before I get in over my head, I want to make sure I'm on the right track.   Will the following code take in the 3 inputs, then display each input, along with the calculated "result", and the time (in milliseconds) that has gone by between each loop?

const int analogpinP1 = 1;  // Analog input at pin 1 is "P1"
const int analogpinP2 = 2;  // Analog input at pin 2 is "P2"
const int analogpinP3 = 3;  // Analog input at pin 3 is "P3"

void setup()
{
 Serial.begin(9600);   // initialize serial communications at 9600 bps:
}

void loop()
{
 int adcvalue1 = analogRead(analogpinP1);    // read the analog in value for P1:
 Serial.print("sensor P1 = " );
 Serial.print(adcvalue1);    // print the adc value to the serial monitor:
 long pressure1 = 950 + adcvalue1 / 8.5;  //convert it to milli bars
 Serial.print("\t pressure1 = ");
 Serial.print(pressure1);   // print the pressure
 Serial.println(" mb");
 
 int adcvalue2 = analogRead(analogpinP2);    // read the analog in value for P2:
 Serial.print("sensor P2 = " );
 Serial.print(adcvalue2);    // print the adc value to the serial monitor:
 long pressure2 = 950 + adcvalue2 / 8.5;  //convert it to milli bars
 Serial.print("\t pressure2 = ");
 Serial.print(pressure2);   // print the pressure
 Serial.println(" mb");      
 
 int adcvalue3 = analogRead(analogpinP3);    // read the analog in value for P3:
 Serial.print("sensor P3 = " );
 Serial.print(adcvalue3);    // print the adc value to the serial monitor:
 long position = 950 + adcvalue3 / 8.5;  //convert it to milli bars
 Serial.print("\t position = ");
 Serial.print(position);   // print the pressure
 Serial.println(" in");
 
 long result = ((pressure1 + pressure2)^(1.0/2.0))/(position^2);   // calculate result
 Serial.print("\t result = ");
 Serial.print(result);       // print result
 Serial.print(" estimated);

 Serial.println(millis(), DEC);

 delay(100);        
}



PaulS

Code: [Select]
long pressure1 = 950 + adcvalue1 / 8.5;  //convert it to milli bars
This will perform floating point arithmetic. That could be avoided by multiplying adcvalue1 by 2 and dividing by 17.

Code: [Select]
long result = ((pressure1 + pressure2)^(1.0/2.0))/(position^2);   // calculate result
The ^0.5 operation should be replaced by the sqrt() function. The position^2 operation should be replaced by position*position.

The delay() function call is in direction opposition to the "need for speed" expressed earlier.

Go Up