smoothing analog sensor

Hi,

I'm new to Arduino and trying to smooth some analog accelerometer data but receive only strange data in Processing. Any suggestions?

#define NUMREADINGS 10
int xVal, yVal, zVal = 0;
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

//analog pins from accelerometer
int xPin = 0;
int yPin = 1;
int zPin = 2;

byte inByte;

void setup() {
Serial.begin(9600);
establishContact();
for (int i = 0; i < NUMREADINGS; i++)
readings = 0; // initialize all the readings to 0
}
void loop()
{

  • // if we get a valid byte, read analog ins:*
  • if (Serial.available() > 0) {*
  • // get incoming byte:*
  • inByte = Serial.read();*
  • xVal = analogRead(xPin);*
  • yVal = analogRead(yPin);*
  • zVal = analogRead(zPin);*
  • Serial.print(xVal, BYTE);*
  • Serial.print(yVal, BYTE);*
  • Serial.print(zVal, BYTE);*
  • total -= readings[index]; // subtract the last reading*
  • readings[index] = analogRead(xPin); // read from the sensor*
  • readings[index] = analogRead(yPin);*
  • readings[index] = analogRead(zPin);*
  • total += readings[index]; // add the reading to the total*
  • index = (index + 1); // advance to the next index*
  • if (index >= NUMREADINGS) // if we're at the end of the array...*
  • index = 0; // ...wrap around to the beginning*
  • average = total / NUMREADINGS; // calculate the average*
  • Serial.println(average); // send it to the computer (as ASCII digits) *
  • }*
    }
    void establishContact() {
  • while (Serial.available() <= 0) {*
  • Serial.print('A', BYTE); // send a capital A*
  • delay(500);*
  • }*
    }
    [/quote]

I'm not sure what you are trying to do exactly, but there are a couple of things around this part of the code:

xVal = analogRead(xPin); 
yVal = analogRead(yPin); 
zVal = analogRead(zPin); 

Serial.print(xVal, BYTE); 
Serial.print(yVal, BYTE); 
Serial.print(zVal, BYTE); 
total -= readings[index];             // subtract the last reading 
readings[index] = analogRead(xPin);      // read from the sensor 
readings[index] = analogRead(yPin); 
readings[index] = analogRead(zPin);
  1. Why do you read the analog pins, send the data then read the pins again?

  2. You seem to be adding all the x, y and z reading together into the reading[] array. Should you be using 3 different arrays? (or a 2 dimensional array).

Regards,

Mike

Yes, it's a little strange. You're writing the ADC values to the same array location, so only the last one is stored. Definitely fix this with separate arrays and averaging variables, or two-dimensional arrays.

Doing a round-robin sampling approach like this works quite well, I've done it before in situations I wanted some sample averaging, but faster response to changes in input.

Couple other things to check. This approach requires either an ADC input signal centered near VCC/2, or signed variable types, since you will run into situations where the new value is larger than the current total. You've got signed variables, but does the Serial.println correctly print a negative integer? Can't say I've tried it, so I don't know.

More: you're trying to send ADC readings as BYTE types. Right in the Serial.println portion of the manual, it shows you have to divide by 4 since an ADC reading can exceed the value of a BYTE. Also, instead of doing another reading to assign values to your array, you could use the xVal etc that you just read.