Hello. I have bought the BMA180 accelerometer breakout board through Sparfun’s website: http://www.sparkfun.com/products/9723 .
By putting it in a car, I am trying to get it detect two states, namely, car at rest and car at motion.
I am quite new at using Arduino and the accelerometer. Although I have some basic knowledge of C, I am quite lost after looking through the data sheet provided: http://dlnmh9ip6v2uc.cloudfront.net/dat … 0-07_2.pdf .
At this point, I have the following code that I have obtained from a post on Arduino’s forum: http://www.arduino.cc/cgi-bin/yabb2/YaB … 1276427322 and modified to try to obtain my stated objective:
#include <Wire.h>
#define address 0x40
void setup()
{
Wire.begin();
Serial.begin(9600);
initBMA180();
delay(2000);
}
int temp;
void loop()
{
readAccel();
delay(500);
}
int y;
void readAccel()
{
int temp, result;
temp = 0;
while(temp != 1)
{
Wire.beginTransmission(address);
Wire.write(0x03);
Wire.requestFrom(address, 1);
while(Wire.available())
{
temp = Wire.read() & 0x01;
}
}
Wire.beginTransmission(address);
Wire.write(0x04);
Wire.requestFrom(address, 1);
while(Wire.available())
{
temp |= Wire.read();
temp = temp >> 2;
}
Serial.print("y = ");
Serial.println(temp);
if (temp > 5) {
Serial.println("In motion");
}
else {
Serial.println("At rest");
}
result = Wire.endTransmission();
}
void initBMA180()
{
int temp, result, error;
Wire.beginTransmission(address);
Wire.requestFrom(address, 1);
while(Wire.available())
{
temp = Wire.read();
}
Serial.print("Id = ");
Serial.println(temp);
result = Wire.endTransmission();
checkResult(result);
if(result > 0)
{
error = 1;
}
delay(10);
if(temp == 3)
{
// Connect to the ctrl_reg1 register and set the ee_w bit to enable writing.
Wire.beginTransmission(address);
Wire.write(0x0D);
Wire.write(B0001);
result = Wire.endTransmission();
checkResult(result);
if(result > 0)
{
error = 1;
}
delay(10);
// Connect to the bw_tcs register and set the filtering level to 10hz.
Wire.beginTransmission(address);
Wire.write(0x20);
Wire.write(B00001000);
result = Wire.endTransmission();
checkResult(result);
if(result > 0)
{
error = 1;
}
delay(10);
// Connect to the offset_lsb1 register and set the range to +- 2.
Wire.beginTransmission(address);
Wire.write(0x35);
Wire.write(B0100);
result = Wire.endTransmission();
checkResult(result);
if(result > 0)
{
error = 1;
}
delay(10);
}
if(error == 0)
{
Serial.print("BMA180 Init Successful");
}
}
void checkResult(int result)
{
if(result >= 1)
{
Serial.print("PROBLEM..... Result code is ");
Serial.println(result);
}
else
{
Serial.println("Read/Write success");
}
}
void readId()
{
int temp, result;
Wire.beginTransmission(address);
Wire.requestFrom(address, 1);
while(Wire.available())
{
temp = Wire.read();
}
Serial.print("Id = ");
Serial.println(temp);
result = Wire.endTransmission();
checkResult(result);
delay(10);
}
I obtain the following output in the monitor window:
Id = 229
Read/Write success
X = 63
In motion
X = 0
At rest
X = 0
At rest
X = 0
At rest
X = 0
At rest
Now, when I slightly jolt the board with everything attached, it will say that it is in motion. However, while it is still in motion, the monitor will often display “X = 0 At rest”. Also, at the beginning after the “Read/Write success”, it always says it is in motion. I hope someone can help me overcome these issues so that it will precisely read “At rest” when it is at rest and “In motion” when it is clearly in motion. Suggestions and comments will be greatly appreciated.
-Choke
It looks like you are assuming that there will be non-zero ratings when the accelerometer is in motion. This is not true; the accelerometer only reads a change in velocity and not velocity itself. This is not an easy thing to accomplish, although I think maybe you measure acceleration in the Z direction over a period and if that is “noisy” you can probably assume you are in motion since most roads have bumps in them. Otherwise you’re out of luck and should try a GPS unit instead.
Do no try and integrate the acceleration to get velocity. This will not work well for you.
As a final note, I recommend a GPS, an accelerometer is not right for this. Sorry if you already knew this and I misunderstood you!
The accelerometer measures acceleration so you’re never going to have it sense absolute motion (or not in motion). What it’s doing is detecting the change from stopped to moving (or moving to stopped), if that change is large enough. A hard start (high acceleration) or hard stop (high deceleration) is easy to detect with a threshold test (this is what’s being done). Once either acceleration is ceased and the vehicle is either moving at a steady speed or stopped, the measured output is also zero and so it fails the threashild test … thus the indication that it’s not in motion. It’s like the test being done in setion 6 of the PDF you attached. For that matter read section 7, it appears you could have the accelerometer do all the processing presently done in the Arduino and simply output a single digital line.
The best you can hope for using an accelerometer is to ASSUME the car is initially at rest and sense the acceleration to declare the “in motion” state. The software should leave this state alone (“in motion”) until it detects a large deceleration, and then declare the “at rest” state. It also ASSUMES the decelration is large enough for long enough to stop the car (opposed to just slowing it down). If either acceleration isn’t large enough in magnitude to detect above the noise … you’re out of luck.
There are optical “5’th wheels” that can detect absolute motion (as well as measure speed) but they’re $$$s.
http://www.accidentscience.com/datron.htm
They are other ways you could rig a car but I’m assuming you want something portable and not specific to any one vehicle.
A review of Newton’s laws of motion might help clear up any confusion re: acceleration and motion.
http://en.wikipedia.org/wiki/Newton’s_laws_of_motion
Thanks for all the helpful replies. The BMA180 was recommended by a friend after discussing with that person of what I wanted to accomplish. After reading some guides and running some example codes, I began to realize that the thing is very good at measuring sharp changes in acceleration but seems somewhat unfit for my purpose.
AKAtheHat, is the GPS you are referring to compatible with the arduino to be programmed and small enough to be attached on a regular sized breadboard?
Mee_n_Mac, how would I declare “in motion” and “at rest” states? Because at the beginning after ‘Read/Write success’ the X value seems in accurate, so I’m guessing one should skip that value. An example code will help greatly. The second assumption about the deceleration being large enough and long enough to stop the car does seem hard to make whenever the car is moving slowly or when the car’s deceleration is low.
Finally, could there be any other ways to accomplish my task here?
Thanks again.
artichoke:
Finally, could there be any other ways to accomplish my task here?
Thanks again.
GPS is one way. Does your car have a speedometer ? If not, why not add one ? Can you tells us a bit more about the specific circumstances that seem to prohibit the obvious answers and are forcing you into this external device ? Using an accelerometer can only crudely indicate in motion or at rest for the reasons already mentioned.
This is part of a project I’m doing. I’m trying to make the ‘gadget’ warn inattentive drivers. The project involves sensing obstructions and lights. I want to put it inside or on a vehicle. First thing is that the ‘gadget’ will know whether a car is moving or not, and if it is in motion, it should be in some idle state since I’m assuming the driver’s at attention while the car’s moving. Then when the ‘gadget’ knows that the car is in complete stop, it searches for red light and/or any obstruction in front (be it car, person, etc.). And when traffic light is green and/or obstructions are cleared, it gives out an audible signal to let drivers know that it is clear to go. I will delay the output somewhat since the reaction time of the driver might be one or two seconds, and I don’t want it to constantly gives out audible signals when it is not necessary.
So that is pretty much the gist of it. I acquired a SRF02 ultrasonic sensor and that appears to be working fine, giving our accurate distance of the obstruction in front, and the code written allowed arduino’s monitor window to display ‘No obstruction’ and ‘Obstruction’ at the right circumstances. The accelerometer does not do the trick and, as mentioned here by the responses here, will only give crude results. So I’m looking for alternatives. About the GPS, can you refer to me a page that sells it since I’m not quite familiar with it? Thanks.
The GPS producs SF sells are here …
http://www.sparkfun.com/categories/4
You may find this tutorial of some interest and I’d be suprised if there isn’t an Arduino shield and code to go with it.
http://arduino.cc/playground/Tutorials/GPS
Note the speed in knots is commonly sent out.
I’m not familiar with that unit. But it would seem capable. You should enquire whether the GPS outputs a TTL level serial data stream. If it’s RS232 or RS422 only, you’ll need another converter IC. Be aware GPS may not work inside a car unless the antenna has a clear line of sight up and out a window. Some receivers are better than others in this regard.
From the descriptions and the specs, it appears that it has TTL asynchronous serial output @ 4800 bps. As for the antenna, it is a built-in patch antenna. More info.: http://www.robotshop.com/content/PDF/pr … -28500.pdf