Рейтинг@Mail.ru
Аналоговый трёхосный акселерометр ADXL335
Аналоговый трёхосный акселерометр ADXL335

Как подключить акселерометр к Arduino

В этот раз мы займёмся подключением аналогового трёхосного акселерометра ADXL335 к Arduino.

Инструкция по подключению акселерометра ADXL335 к Arduino

Вам понадобится

  • Arduino;
  • акселерометр ADXL335;
  • персональный компьютер со средой разработки Arduino IDE.

1Принцип действияакселерометра

Акселерометры используют для определения вектора ускорения. Акселерометр ADXL335 имеет три оси, и благодаря этому он может определять вектор ускорения в трёхмерном пространстве.

Ввиду того, что сила земного притяжения – это тоже вектор, мы можем определять ориентацию акселерометра в трёхмерном пространстве относительно центра Земли.

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

Принцип снятия измерений с аналогового акселерометра ADXL335
Принцип снятия измерений с аналогового акселерометра ADXL335

Рассмотрим подробнее, что же показывает нам акселерометр. Пусть датчик лежит горизонтально, например, на столе. Тогда проекция вектора ускорения будет равна "1g" по оси Z, или Zout = 1g. По остальным двум осям будут нули: Xout = 0 и Yout = 0. При повороте датчика «на спину», он будет направлен в противоположную сторону относительно вектора силы тяжести, т.е. Zout = −1g. Аналогично измерения снимаются по всем трём осям. Понятно, что акселерометр может быть расположен как угодно в пространстве, поэтому со всех трёх каналов мы будем снимать отличные от нуля показания.

Если датчик сильно тряхнуть вдоль вертикальной оси Z, то значение Zout будет больше, чем "1g". Максимальное измеряемое ускорение составляет "±3g" по каждой из осей («плюс» и «минус» тут обозначают направление ускорения).

Думаю, с принципом работы акселерометра разобрались. Теперь рассмотрим схему подключения.

2Схема подключения акселерометра к Arduino

Чип аналогового акселерометра ADXL335 довольно мелкий и помещён в BGA корпус, и в домашних условиях его сложно смонтировать на плату. Поэтому я буду использовать готовый модуль GY-61 с акселерометром ADXL335. Такие модули в китайских интернет-магазинах стоят практически копейки.

Для питания акселерометра необходимо подать на вывод VCC модуля напряжение +3,3 В. Измерительные каналы датчика подключаются к аналоговым выводам Arduino, например, "A0", "A1" и "A2". Это вся схема :)

Схема подключения акселерометра ADXL335 к Arduino
Схема подключения аналогового трёхосевого акселерометра ADXL335 к Arduino

3Калибровкааналогового акселерометра ADXL335

Arduino имеет 10-разрядный АЦП, а максимальное допустимое напряжение на выводе – 5 вольт. Измеренные напряжения кодируются битами, которые могут принимать только 2 значения – 0 или 1. Это значит, что весь диапазон измерений будет поделён на (1+1)10, т.е. на 1024 равных отрезка. Для того чтобы перевести снимаемые показания в вольты, нужно каждое измеренное на аналоговом входе значение поделить на 1024 (отрезка), а затем умножить на 5 (вольт).

Загрузим вот такой скетч в память Arduino. Будем считывать с аналоговых входов показания по трём каналам, преобразовывать их в напряжение и выводить в последовательный порт.

//определяем аналоговые пины:
const int xPin = A0; 
const int yPin = A1;
const int zPin = A2;

void setup() {
  //инициализируем послед. порт:
  Serial.begin(9600); 
}

void loop() {
  // считываем показания:
  int xRead = analogRead(xPin); 
  int yRead = analogRead(yPin);
  int zRead = analogRead(zPin);

  //Выводим показания в порт в Вольтах:
  Serial.print("x: ");
  Serial.print(xRead * 5 / 1024.0); 
  Serial.print(" | y: ");
  Serial.print(yRead * 5 / 1024.0);
  Serial.print(" | z: ");
  Serial.println(zRead * 5 / 1024.0);

  delay(100); //задержка 100 мс
}

Посмотрим, что же реально приходит с акселерометра на примере оси Z (см. последний столбец на иллюстрации). Когда датчик расположен горизонтально и смотрит вверх, приходят числа (2,03±0,01). Это должно соответствовать ускорению "1g" по оси Z и углу 0° согласно паспорту на ADXL335. Перевернём датчик. Приходят числа (1,69±0,01), что должно соответствовать "−1g" и углу 180°.

Калибровка аналогового акселерометра ADXL335
Калибровка аналогового акселерометра ADXL335

4Определение ускоренийпо трём осям акселерометра

Снимем значения с акселерометра при углах 90° и 270° и занесём в таблицу. Таблица показывает углы поворота акселерометра (столбец "A") и соответствующие им значения Zout в вольтах (столбец "B").

Определение ускорений по трём осям акселерометра ADXL335
Определение ускорений по трём осям акселерометра ADXL335

Для наглядности приведён график напряжений на выходе Zout в зависимости от угла поворота. Голубое поле – это область значений в спокойном состоянии (при ускорении 1g). Розовое поле на графике – это запас для того чтобы мы могли измерять ускорение до +3g и до −3g.

При угле поворота 90° на ось Z приходится нулевое ускорение. Т.е. значение 1,67 вольт – это условный ноль Z0. Тогда определим ускорение так: g = Zout – Z0 / Sz, здесь Zout – измеренное значение в милливольтах, Z0 – значение при нулевом ускорении в милливольтах, Sz – чувствительность датчика по оси Z, измеренная в мВ/g.

Чувствительность акселерометра приведена в паспорте и равна в среднем 300 мВ/g или 0,3 В/g, но вообще лучше провести калибровку акселерометра и вычислить значение чувствительности конкретно для вашего датчика по формуле: Sz = Z(0°) – Z(90°) В данном случае чувствительность акселерометра по оси Z = 2,03 – 1,68 = 0,35 В/g. Аналогично чувствительность нужно будет посчитать для осей X и Y.

В столбце "С" таблицы приводится расчётное ускорение при чувствительности, равной 350 мВ/g. Как видно, расчёты практически совпадают с номинальными величинами, которые даются на первом рисунке из паспорта на датчик ADXL335, т.е. наш датчик довольно точно показывает свою ориентацию в пространстве (я показал это просто для самопроверки, дальше это не пригодится).

5Определение углов поворота акселерометра

Вспомнив базовый курс школьной геометрии, выведем формулу для вычисления углов поворота акселерометра: angle_X = arctg[ √(Gz2 + Gy2) / Gx ]. Значения получаются в радианах. Чтобы перевести радианы в градусы, поделим результат на число π и умножим на 180°.

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

const int xPin = A0; //определяем аналоговые пины,
const int yPin = A1; //к которым подключим
const int zPin = A2; //три канала акселерометра

const float Vmax = 5.0; //макс. допустимое напряжение на аналоговом входе

const float x0 = 1.71; //значения по осям при нулевых "g";
const float y0 = 1.69; //эти значения вы должны определить
const float z0 = 1.68; //самостоятельно (см.шаг 4)

const float sens_x = 0.35; //чувствительность по осям в В/g;
const float sens_y = 0.35; //эти значения вы должны определить
const float sens_z = 0.35; //самостоятельно (см.шаг 4)

void setup() {
  Serial.begin(9600); //инициализация последовательного порта
}

void loop() {
  unsigned int value_x = analogRead(xPin); //считываем значения с акселерометра
  unsigned int value_y = analogRead(yPin);
  unsigned int value_z = analogRead(zPin);
  
  float Gx=(value_x*Vmax/1024.0 − x0)/sens_x; //определяем ускорения по осям 
  float Gy=(value_y*Vmax/1024.0 − y0)/sens_y;
  float Gz=(value_z*Vmax/1024.0 − z0)/sens_z;
  
  Serial.print("Gx:\t" + String(Gx)); //выводим ускорения в послед. порт  
  Serial.print("\t| Gy:\t" + String(Gy));
  Serial.println("\t| Gz:\t" + String(Gz));
  
  float angle_x = atan(sqrt(Gz*Gz + Gy*Gy) / Gx)*180 / PI; //ищем углы поворота
  float angle_y = atan(sqrt(Gx*Gx + Gz*Gz) / Gy)*180 / PI;
  float angle_z = atan(sqrt(Gx*Gx + Gy*Gy) / Gz)*180 / PI;
    
  Serial.print("x:\t" + String(round(angle_x))); //выводим углы поворота акселерометра
  Serial.print("o\t| y:\t" + String(round(angle_y)));
  Serial.println("o\t| z:\t" + String(round(angle_z)) + "o");
  Serial.println();
 
  delay(500);
}

При выводе в порт Serial.print() символ \t обозначает знак табуляции, чтобы столбцы были ровные, и значения располагались друг под другом. Символ + означает конкатенацию (объединение) нескольких строк. Оператор String() явно указывает компилятору, что численное значение нужно преобразовать в строку. Оператор round() округляет угол с точностью до 1°.

Подключение аналогового акселерометра ADXL335 к Arduino
Подключение аналогового акселерометра ADXL335 к Arduino с помощью макетной платы

Итак, мы с вами научились снимать и обрабатывать данные с аналогового акселерометра ADXL335 при помощи Arduino.

Полезный совет

Определите «нулевые» значения напряжений и чувствительности по осям X, Y и Z для вашего датчика с помощью скетча, описанного в разделе «Калибровка аналогового акселерометра ADXL335». Иначе углы и ускорения будут вычисляться со значительными ошибками.

Последнее изменениеВторник, 05 Январь 2016 16:43
(8 голосов)
Прочитано 7745 раз

Поделиться

Другие материалы в этой категории:

Как начать программировать Arduino »

Оставить комментарий

Убедитесь, что вы вводите (*) необходимую информацию, где нужно
HTML-коды запрещены