Pages: [1]   Go Down
Author Topic: Smoothing Analog values (different numReadings)  (Read 2000 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody,

most of you dealing with analog sensor know the problem of jittering values.
There is this nice example in the standard arduino library called "Smoothing" (Examples>Analog).
See down
I would like to choose different Smoothing strenght in my code (with buttons).
All I want to do is to change the numReadings... but as const int
its read-only! and not changeable in later code...
Has anybody an idea ? I am really new to programming.
Help would be great

Best
Nico


Code:
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

void setup()
{
  // initialize serial communication with computer:
  Serial.begin(9600);                   
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;         
}

void loop() {
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor: 
  readings[index] = analogRead(inputPin);
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array: 
  index = index + 1;                   

  // if we're at the end of the array...
  if (index >= numReadings)             
    // ...wrap around to the beginning:
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer as ASCII digits
  Serial.println(average);   
  delay(1);        // delay in between reads for stability           
}



Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1260
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Simply remove the 'const' to make it a variable.

Code:
int numReadings = 10;
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

would be nice, but then I got this error
"array bound is not an integer constant"


int readings[numReadings];      // the readings from the analog input
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1. What are you reading from? Unless the device itself produces a jittery result (e.g. acceleration sensor), jittery readings can be caused by noise pickup or ground wire current, both of which you can do something about.

2. Try:

Code:
const int maxReadings = 20;
int readings[maxReadings];
int numReadings = 10;    //  must always be between 1 and maxReadings inclusive

Rest of code as in original.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks a lot for your answers.

I am reading from IR sensor. I know some people talking about capacity elements wich avoid this noise. but first I wanted to give the software solution a try.


with the code from dc42 I now can change numReadings. which is great. thanks alot.

but somehow changing different numReadings ( button 1= numReadings = 10 or button 2 numReadings = 100)
causes strange behaviour. the minimum value of the sensor readout seems now affected by the last value of Reading...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

maybe this describes better:

if the state is button=2 (numReadings = 100)and sensor value is 50% of the maximal output value (caused by my hand)

I can not get under the level of 50% when switching to button=2

understand ?
Logged

Montreal
Online Online
Faraday Member
**
Karma: 27
Posts: 2569
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There was no buttons in your original code, can you re-post your code with all mods?
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 219
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

for smoothing i often use code like this

Code:
void loop(){
a = inputPin(A0);
average = ( average * 9 + a ) /10     // it requires a few loops for average to get near "a"
// your stuff here...
}
you could use other numbers (as 9 and 10) too here, this construction will always average lag behind a, which is kind of nice; if the data contains a lot of statistical spikes use for example 29 and 30  / if there only a few spikes and you want faster response use 4 and 5
Typical for this construction is that on startup and average still is zero, the function climbs to "a".
I know there are other math constructions, but its small and fast computer code.
instead of *9 one might do *8 or even faster do bitshifts to get *8 (2^3 == thats 3 bitshifts left) and then do only one 'complex' division command.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

there are plus/minus buttons changeing for states

Code:

switch (remainder+1) {
  
  case 1:
  numReadings = 1;
  break;

  case 2:
  numReadings = 40;
  break;
  
  case 3:
  numReadings = 40;
  break;
  
  case 4:
  numReadings = 100;
  break;
}  


nothing special so far, just choosing a specified numReading via buttons




Logged

Montreal
Online Online
Faraday Member
**
Karma: 27
Posts: 2569
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
instead of *9 one might do *8 or even faster do bitshifts to get *8 (2^3 == thats 3 bitshifts left) and then do only one 'complex' division command.
Division is much slower, than multiplication. So to optimize speed, better instead of *9, do *7 , add new value, than shift right >>3 replacing slow division by 8.  Or *15, sum, >>4.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Code supplied ba PGTBOOS was straight forward..

elegant and easy way, so I got it to work

(maybe this code has more latency? or?, there must be a reason why they put this more complicated code in the examples smiley-wink )


Thanks all you guys. This forum is ***** helpful


Logged

USA
Offline Offline
Sr. Member
****
Karma: 13
Posts: 360
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's what I see about your original code:

If you used this declaration for your array of readings -
Code:
const int maxReadings = 20;
int readings[maxReadings];
then the compiler has set aside 20 integer-sized memory locations for the array.  If you later execute this -
Code:
  numReadings = 100;
- then your program will read from, and write to, 100 locations, 80 of which aren't reserved for the array, and many of which may be in use for storing something else.  We don't know what variables use those locations, but they might be index, total, or average, in which case you'd be writing analog readings to those variables.  I'm not surprised that you got unexpected results.

If you want the maximum number of readings to be as high as 100, under program control, then you'll need to declare your array of readings to have space for 100 values.  Otherwise, chaos ensues.
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

maybe this describes better:

if the state is button=2 (numReadings = 100)and sensor value is 50% of the maximal output value (caused by my hand)

I can not get under the level of 50% when switching to button=2

understand ?

You need to change the type of 'total' from 'int' to 'long', otherwise it may overflow when the analog reading is near its maximum value of 1023 and numReadings is greater than 32.

Also, when changing numReadings, you need to adjust 'total'. Multiply it by the new numReadings and divide it by the old numReadings. Again, this may overflow unless you change its type to long.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Pages: [1]   Go Up
Jump to: