Simple angle meter using ADXL335 accelerometer [Arduino]


ADXL335

ADXL335 is 3 axis accelerometer with analog output from Analog Devices. You can buy it as an evaluation kit  with standard 2,5 mm connector.

ADXL335 acceleration measurement range is +/- 3 g. Supply voltage is 1.8 -  3.6 V, however all specifications at the datasheet is given at 3.0 V. This accelerometer has  3 outputs for X,Y,Z axis which voltage is proportional to acceleration on specific axis.

At midpoint when acceleration is 0 g output is typically 1/2 of supply voltage. If a supply voltage is 3V, then output is 1.5 V. Output sensitivity typically is 300 mV/g.

The connecting ADXL335 to Arduino board is simple. The accelerometer can be supplied from the 3.3 V output at Arduino board, however then midpoint voltage and sensitivity is different from specified at datasheet. I used 3.0 V supply voltage, it came from voltage regulator LM317.

Outputs of X,Y,Z axis are connected directly to analog inputs of Arduino.

R1 is 2.7k resistor, while R2 is variable 10k resistor. Please adjust R2 to have  3.0 V  output at LM317 before connecting ADXL335 board. Connect the board and adjust again, because output voltage will drop since load is connected. If  readings of the acceleration are unstable please connect additional capacitor between VSS and COM.

An accelerometer can be used not only measure acceleration, but also orientation. It’s because accelerometer sense the force of gravity which is pointed to the center of earth.

This is how sensing axis are orientated to ADXL335 (images from ADXL335 datasheet)

Readings from X,Y,Z axis reflects an orientation of an accelerometer.

Interesting that if a direction of sensing axis match to gravity direction measurement result is negative (-1 g).

Let’s start with an Arduino program. This program not only sends readings of acceleration from 3 axis via serial port, but also calculates rotation of the accelerometer around X, Y, Z, axis.


#define ADC_ref 2.56

#define zero_x 1.569

#define zero_y 1.569

#define zero_z 1.569

#define sensitivity_x 0.3

#define sensitivity_y 0.3

#define sensitivity_z 0.3

ADC reference voltage is 2.56 V. Default “on board 5V” is not selected because is slightly lower then 5.0 V and can be unstable. 0 g voltage after some simple calibration is set to be 1.569 V. The sensitivity for calculations is used as default – 300 mV/g.

void setup()   {

analogReference(INTERNAL2V56);

Serial.begin(256000);

}

Setting the ADC reference to 2.56 V and starting serial communication.

void loop() {


value_x = analogRead(0);
value_y = analogRead(1);
value_z = analogRead(2);

At the loop A/D conversions are performed for each of 3 channels.

xv=(value_x/1024.0*ADC_ref-zero_x)/sensitivity_x;

The acceleration is calculated at this line.

angle_z =atan2(-yv,-xv)*57.2957795+180;

The rotation(for Z axis) is calculated using atan2 function. It calculates angle from length of X, Y vectors. *57.2957795 – is conversation of radian to degree. +180 is for offset.

Full code:

// Simple angle meter using ADXL335 accelerometer
//from electronicsblog.net/

#define ADC_ref 2.56

#define zero_x 1.569

#define zero_y 1.569

#define zero_z 1.569

#define sensitivity_x 0.3

#define sensitivity_y 0.3

#define sensitivity_z 0.3

unsigned int value_x;
unsigned int value_y;
unsigned int value_z;

float xv;
float yv;
float zv;

float angle_x;
float angle_y;
float angle_z;

void setup()   {

analogReference(INTERNAL2V56);

Serial.begin(256000);

}

void loop() {

value_x = analogRead(0);
value_y = analogRead(1);
value_z = analogRead(2);

xv=(value_x/1024.0*ADC_ref-zero_x)/sensitivity_x;

Serial.print ("x= ");
Serial.print (xv);
Serial.print(" g ");

yv=(value_y/1024.0*ADC_ref-zero_y)/sensitivity_y;

Serial.print ("y= ");
Serial.print (yv);
Serial.print(" g ");

zv=(value_z/1024.0*ADC_ref-zero_z)/sensitivity_z;

Serial.print ("z= ");
Serial.print (zv);
Serial.print(" g ");

Serial.print("\n");

Serial.print("Rotation ");

Serial.print("x= ");

angle_x =atan2(-yv,-zv)*57.2957795+180;

Serial.print(angle_x);
Serial.print(" deg");
Serial.print(" ");

Serial.print("y= ");

angle_y =atan2(-xv,-zv)*57.2957795+180;

Serial.print(angle_y);
Serial.print(" deg");
Serial.print(" ");

Serial.print("z= ");

angle_z =atan2(-yv,-xv)*57.2957795+180;

Serial.print(angle_z);
Serial.print(" deg");
Serial.print("\n");

delay(1000);
delay(1000);
}

And the demonstration of program in the video below.

  • tony

    Hi, i have tryed the code and makes error  on #32
    what´s wrong?

    • http://www.electronicsblog.net/ Darius

      http://www.arduino.cc/en/Reference/AnalogReference Internal 2.56 V reference only available at Arduino Mega Board. You could just comment that  line and change #define ADC_ref 2.56 to #define ADC_ref 5.0 or #define ADC_ref 3.3 depending on the board you have.

      • tony

        Hello Darius, ok, i have the arduiono Uno and a adxl335
        can you please send ,e code for this board?
        Im still a beginer, but  this reading with rotation are very interresting to me, due i want to wach the position of a satelite antenna dish.
        best regards
        tony

  • helyx

    Hi, sorry I’m very new to this, what exactly do you mean by a standard 2.5mm connector? I can see it in the video but I need to buy it separately. Thanks!

  • http://www.facebook.com/people/Prem-Kumar/100001163078127 Prem Kumar

    hi,i am newly using the accelerometer(adxl335) ,can u pls help me to write the code for aurdino  in bascom anguage

    • http://www.electronicsblog.net/ Darius

       Just find bascom example for ADC and adapt it for reading values from  adxl335.

  • http://twitter.com/Suresh_Jonna Suresh Jonna

    Hi Darius,

    I thank you so much for this information. This is my question given below,

    Does your code show change in angle from 0 to 360 Degree?

    PS: Videos doesn’t work in my system.

  • Josh

    First of all this example is great, thanks a lot. But I was curious how did you get the #define zero and #define sensitivity values, and do I need to change these values if I’m running the ADXL335 straight off of the 3.3 V supply off my Arduino Uno?

    • http://www.electronicsblog.net/ Darius

       #define zero would be 3.3/2 = 1.65 V. #define sensitivity leave as it as. Just ran code and position sensor at various positions as shown in the last pictures of this blog post. If you don’t get “zero” g reading adjust #definezero. If  zero is adjusted get “one” g bay changing #definesensitivity.

      • Josh

        Awesome, it works perfect, thanks a lot.

        • rupali

          josh,
          I am also using 3.3 V supply from arduino & connecting 3.3 V to Aref of arduino pl. tell me what values u have taken for zero and sensitivity?

          • http://www.electronicsblog.net/ Darius

            Find out that values yourself. Align sensor so it would sustain -1G , 0G, +1G and measure voltage output, with arduino, or with multimeter. Voltage at 0G will show you a middle point – zero. Voltage difference (range) between +1G and -1G divided by 2 would be your sensitivity.

          • Rupali

            Thanks for replying.
            I have measure voltage using multimeter when my xposition is at 1g,-1g and 0 g respectively. I got following results.
            1g=1.506,-1g=1.014,0g=1.262. Now pl tell me whether following calculations are correct or not.

            Sensitivity=1.506-1.014/2=0.
            246 and Zero_X =1.262 I am using 3.3 v as adc reference and Vcc for adxl335.
            Thanks.

          • http://www.electronicsblog.net/ Darius

            Seems good, although is odd, that voltage is higher than mine using 3.0 V voltage source. The best way to be ascertain that is it correct output G reading via serial port and check if G values (-1,0,1 G) are what it suppose to be.

  • saramijou

    hi im using adxl335 to measure the speed of the ball can any one help me

  • saramijou

    im using adxl 335 to measure the speed of the ball as wristband speed detector.
    so can u just help me with brife explanition how can i measure the speed and what program should i use ?
    how can i measure it by using multimeter?
     

    • http://www.electronicsblog.net/ Darius

      You want to measure RPM?

      • saramijou

        i just want to get the value of x,y and z
        in volt

  • D Edwards649

    im using the adxl 326, could you show me how you wired your accelerometer to the arduino board or what pins you used?

    -Thanks

  • Pingback: Akcelerometr – ADXL335 | YWD - blog

  • http://www.facebook.com/belyksaravananBE Saravanan Vel

    hi Darius.. i’m saravanan doing my Master of Engineering in Anna university, chennai25, Tamilnadu, India.. i’m doing my final year project, “designing and control of an inverted pendulum using avr (or may be dspic)”.. can i use adxl 335 accelerometer to measure the current angular position of the pendulum… please help me regarding my project.. waiting for your reply.. thanks in advance…

    • http://www.electronicsblog.net/ Darius

      Yes, angular position can be calculated from X Y Z values while adxl 335 should be inside ball.

  • Murilo

    Where is the funtcion “serial.print()”? Tahnk’s

    • http://www.electronicsblog.net/ Darius

      it’s included by default in Arduino library.

  • naren

    how do i change the reference point to measure the angle from . . .?

  • Amir

    Dear Darius . Thanks for you useful code. The initial values when I place the accelerometer on a flat surface are x= 94 g y= -1.77 g z= -0.53 g

    Angle x= 253.46 deg y= 254.85 deg z= 222.35 deg . I don’t get Zero g. is that normal ? how much should change sensitivity ? I mean on a flat surface which one should be zero ?

    • http://www.electronicsblog.net/ Darius

      I think you should multiply g reading by 0.01. It would make more sense – x = 0.94 g , y = – 0.0177 z = -0.0053g.

  • AGSP

    I dont want to use Z axis, because I have only 2 analog pins. I just want to measure x axis angle with respect to x, y axis. Can you please tell me how should i do that………

  • ayub

    hi great post very helpful. could you please tell me that if we are using ADC reference of 2.56v to VCC pin of accelerometer then are we not suppose to connect the 3.3v supply voltage to the same pin? and can i run this at 9600 baud? because in the serial monitor baud rate of 256000 is not available. please reply.

    • http://www.electronicsblog.net/ Darius

      ADXL335 sensing range +/- 3 G. So if it is suppled with 3.0 V sensing output(0.3 V / G) is between 0.6 and 2.4 V so reference of 2.56 V is enough.
      Yes, you can use whatever baud rate you want.

  • jayanth

    what if we use a different internal voltage reference…because only arduino mega has INTERNAL2V56 while Arduino Du has INTERNAL …

    • http://www.electronicsblog.net/ Darius

      Just delete this line, and replace #define ADC_ref 2.56 with #define ADC_ref 3.3 if board is powered by 3,3 V or
      -> #define ADC_ref 5.0 if board is powered with 5.0 V.

  • Dillon Chaffey (Chafflube)

    Thank you very much for this code, I am learning from it as we speak, with intentions of making a “space-style” 3D rotating plane on a 7″ TFT in the dash of my car that will display almost real time data relating to the angle my car is sitting on at the time, I hope to use this data to control the height of each of the four wheel using pneumatic pistons, so as to allow a perfectly horizontal ride all the time, even while going over speed bumps. This would be particularly handy when I transport fragile items.

  • hema

    can i use this code for MMA7361 accelerometer

  • ali

    great code and demonstration!!! thanks alottttt

  • neward

    totally newbie, but I want to put accelerometer in a box and drop it to measure the g-force on a box. Is that feasible(with work)

    • http://www.electronicsblog.net/ Darius

      This accelerometer can measure forces to 3 G. You should so same calculations it is will be enough for you.

      • neward

        Thank you.

        • neward

          Darius: Just an update on my thinking, if I drop a box from 1 foot that is subject to 2g, box is reaching the floor at 11f/sec ( escape velocity of a rocket into space is 8f/sec). My point is it is quite adequate!!

          v=sq root of (2x2x32x1)

  • Santiago Paladines

    I have a problem with this line “analogReference(INTERNAL2V56);” there shows that the INTERNAL2V56 was not declare I’m using an arduino uno

    • http://www.electronicsblog.net/ Darius

      Just delete this line, and replace #define ADC_ref 2.56 with #define ADC_ref 3.3 if board is powered by 3,3 V or
      -> #define ADC_ref 5.0 if board is powered with 5.0 V.

      • Santiago Paladines

        it doesnt work… i get this at the serial monitor “Úîê+ý˵y±ÏÍÖ½üù” help me please….

        • http://www.electronicsblog.net/ Darius

          Did you set speed of serial monitor to 256000 ?

          • Santiago Paladines

            yes and i already try with 330000 500000

          • http://www.electronicsblog.net/ Darius

            Try to use lower speed, try 9600, set it serial monitor and change code to “Serial.begin(9600);”

  • Ayashi

    You saved my day : THANK YOU!

  • laura jacqueline

    hey, i was searching for an accelerometer reading code and your code is great! but the thing is, mine shows a same data all the time…and i’m using #define ADC_ref 3.3. can you help me to figure it out?

    • http://www.electronicsblog.net/ Darius

      Measure voltage with multimeter on the Arduino pins, that supposed to receive signal from ADXL to check what voltage is in the correct range and changes when you rotate chip.