Pages: 1 [2]   Go Down
Author Topic: Suggestions for lowering accelerometer noise  (Read 6906 times)
0 Members and 1 Guest are viewing this topic.
Georgina Ontario
Offline Offline
Sr. Member
****
Karma: 5
Posts: 437
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is my setup routine...

NOTE: The sample skipping... That gives a pretty dramatic noise reduction...

I have found modes 1 & 2 to be useless in some respects as they offset X-Y -- I forget which does which... So it's noisy mode Zero (0) or Somewhat OK Mode three (3) that doesn't muck up too much...

I also believe that the ISR on Pin2 might be interfering with something else -- can't figure out what though... It is now on Pin 3 Interrupt (ISR 1)... Maybe it is simply that I was driving it with 3.3 V... I need to hook up another level converter I guess...

I will probably stick with 1.5G and possibly 1G for my work.

This used the library by Jurgen...  (Jayduino?)

Code:
// Best seetings F15HZ0 and Mode 3
// Also F300HZ and Mode 2

/* Filter settings
   F10HZ=0,F20HZ=1,F75HZ,F15HZ0,F300HZ,F600HZ,F1200HZ,HPPLUS1,BP300}FILTER;

*/
  bma180.setFilter(bma180.F300HZ);
  /* G Sensitivity
      G1=0,1.G15=1,G2,G3,G4,G8,G16  ... enumerated type, 1, 1.5,2,3,4,8,16 g settings
  */
  bma180.setGSensitivity(bma180.G15); // lets put 1.5 G maximum, not doing tests in a space shuttle
  //setRegValue(int regAdr, int val, int maskPreserve)
/*  MODE  -- for 1, 1.5 and 2g
    0x00=LowNoise,       BW=1200 Noise 150 ug/rt
    0x01 Ultra Low Noise BW=472  Noise 150 ug/rt
    0x02 Low Noise Low Power BW= 236  Samp/Sec =1200 Noise 200 ug/rt
    0X03 Low Power       BW=600                      Noise 200 ug/rt
    Must see Page 28 section 7.7.3 for full info
*/
  bma180.setRegValue(0x30,0x03,0xFC);
 
  // digital pin 3= ISR1  ---  ISR 0 = Dig Pin 2  ISR0 gave problems????
  attachInterrupt(1, BMAISR, RISING);
  // +++++++++++++++++++++++++++++++  -- note this

  // sample skipping reduces noise sonsiderably... not sure of count...
  bma180.setSMPSkip(); // allow sample skipping to reduce load...

  bma180.setISRMode(); // allow interrupt on (connect to Dig. Pin 3)


  bma180.disableWrite(); //parametrs are set so disallow further changes
  delay(2000);  //just a wait till thinggs settle and readings stabilize...


// End BMA180 Setup +++++++++++++++++++

 Serial.println("Starting...");
 SendPackets = false;
 flipflop = 0;

} //end setup

// End Setup
//*****************************************


Have fun...
Logged

Just another Hacker

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

I have found modes 1 & 2 to be useless in some respects as they offset X-Y

I had to recalibrate the sensor to use mode 1.  I found that you can modify the offset registers, and I used a level to find the right values. I got it so that the given axis should be perpendicular to the gravity, and so that axis should be 0.  I noted the offset from zero to figure what to add to the registers.  Unfortunately, I never quite figured out how to permanently write those values to the EEPROM registers. So if there is ever a short that causes the BMA180 to reset, the default values come back.

Even the other modes can need recalibration depending on what you put on the circuit, but the recalibration is not as significant for mode 0 and 3.
Logged

Georgina Ontario
Offline Offline
Sr. Member
****
Karma: 5
Posts: 437
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have found modes 1 & 2 to be useless in some respects as they offset X-Y

I had to recalibrate the sensor to use mode 1.  I found that you can modify the offset registers, and I used a level to find the right values. I got it so that the given axis should be perpendicular to the gravity, and so that axis should be 0.  I noted the offset from zero to figure what to add to the registers.  Unfortunately, I never quite figured out how to permanently write those values to the EEPROM registers. So if there is ever a short that causes the BMA180 to reset, the default values come back.

Even the other modes can need recalibration depending on what you put on the circuit, but the recalibration is not as significant for mode 0 and 3.

This might be a good reason to store the values in the Arduino EEPROM....

If the sensor chips had UUID's it would even be possible to pick the right one through lookup... (Like the DALLAS Temp Chips.)
Logged

Just another Hacker

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

This might be a good reason to store the values in the Arduino EEPROM....

It is stored in the Arduino EEPROM. I'm talking about the BMA180 EEPROM. The documentation suggests that it can be written to, I just haven't figured it out. It talks about the low level details about how it works, but there aren't specific steps or an example included.
Logged

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

I made a discovery. I found out that this BMA180 accelerometer works differently from the ADXL345. The vibration bandwidth frequency really is decoupled from the sampling frequency. So even though I want to measure frequencies in the 0.001–50 Hz range (0.1-10 Hz for the stronger ground motion), I can sample at 200 samples per second. The ADXL345 would flatline between two samples when the bandwidth went below the sampling frequency.  The BMA180 actually gives a nice slope. So I set the bandwidth filter to 40Hz and sample at 200sps. This cut the noise floor in half again. smiley

BTW the bandwidth filters 0x8 and 0x9 are quite interesting. They cancel out gravity, which would seem quite helpful in other usage scenarios. They have an interesting fading effect on the tricolor LED I'm using. I guess gravity has a frequency of 0Hz because it's normally constant. It's unfortunate that the documentation doesn't advertise the purpose of those modes. smiley-sad
Logged

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

Hello.
I'm just reading your interesting topic about BMA180. I'm using PROPELLER instead of ARDUINO, so I'm quit off this forum, but you're the only ones with BMA180 experience I have found so far. BOSCH datasheet sucks!!! Nothing concrete about calibration, ...

I have quite a problem with my project and reading BMA180 acc values. When I read acc values, LSB values are fluctating from 0 to 255 without order - sensor is still. I don't understand what is going on, because I can read MSB regs with no problem (no fluctation) - values corresponding to slope of sensor.

I didn't change any register, they're still factory defaults.

Can anyone give me an advice how can I fix this?

I'm quite deperate here.

Thank you all

- Sorry for my English - I tried really hard smiley
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26302
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the bandwidth filters 0x8 and 0x9 are quite interesting. They cancel out gravity,

Better make sure your board is tied down!
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

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

I'm using PROPELLER instead of ARDUINO, so I'm quit off this forum, but you're the only ones with BMA180 experience I have found so far. BOSCH datasheet sucks!!! Nothing concrete about calibration, ...

I have quite a problem with my project and reading BMA180 acc values. When I read acc values, LSB values are fluctating from 0 to 255 without order - sensor is still. I don't understand what is going on, because I can read MSB regs with no problem (no fluctation) - values corresponding to slope of sensor.

It depends on what kind of fluctuation you have.  Maybe you have a loose connection. I know that the SparkFun logic level converter increases the noise level and that noise looks different.  Some fluctuation is expected, but the amplitude of the fluctuation should be in the range of 60-70 when still. The rest of this discussion was on how to reduce it further.  Of course this is on a sturdy floor with no fan vibration from my computer.  A stable voltage supply is also important.

Just a reminder, the MSB (Most Significant Byte) and LSB (Least Significant Byte) are not suppose to be interpreted individually. They are suppose to be combined to form a 2 byte signed integer. The code on my web site provides an example on reading the sensor, and it may help you too.

Your issue is off topic from this thread and forum, and it shouldn't be continued here. If you want to discuss this topic further, please contact me through my web site (see the bottom of the page).  I'll see if I can help you further from there.  http://www.centralnexus.com/seismograph/
Logged

Italy
Offline Offline
Full Member
***
Karma: 3
Posts: 142
jayduino rox
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have quite a problem with my project and reading BMA180 acc values. When I read acc values, LSB values are fluctating from 0 to 255 without order - sensor is still. I don't understand what is going on, because I can read MSB regs with no problem (no fluctation) - values corresponding to slope of sensor.

This should happen if you read the status bit. And as (actually the datasheet is quite good, compared to some chinese ones smiley-eek-blue ) stated in the datasheet you get into having shadowing problems of register values. The procedure of reading is very important to get consistent readings and the best way of action is to use the interrupt mode.

Some code for reading (don't check the status bit)
Code:
  Wire.beginTransmission(address);
  Wire.send(0x02);
  Wire.endTransmission();
  Wire.requestFrom((int)address, 6);
  if(Wire.available()==6)
  {
    int lsb = Wire.receive()>>2;
    int msb = Wire.receive();
    x=(msb<<6)+lsb;
    if (x&0x2000) x|=0xc000; // set full 2 complement for neg values
    lsb = Wire.receive()>>2;
    msb = Wire.receive();
    y=(msb<<6)+lsb;
    if (y&0x2000) y|=0xc000;
    lsb = Wire.receive()>>2;
    msb = Wire.receive();
    z=(msb<<6)+lsb;
    if (z&0x2000) z|=0xc000;
  }

if (you got questions) {ask();}
« Last Edit: March 18, 2011, 05:18:00 am by scjurgen » Logged

Juergen

Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

- just for reference:

datasheet, page 27: the bw (bandwidth modes) 8 & 9 are a highpass and bandpass filter - that is why they "cut out" the constant earth gravitational force as long as the sensor is not moved. The 0Hz component is simply not recorded.

datasheet, page 29: "The sensor is calibrated for mode_config = '00'. By changing to other modes, the offset is changed too, thus subsequently an offset correction has to be performed."

datasheet, page 52: "Noise perturbations due to serial interface noise [traffic on the I2C lines] should be avoided. This is especially true when many slave ICs are connected on the same serial data and clock pins. ... Thus, to be able to achieve low noise level, no activity on SCK SDI and SDO should occur excepted to read out acceleration like explained on above chapter." - which probably refers to the interrupt synced readout procedure describe on the page before, p. 51. This echos the suggestion of scjurgen above... smiley-wink

... and some words of caution:

datasheet, page 26: "In the case of the BMA180 the specified number of write cycles is 1000." This is a rather low value, so you should probably not write too often to the EEPROM....

datasheet, page 42: "Attention: Customer is able to recalibrate sensitivity. If this is done including EEPROM writing, the initial calibration values are lost...." - if that happens, you will get readings, but the values might no longer correspond to a specific g-value. So be careful just where you write if you write into the EEPROM, or backup these values by reading them out before doing anything with the EEPROM.


« Last Edit: March 19, 2011, 05:47:56 am by cpixip » Logged

Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello ! I am resurrecting this very helpful topic in order to try to summarize some things and ask for further help smiley

I am currently working on an acceleration logger project for earthquake events using the very good BMA180 sensor, and I am trying to find ways to minimize the inherent noise as much as possible.

From what I read both on this forum and the (well, not very detailed) datasheet, I came up to the following options for logging data :

1) using a timer interrupt on the Arduino, where you explicitly specify the sampling rate (e.g. 100 Hz), irrespective of the selected BMA180 bandwidth (thanks to DiamondSky).
2) using sample skipping in BMA180, in order to set the new_data_int interrupt to be synchronized with the 2x selected bandwidth (e.g. if 75 Hz is selected, interrupt will fire at 150 Hz). Afterwards, you attach this external interrupt to Arduino.

I am assuming that the second way is better because it does not introduce synchronization problems which increase sensor noise (the datasheet says so). What do you think ?

My questions are :

1) is there any way to cancel the mechanical behavior of the sensor and just read (and evaluate) the zero-g noise from the output (maybe with the self-checking capability) ?
2) did anybody try the self-calibration procedure for this sensor ? does it improve things with respect to noise, or just zeroes the idle-state acceleration components ?

Thanks a lot in advance for helping me smiley smiley
Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12179
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't understand this thread, MEMS accelerometers are nowhere near sensitive enough to make a seismometer.  Seismometer's can detect down to 0.0000000003 m/s^2, MEMS accelerometers perhaps to 0.01 m/s^2

[ Even a loudspeaker coil with code removed and added mass would far-farr exceed the sensitivity of a MEMS device ]
« Last Edit: June 22, 2012, 05:21:30 pm by MarkT » Logged

[ I won't respond to messages, use the forum please ]

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

I don't understand this thread, MEMS accelerometers are nowhere near sensitive enough to make a seismometer.  Seismometer's can detect down to 0.0000000003 m/s^2, MEMS accelerometers perhaps to 0.01 m/s^2

[ Even a loudspeaker coil with code removed and added mass would far-farr exceed the sensitivity of a MEMS device ]

Personally I only care about the earthquakes I can feel. I really don't care about microquakes, nor that something heavy was dropped on the ground near my house.  I don't want to spend thousands of dollars for a professional version, nor the price of the research variety where the gravity sensitivity can sense the moon and sun.  The Arduino's analog sensitivity (acceleration per bit) is far lower than these accelerometers.  These accelerometers are the right answer for the price, size and level of complexity I desire.

The USGS variety of MEMS based seismometers are much more sensitive to acceleration, but they're much more expensive.

In any case...

1) is there any way to cancel the mechanical behavior of the sensor and just read (and evaluate) the zero-g noise from the output (maybe with the self-checking capability) ?
2) did anybody try the self-calibration procedure for this sensor ? does it improve things with respect to noise, or just zeroes the idle-state acceleration components ?

I have not tried it, but I believe the self-calibration is used more for centering the values.  So a 180 degree turn of an axis will result in the same magnitude, but that axis will have the opposite negative sign.  This can be important when calculating the magnitude of the acceleration in order to cancel out the acceleration from gravity.  I only did manual calibration.  Without calibration, you get asymmetric acceleration magnitudes.

One of the problems with canceling out the gravity is that you don't get an isolated gravity vector. You get a cumulative acceleration value that includes the earthquake motion and the gravity. Some earthquakes do shift foundations.  Water unevenly seeping under a foundation can change the angle of the floor.  The temperature of the sensor can also affect the values, but the BMA180 can compensate for most of that temperature issue.  So the absolute values will drift after a while.

Other things that people have considered with getting more accurate results include the following:

  • Add multiple accelerometers, and average the results. This allows isolation of internal noise of a specific chip from external motion affecting all chips. The trick is to synchronize the same acceleration reading between them.  You don't want readings at different times.
  • Add a 3 axis gyroscope so that you can compensate a change in tilt more accurately
  • Add a magnetometer so that you can sense magnetic north to compensate for gyroscope drift.
  • Add a GPS sensor so that you can calculate true north, and changes in total shift in ground level. This allows you to compensate for magnetic pole drift and long term absolute movement.
  • Make sure that the main computer that is connected to the Arduino is connected to an accurate NTP server.  That way the time of an event is accurate.

Of course each item increases the cost and complexity of the overall project.  So it depends on what you want to spend on time and money.
Logged

Thessaloniki, Greece
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Add multiple accelerometers, and average the results. This allows isolation of internal noise of a specific chip from external motion affecting all chips. The trick is to synchronize the same acceleration reading between them.  You don't want readings at different times.

this is pretty interesting ! do you have any reference for this idea ? Thanks a lot in advance.
Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12179
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Noise averaging, standard technique, discussed at length in "The Art of Electronics" for instance.  Take N^2 readings
and average and you'll get a factor of N less sensor noise (assuming each sensor's noise is independent).  With care the
same idea works in the time domain, multiple readings from the same sensor can be averaged (though this is often
thought of as low-pass-filtering).  Readings from the same sensor are less likely to be independent though...
Logged

[ I won't respond to messages, use the forum please ]

Pages: 1 [2]   Go Up
Jump to: