ADXL335 акселерометры. теория и практика.

24.05.2012
By

Гироскоп или акселерометр

Комментарии: 47

После выхода iPhone 4 многие много внимания было уделено новому дисплею, корпусу и прочим важным вещам. И лишь мимоходом отметили замену акселерометров на гироскопы для улучшения управления в играх. В своей статье для «Компьютерного обозрения» я отметил этот момент, в следствие чего даже консультировал одного из читателей. Почему бы не уделить этому моменту внимание и не разобраться зачем одни датчики были заменены на другие и чем они собственно отличаются?

Начнем с того, что и акселерометры и гироскопы являются инерционными датчиками. Акселерометры (лат. accelero — ускоряю и ?????? — измеряю) — приборы, предназначенные для имерения проекции кажущегося ускорения.

Простейшая модель акселлерометра

В данном случае русская Википедия дает на удивление неплохое определение. В случае с мобильными телефонами датчики реагировали на изменение вектора ускорения свободного падения и все последующие действия исходили из этого.

Условная схема определения положения устройства в пространстве с применением двух акселлерометров

Точность в результате была довольно низкой, так как угол поворота устройства в пространстве напрямую измерить таким образом невозможно, лишь примерно оценить. На практике это выражалось в задумчивости поворота экранов, ложных срабатываниях и т.д. Какие же преимущества дает гироскоп и чем он собственно отличается?

Определение на Вики настолько далеко от общего, что обратимся к первоисточнику.

Впервые определение гироскопу дал Леон Фуко, назвавший так свой прибор, с помощью которого он наблюдал суточное вращение Земли. В Большой Советской Энциклопедии приводится следующее «Гироскоп — быстро вращающееся твердое тело, ось которого может изменять свое направление в пространстве». В современных гироскопах могут происходить разнообразные физические процессы, не обязательно основанные на вращении твердого тела. Хотя и классические гироскопы все еще применяются.

Примеры гироскопов. Банальный волчок по своей природе является гироскопом.

Примером классического гироскопа является ротор в кардановом подвесе. При вращении ротора он будет сохранять неизменным свое положение в пространстве независимо от движения основания. Таким образом можно измерять угол поворота основания, а соответственно и корабля/самолета etc. Именно по гирокомпасам ходят суда и летают самолеты, не полагаясь на примерные показания магнитного компаса, особенно в полярных широтах, а данные о положении самолета в пространстве получаются с гировертикали и гирогоризонта.

Естественно, классический гироскоп не может применяться в электронике. Для этого используются вибрационные микромеханические гироскопы — датчики угловой скорости. Чувствительный элемент таких приборов закреплен, при попытке его поворота возникает кориолисова сила, пропорциональная угловой скорости. Не вдаваясь в подробности работы, которые вряд ли будут кому-то интересны скажем, что выходным сигналом ДУС является напряжение, пропорциональное угловой скорости. Такие датчики имеют небольшие габариты (около 10x10x2 мм) и могут быть легко интегрированы в печатную плату.

Мировым лидером в производстве таких датчиков является компания Analog Devices, датчик которой изображен на рисунке. Можно с большой долей вероятности утверждать, что именно датчики этой компании установлены в iPhone 4.

Преимущества очевидны. В любой момент времени можно знать положение телефона в пространстве. В играх для управления можно использовать не только поворот устройства, но и скорость поворота, что позволяет организовать более точное и реалистичное управление.

Надеюсь, этот небольшой экскурс в теорию и практику гироскопов вас не утомил, а лишь еще раз подчеркнул, что современный мобильный телефон крайне сложное устройство, в котором применяются технологии ранее доступные только авиационной и космической промышленности. А мы тем временем не брезгуем ими открывать пивные бутылки.

Изображения датчиков взяты с сайта представительства Analog Devices в СНГ и странах Балтии

 

http://www.sparkfun.com/products/9269 - информация по ADXL335

 

http://www.electronicsblog.net/simple-angle-meter-using-adxl335-accelerometer-arduino/ - измерение угла с помощью ADXL335

 

Sensing Orientation With The ADXL335 + Arduino

Friday, April 22 nd , 2011

I know, I know, this one has such a simple name. Where’s the pun? Honestly, the description was just to long to include one. Maybe it could have been “What’s Up? Sensing Orientation With The ADXL335 + Arduino” – Ehhh… Probably not.

A few weeks ago we wrote a tutorial about using the ADXL345 to sense taps, and drops, but this week we are going to wind it back, go back to basics, and show you how to take an analog 3-axis accelerometer and use it to sense simple orientation with it, specifically the ADXL335, but this can be applied to any analog 3-axis accelerometer.

Before we really dive into it, we need a general understanding of how accelerometers work, so if you already know why each axis can only differentiate 180deg of movement, you can skip this. Wraning: Over-simplification ahead. In the last article I described an accelerometer as a device that sensed movement. Today, think of them as devices that sense gravity.

Basic Understanding Of Accelerometers

Accelerometers measure acceleration, often caused by motion. But when they are standing still, the only acceleration the accelerometer senses is due to gravity pulling down on it.

Imagine a box that has little springs sticking straight out from the sides of the box, and that the accelerometer measures how hard gravity is stretching out those springs. The springs on the side are all bending the same amount, the spring on the bottom is all stretched out, and the one at the top is not stretched at all (because the spring is pull back into itself), so the accelerometer sees it as feeling no gravity, or 0g (gravity). If you rotate the box 90? and follow the spring on the top. It is now on the side and is hanging down some and the sensor sees it now feels .5g. Rotate 90? again, and it is at the bottom, stretched out, and it feels 1g. Rotate again 90? and we are at the side again, with it feeling .5g, and 90? rotation again, we are back at the top and it feels 0g. So we made a full rotation and the accelerometer saw this: 0g-> .5g -> 1g -> .5g -> 0g.

If you look at this, it means that the accelerometer can really only sense differences in 180? of movement as the other 180deg is just a mirror image. So how can we sense 360 deg of movement?

The trick to this is that while one axis can only sense a 180deg difference, so can the another axis, but they sense it differently. If you look at the chart to the right, you can see the sensed values while rotating round the X Axis. (The x never changes because it is always facing the same direction) – So we can combine the y, and z values to find x using a trigonometry function called Atan2 who then gives us values back as -180? to 180? (but in radians, so it is -? to ? and well have to convent it).

No Love For Yaw

Yaw is name for rotation around an axis that is similar to spinning a top, or shaking your head “no.” Accelerometers can’t measure this type of motion. Why? Well think about the box. If you turn the box in this manner, non of the sides change their orientation to the ground. If you need to measure yaw, you will need to incorporate a gyro or digital compass into your project, but it gets tricky, and is beyond the scope of this article.

Why So Shaky?

The accelerometer is really going to report a proper measurement when it is standing still. if it is shaken, moved, bumped, or in free fall, the acceleration the accelerometer measures is no longer purely gravity based, and you are going to see that in your readings.

But I Need A Cleaner Reading

If you need a clean reading during movement, you need something this article won’t provide, and that is a gyro and an accelerometer working in combination. Together they form something called an IMU – Inertial measurement unit. Correctly setup, and gyro is able to kick in where an accelerometer leave off, and vise versa. A gyro is great at measuring rotation, but has no understanding of orientation. And an accelerometer is good at determining orientation, but has no ability to keep track during rotation.

Hooking It Up

Connecting the ADXL335 to your Arduino is a snap. It powers off of the 3.3v, and the x,y,z connectors just connect to the 0,1,2 analog input pins. This accelerometer is a very simple and just outputs an analog voltage depending on the sensed value.

Code For The ADXL335 Or Other Analog Accelerometer

So here is some code: This code simply calculates 0-360? values for X,Y & Z and prints it to the serial terminal. This code is not specific to the ADXL335, and with almost no tweaking you can make this work with any analog 3-axis accelerometer.

Our Arduino’s analog input pins are comparing the analog voltage from the accelerometer’s analog outputs to 5v, and assigning number to that. If the Arduino senses 0V it reports 0, and 5V it reports 1023 ( you read more in the ADC Article in our wiki). The highest value I read from the sensor when it was standing still was 402, so that is 1g, and the lowest was 265, so that is 0g. If you get funny output from the code, you will need to change this depending on the highest and lowest values you get from your accelerometer. (Ask us the discussion forum for help if you need it.) Just changing these values will make the code work for any other analog 3 axis accelerometer, not just the ADXL335.

Because 265 (0g) was sensed at 0?, and 402 (1g) was sensed at 180? we are going to convert those values accordingly. But atan2, likes using -90 to 90 better, so we will do that instead. Lastly we convert the atan2 radian output to degrees, and voila, we have 360? measurements!

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Simple code for the ADXL335, prints calculated orientation via serial
//////////////////////////////////////////////////////////////////

//Analog read pins
const int xPin = 0;
const int yPin = 1;
const int zPin = 2;

//The minimum and maximum values that came from
//the accelerometer while standing still
//You very well may need to change these
int minVal = 265;
int maxVal = 402;

//to hold the caculated values
double x;
double y;
double z;

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

void loop(){

  //read the analog values from the accelerometer
  int xRead = analogRead(xPin);
  int yRead = analogRead(yPin);
  int zRead = analogRead(zPin);

  //convert read values to degrees -90 to 90 - Needed for atan2
  int xAng = map(xRead, minVal, maxVal, -90, 90);
  int yAng = map(yRead, minVal, maxVal, -90, 90);
  int zAng = map(zRead, minVal, maxVal, -90, 90);

  //Caculate 360deg values like so: atan2(-yAng, -zAng)
  //atan2 outputs the value of -? to ? (radians)
  //We are then converting the radians to degrees
  x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
  y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
  z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);

  //Output the caculations
  Serial.print("x: ");
  Serial.print(x);
  Serial.print(" | y: ");
  Serial.print(y);
  Serial.print(" | z: ");
  Serial.println(z);

  delay(100);//just here to slow down the serial output - Easier to read
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

 

Extending This

Even with the limitations of the ADXL335, you can do some great things. This is one time that I think just hooking a RGB LED to your Arduino with this makes a great device. Just kinda fun to play with, mixing colors as you turn it, so if you must use LEDs with this, I’m ok with that.

This can really come in handy when you want to control anything based on orientation. So, get your tools ready, and build a reclining chair that knows when you reclined, and turns on the TV for you, OR… use it to master your posture as you balance a book on your head while recording the values.

Just a note: I had issues with connecting this with a servo. The servo was taking too much power from the Arduino, and the it was really throwing off the analog readings. So just note that. I did read that the servo needed a decoupling capacitor to work well, but I have not tried it.

We need your help

bildr is in need of people interested in helping write any sort of blog post for bildr, not just tutorials. If you think you would like to help bildr by writing something, supplying code or schematic, or just have an idea for an article or other post you think should be written, please contact us at blog@bildr.org or let us know in the forum.

 

 

Simple angle meter using ADXL335 accelerometer [Arduino]

Posted on 

 

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 voltageregulator 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
#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.

1
2
3
4
5
6
7
void setup()   {
analogReference(INTERNAL2V56);
Serial.begin(256000);
}

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

void loop() {

1
2
3
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.

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

The acceleration is calculated at this line.

1
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// 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.

 

Добавить комментарий