Hi I hope someone can help me. I have bought a Sparkfun 5DOF IMU which uses an ADXL335 Accelerometer. I am building a Segway type balancing scooter so and will be using a complementary filter combining the readings from the Accelerometer with the Gyro.
First some precursors
I am have hooked the Arduinos 3.3v to the AREF
I am definitely calling AnalogReference(EXTERNAL); in the sketch
I am using a clean regulated power supply to power the Arduino Uno.
To begin with I am trying to get a sensible reading out of either the X or Y axis of the accelerometer. What I want to do is read the values and at rest, calculate a reliable angle from -90 to +90 degrees. At rest my low reading is 399 and my high reading is 607, so the range of values I am interested in is 208 ADC steps. I know accelerometers read acceleration so for the purposes of this question I will ignore values outside this range caused by positioning the accelerometers breadboard at -90 degrees, flat and +90 degrees.
So basically at rest the mid point value is around 503. With 104 ADC reading steps either side.
My question for those who have used ADXL335’s with 3.3v power.
1.) Is it normally to have a range of around 208 steps on the ADC from -90 to +90? I just need a quick sanity check.
2.) I know I could use a function like map(ADC_Value, 399, 607, -90, 90); to coerce these values into a range but that would only give whole degrees. Ideally would like fractions of degrees e.g 10.1, 10.2, 10.3 etc. Is this possible with some clever code as 180 degrees / 208 steps gives 0.86538461538461538461538461538462 degrees per step. Which is pretty rough
3.) I have noticed that the closer my angle gets to 90 degrees (vertical) the less responsive the accelerometer is to small changes. Is this normal, logically it seems so as the force of g acting on that plane of the accelerometer reduces the further it moves from its ideal plane of measurement. But if so how does anyone ever manage to get usable angles out of it.
Please help, I have been on for 4 days about 10 hours a day trying to make sense of this and have tried every snippet of code I can find on the web.
I suppose my question is, can I use an accelerometer to get reasonably accurate angle from -90 to +90 degrees, does anyone have an example of some code which does exactly that (I am not interested in 360 degrees, just a clean 180).
What's the voltage range of the IMU, I remember playing with an ADXL335 and deciding that the range was not good enough for the Arduinos ADC to get much resolution. IIRC it went from say 1v to 2v so that was 1000mV range with 5mV res on the Arduino or 1:200 over 180 degrees. IE ~1 degree.
Don't quote my on the numbers but the board I designed (haven't built yet) used a 16-bit ADC to get the res I wanted.
As for increasing the res in software, I don't see that you can do that. If you gate 90 from the ADC when 91.2 was actually on the input I see no way of recovering the lost data.
Use a voltage divider to drop the 3v3 referance to about 2V, this is more than the internal voltage comparison (1.1V) so it should be ok.
this will increase the resolution to about 1/2 degree or so.
You could also use the internal referance of 1.1v and use voltage divider on the ADXL335 so it does not exeed the 1.1V, not sure what is better
If I'm correct in that the output is ratiometric and centered around VCC/2 you can never get full/good resolution without offsetting the voltage, or using a better ADC.
However ArduinoM's idea of dropping AREF will get you as good as you can get and only use two resistors. Drop it to whatever the ADXL puts out at +90 degrees.
Thank you all. Some very good ideas here. I am fine with the coding but electronics is not my strong point. Just to clarify.
So based on the current setup at 3.3v AREF the accelerometer outputs 1.287v at -90 (ADC reading 399) and 1.958v at +90 (ADC reading 607).
Graynomad suggests I should use a voltage divider to to set the AREF voltage at the +90 value of ~2v
Ok, So heres my follow up question. Assuming I build a voltage divider using 1% tollerance resistors I take the output from the 5v line and divide it down to 2v and feed it into the AREF pin.
BUT, do I still drive my ADXL335 directly at 3.3v from the 3.3v pin. Thats the bit I am having a brain freeze on.
Excellent, thank you both. Its all becoming clearer now. My only remaining query relates to stepping down the voltage from the 5v provided by the Arduino Uno to ~2v for my new reference voltage.
I have taken a look at voltage dividers but the calculations all seem to require knowing the current drawn by the final device which is frankly over my head.
Also I am concerned that the 5v output from the Arduino may not be stable. My Arduino will be powered by the 5v Output from a Sabretooth 2x25 Motor Controller and I am worried that as the large motors draw power the 5v pin on the Arduino may fluctuate. This being the case I believe if I build a voltage divider using 1% tolerance resistors their output voltage will fluctuate.
I think an alternative way to build this would be using a zener diode. I am not sure but I am led to believe these provide a more stable current when the input voltage fluctuates
I am really after a recommendation of some way of maintaining of taking a 5v input and producing a clean 2v output. If anyone can recommend a part code which will take me in one step from 5v to around 2v with a high tolerance ~1% I would be over the moon.
My Arduino will be powered by the 5v Output from a Sabretooth 2x25 Motor Controller and I am worried that as the large motors draw power the 5v pin on the Arduino may fluctuate.
This is a worry. You're Arduino will thank you for a nice 7v or so VIN so it can use it's own regulator.
I don't think you said what accuracy you need but you have to have good voltage levels all up the chain and that power supply you're using does not seem right.
A zener would be OK I think, personally I'd go for a proper voltage reference like the REF191, that's 2.048 volts.
The way you have it now with both AREF and the ADXL running from the same 3v3 is good in the sense that if the 3v3 changes all the readings stay the same in relation to each other, ie if you have 3v or 3v3 the mid point reading from the ADC is still 512.
That's not the case it you have a separate AREF. If you add a separate 1% AREF and the 3v3 is only good for say 5% then you will get fluctuations in the readings.
So I think the first job is to get rid of the Sabretooth as the Arduibo PSU and see what the specs are for the Arduino 3v3 regulator.
As always your logic is as impeccable as your foresight.
I will start by removing the Sabretooth 2x25 motor controller from the equation for the time being and assume I am using a 7v regulated power supply.
Thinking on what you have said below:
The way you have it now with both AREF and the ADXL running from the same 3v3 is good in the sense that if the 3v3 changes all the readings stay the same in relation to each other, ie if you have 3v or 3v3 the mid point reading from the ADC is still 512.
I have a proposed solution. How about if I run the 3.3vpin directly to the IMU and also run the 3.3v via a voltage divider into the AREF pin as below
3.3v---+------+
| |
IMU |
Vin |
64KOhm
|
------------- 1.97v to AREF
|
100Kohm
|
Ov
That way If the 3.3v fluctuates the voltage to the AREF pin does so at the same time.
However... I believe that when calling AnalogReference(EXTERNAL); the Arduino uses an internal ~32Kohm resistor on the AREF pin so in my case, instead of needing the voltage divider above, simply putting a single 20Kohm resistor between 3.3v and the AREF pin should form a voltage divider giving me ~1.988v on the AREF pin.
As my IMU puts out ~1.96v at +90 degrees this should give me the best resolution I can expect from these sensors.
As always your thoughts are very much appeciated.
P.S Been on the net since 1996 and this is my first every forum post, thank you for making it a rewarding experience.
just grab your multimeter and one rotary potentiometer and adjust, it will probably be the most painless operation. the chanches of the 5v mirroring the 3v3 fluctuations are big so if you connect the pot to 5v it should be ok. You should not overengineer this thing with too many of components, if doing that go for the big gun and use omp-amps and voltage offseting and bigger ADC
My guess is that your thingy will be too fast to keep up with super fine resoloution and thus slower reaction arduino because of higher amount of data going through the processing....