Go Down

Topic: software low pass filter debug help (Read 836 times) previous topic - next topic

Dec 09, 2012, 06:45 pm Last Edit: Dec 09, 2012, 07:09 pm by waspinator Reason: 1
Hi,

I'm trying to add a software low pass filter to a noisy sensor to make the output smoother. I think I have the idea right and it compiles and uploads fine, but my arduino seems to crash when I run it; no serial output when if I call the lowPassFilter function. I'm used to seeing run time errors when I usually program, and now that I don't I'm stuck figuring out my error. Is there any way to simulate run time somehow to figure out errors? Or do I need a hardware debugger? I'm new to arduino so I'm just using the standard arduino IDE. It's not very feature rich in terms of auto completion or built in documentation. Should I be using something else?

here is my code:

Code: [Select]


float data[10];

void setup(){
  Serial.begin(9600);

  // initialize array
  for (int i = 0; i < sizeof(data); i++){
    data[i] = 0.0; 
  }
}

void loop(){
  float current_value = readData();
  float filtered_value = lowPassFilter(current_value, data);

  Serial.print("Value = ");
  Serial.println(filtered_value);
}

float lowPassFilter(float new_data, float *data_array){
 
  float filtered_value = 0;
  float data_array_sum = 0;
 
  // remove oldest data in array (first index) and shift all other indexes to the left
  for (int i = 0; i < sizeof(data_array); i++)
    data_array[i] = data_array[i + 1];
 
  // add new data to array (last index)
  data_array[sizeof(data_array) - 1] = new_data;
 
  // get average value from the data array
  for (int i = 0; i < sizeof(data_array); i++){
    data_array_sum += data_array[i];
  }
  filtered_value = data_array_sum / sizeof(data_array);
 
  return filtered_value;
}



Any ideas of what my problem could be or how I could figure it out without a hardware debugger?

Thanks


KeithRB

I am not sure where current_data[] in setup came from.

You loop through every element when getting rid of the old one, but you access data[i+1] which might access an element past the end of the array.

It might be better to use something like avg_val = avg_val* (1-avg_factor)/avg_factor + new_val/avg_factor

#2
Dec 09, 2012, 07:06 pm Last Edit: Dec 09, 2012, 08:02 pm by waspinator Reason: 1
sorry that should have been just `data[]`.

hmm, so maybe my for loop should look like this:

Code: [Select]


  for (int i = 0; i < sizeof(data_array) - 1; i++)
    data_array[i] = data_array[i + 1];



edit: ok it runs now, but for some reason my array seems to be only of size 2, but when I print out sizeof(data) it is 40? And I thought I set it to 10...

pekkaa

Sizeof returns the size of the array in bytes, not the number of elements.

oh I see. Hmm I guess I'll just define the size of the array. I wish arduino had more libraries built in. Thanks.

Nick Gammon

Code: [Select]

// initialize array
  for (int i = 0; i < sizeof(data); i++){
    data[i] = 0.0; 


Quote
Sizeof returns the size of the array in bytes, not the number of elements.



However you can convert that to the number of elements:

Code: [Select]

// number of items in an array
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))


Now:

Code: [Select]

// initialize array
  for (int i = 0; i < NUMITEMS(data); i++){
    data[i] = 0.0; 

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy