Как подключить цифровой акселерометр ADXL345 к Arduino
Для проекта нам понадобятся:
- Arduino UNO или иная совместимая плата;
- модуль GY-291 или аналогичный с цифровым акселерометром ADXL345;
- соединительные провода (рекомендую вот такой набор);
- макетная плата (breadboard);
- персональный компьютер со средой разработки Arduino IDE.
1Описание модуля GY-291 с акселерометром ADXL345
Акселерометр – это устройство, которое позволяет измерить динамическое и статическое ускорение по трём осям X, Y и Z. Благодаря статическому ускорению можно определить положение в пространстве (акселерометр как датчик поворота), а благодаря динамическому (движение или встряска) – направление ускорения.
Цифровой акселерометр ADXL345 – это 3-осевой акселерометр с высоким разрешением (13 бит) по осям с пределом до ±16g. Модуль обладает пониженным энергопотреблением и малыми размерами. Информационный обмен с модулем осуществляется по последовательным интерфейсам I2C или SPI (3- или 4-проводной).
Существует множество модулей для Arduino с акселерометром ADXL345. Модуль может выглядеть, например, так:

Показанный модуль имеет название GY-291. У модуля имеются следующие выводы:
| Вывод модуля | Назначение | Подключать к выводу Arduino | |
|---|---|---|---|
| SPI | I2C | ||
| GND | Земля | GND | GND |
| VCC | Питание | +3,3V | +3,3V |
| CS | Выбор ведомого интерфейса SPI | 10 | – |
| INT1 | Выход прерывания 1 (*) | – | – |
| INT2 | Выход прерывания 2 (*) | – | – |
| SDO | Данные от ведомого | 12 | – |
| SDA | Данные от мастера интерфейса SPI Шина данных интерфейса I2C | 11 | A4 |
| SCL | Шина тактирования | 13 | A5 |
(*) Работы с прерываниями ADXL345 касаться в этой статье не будем. Вот есть хорошая статья, в которой достаточно подробно описан вопрос работы с прерываниями.
В зависимости от выбранного интерфейса – SPI или I2C – подключение модуля будет соответствующим, как показано в таблице. Но в обоих случаях очень простым.
Рассмотрим структуру регистров микросхемы ADXL345:

Кроме того, нас интересует регистр управления питанием, т.к. он отвечает за режим работы устройства:

Как видим, бит D3 (Measure) переключает акселерометр в режим измерения.
2Работа с цифровым акселерометром ADXL345 по интерфейсу SPI
Акселерометр ADXL345 поддерживает 3- и 4-проводные варианты интерфейса SPI. Мы рассмотрим только 4-проводное подключение. Кроме того, акселерометр работает в режиме 3 интерфейса SPI (помните, мы уже обсуждали: CPOL=1, CPHA=1). Диаграмма, показывающая обмен с акселерометром ADXL345 по 4-проводному интерфейсу SPI:

Здесь бит MB – это признак того, что мы собираемся читать много байтов за раз (если бит установлен в 1). Для тестирования работы с SPI устройствами и быстрого освоения порядка обмена с ними я обычно использую отладочную плату с микросхемой FT2232H. Эта микросхема поддерживает множество режимов, в том числе I2C и SPI. Управление работой микросхемы FT2232H – с помощью программы SPI via FTDI, о которой я уже неоднократно рассказывал.
Подключим акселерометр к отладочной плате и прочитаем регистр DEVID, в котором хранится постоянное значение-идентификатор акселерометра ADXL345. Значение идентификатора должно быть 0xE5.

Не забудем перед чтением записать команду 0x80, которая укажет акселерометру, что мы собираемся читать, начиная с регистра по адресу 0x0 (см. диаграмму выше, рисунок 38 – SPI 4-Wire Read):

Видно, что в регистре содержится число 0xE5, которое и является значением идентификатора акселерометра ADXL345, согласно техническому описанию (datasheet). Вот как это выглядит на временной диаграмме:

Устройство отвечает, всё нормально. Теперь нам нужно перевести акселерометр в режим измерений. Для этого необходимо записать в регистр POWER_CTL (адрес регистра 0x2D) число 0x08 (установить бит Measure в HIGH). После этого можно начинать читать регистры с 0x32 по 0x37, в которых хранятся данные об ускорениях по трём осям. Сделаем это с помощью Arduino. Напишем такой скетч:
Скетч для чтения данных ADXL345 по SPI (разворачивается)
#include <SPI.h>
const byte READ = 0x80; // бит маркер чтения
const byte MB = 0x40; // бит MB (многобайтовая передача)
const int CS = 10; // пин выбора ведомого
void setup() {
Serial.begin(115200);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV32); // делитель частоты 500 кГц
SPI.setDataMode(SPI_MODE3); // задаём 3-ий режим SPI
byte id[1];
readRegister(0x00, 1, id); // читаем регистр DEVID
Serial.print("ID = ");
Serial.println(id[0], HEX);
writeRegister(0x2D, 0x08); // переводим ADXL345 в режим измерения
}
void loop() {
byte buff[6];
readRegister(0x32, 6, buff); // читаем значения по осям X, Y, Z
int x = ((int)buff[1] << 8) | buff[0];
int y = ((int)buff[3] << 8) | buff[2];
int z = ((int)buff[5] << 8) | buff[4];
Serial.print(x);
Serial.print("\t");
Serial.print(y);
Serial.print("\t");
Serial.println(z);
delay(10);
}
// записывает значение в регистр
void writeRegister(byte reg, byte value) {
digitalWrite(CS, LOW);
SPI.transfer(reg);
SPI.transfer(value);
digitalWrite(CS, HIGH);
}
// читает из регистра заданное число байтов
void readRegister(byte reg, int bytesToRead, byte *outBuff) {
digitalWrite(CS, LOW);
reg = reg | READ; // покажем акселерометру, что хотим из него читать
if (bytesToRead > 1) {
reg = reg | MB; // и читать хотим много байтов
}
SPI.transfer(reg); // записываем адрес регистра, с которого начинаем чтение
for (int i=0; i< bytesToRead; i++) {
outBuff[i] = SPI.transfer(0x00); // побайтно читаем ответ ADXL345
}
digitalWrite(CS, HIGH);
}
Вот так выглядит временная диаграмма работы этого скетча:

Ясно, почему первый байт передачи от Arduino при чтении значений ускорений по осям – число 0xF2? Это адрес первого регистра, с которого начинаем чтение (0x32), объединённый по ИЛИ с 0x80 – маркером чтения READ – и с 0x40 – маркером многобайтовой передачи MB: 0x32 OR 0x80 OR 0x40 = 0011_0010 OR 1000_0000 OR 0100_0000 = 1110_1101 = 0xF2
Что означают считанные значения? Этот вопрос рассматривается в последнем разделе статьи. Кроме того, существует ряд библиотек для Arduino, которые упрощают настройку и чтение данных с акселерометра, позволяя не думать о таких низкоуровневых вещах как регистры, биты и байты. Ссылки на библиотеки также приведены в конце статьи.
3Работа с цифровым акселерометром ADXL345 по интерфейсу I2C
Временная диаграмма информационного обмена с ADXL345 по интерфейсу I2C выглядит так:

Давайте перепишем скетч для Arduino, который будет делать всё то же самое, только с обменом по интерфейсу I2C:
Скетч для чтения данных ADXL345 по I2C (разворачивается)
#include <Wire.h>
const int adxl345 = 0x53; // I2C адрес ADXL345
void setup() {
Serial.begin(9600);
Wire.begin();
// запишем адрес регистра DEVID
Wire.beginTransmission(adxl345);
Wire.write(byte(0x00));
Wire.endTransmission();
// прочитаем регистр DEVID:
Wire.requestFrom(adxl345, 1);
while (Wire.available()) {
byte c = Wire.read();
Serial.print("ID = ");
Serial.println(c, HEX);
}
// переведём акселерометр в режим измерений
Wire.beginTransmission(adxl345);
Wire.write(byte(0x2D));
Wire.write(byte(0x08));
Wire.endTransmission();
}
void loop() {
// запишем адрес начала данных по осям X, Y и Z:
Wire.beginTransmission(adxl345);
Wire.write(byte(0x32));
Wire.endTransmission();
// прочитаем 6 байтов значений XYZ:
int i = 0;
byte xyz[6];
Wire.requestFrom(adxl345, 6);
while (Wire.available()) {
byte c = Wire.read();
xyz[i] = c;
i++;
}
// посчитаем и отобразим значения X, Y, Z:
int x = word(xyz[1], xyz[0]);
int y = word(xyz[3], xyz[2]);
int z = word(xyz[5], xyz[4]);
Serial.print(x);
Serial.print("\t");
Serial.print(y);
Serial.print("\t");
Serial.println(z);
delay(100);
}
Диаграмма чтения регистра DEVID цифрового акселерометра ADXL345 при обмене по последовательному интерфейсу I2C будет в этом случае такой:

Как видно, ADXL345 возвращает нам ожидаемое значение 0xE5. А вот так будет выглядеть диаграмма чтения регистров, в которых хранятся данные по осям XYZ:

Тут всё ещё проще, чем при работе с интерфейсом SPI.
4Разбор показаний цифрового акселерометра ADXL345
Посмотрите на фотографию ниже. На плате модуля нарисованы три оси: X, Y и Z. Они показывают направление осей акселерометра. Направления осей обусловлены расположением микросхемы ADXL345 на плате. В данном случае ось X акселерометра направлена горизонтально вправо, ось Z направлена горизонтально на нас, ось Y – вертикально вверх.

А вот что выводит наш скетч в монитор последовательного порта среды Arduino IDE (надо уточнить, что данный вывод наблюдается в режиме покоя – акселерометр неподвижно лежит на столе в положении, как на приведённом фото):

В трёх столбцах представлено значение статического ускорения, измеренное акселерометром по осям X, Y и Z, соответственно. В среднем столбце – показания оси Y – значения больше, чем в двух других. Эти значения даны в условных отсчётах, как они записаны в регистрах акселерометра. Акселерометр ADXL345 имеет несколько диапазонов измерений. Давайте посмотрим на сводную таблицу диапазонов и разрешений датчика акселерометра:

Напомню, что g – это ускорение свободного падения, численно равное примерно 9,81 метр в секунду за секунду (м/с2).
Диапазон по умолчанию – от −16g до +16g (размах 32g). Согласно таблице, на этот диапазон ускорений приходится 13 бит точности или 213 = 8192 отсчёта. Таким образом, на 1 отсчёт приходится ускорение 32g/8192 = 0,00390625g=0,00390625×9,81 ≈ 0,038 м/с2. Имея это в виду, получается, что в данном выводе скетча ускорение составляет:
| Ось акселерометра | Ускорение по оси, м/с2 |
|---|---|
| X | 0,76 |
| Y | 10,4 |
| Z | −0,12 |
Что ж, вполне логично. Ось Y направлена вертикально, т.е. вдоль вектора силы земного притяжения, и значение ускорения примерно равно константе g. Ускорения по осям X и Z, которые лежат в одной горизонтальной плоскости, примерно одинаковы и находятся около 0. Из-за кривизны стола, на котором стоит датчик, значения немного отличаются. Если бы я выровнял акселерометр по уровню, то его показания были бы более точные. В идеальном случае по оси Y должно быть ускорение 9,8 м/с2, а по осям X и Z – 0.
Кроме того, датчик ADXL345 имеет возможность тонкой настройки и калибровки. В данном примере мы этого не делали, а использовали акселерометр с заводскими настройками, как есть. Отсутствие калибровки также может вносить некоторые искажения в показания датчика. Рекомендую применять специальные библиотеки Arduino, которые упрощают взаимодействие с акселерометром ADXL345, в частности, позволяют проводить тонкую настройку.
Скачать библиотеку ADXL345
В архиве также лежит техническое описание (datasheet) на цифровой акселерометр ADXL345. Установка библиотеки производится путём копирования разархивированной папки с библиотекой в директорию libraries среды Arduino IDE.
- скачать библиотеку Arduino для акселерометра ADXL345 с Depositfiles.
Скачать вложения:
- Скачать библиотеку Arduino для акселерометра ADXL345 (3722 Скачиваний)
Поблагодарить автора:
Поделиться
Похожие материалы (по тегу)
Последнее от aave
2 комментарии
-
Dima 29.04.2020 13:50 КомментироватьДоброго день, интересует, как вы подключили несколько датчиков и к контроллеру?
-
aave1 29.04.2020 18:27 КомментироватьDima, здравствуйте!
Как SPI, так и I2C интерфейсы поддерживают режим "один ведущий - много ведомых". Вероятно, Вы имеете в виду это? К одному SPI master можно подключить несколько подчинённых устройств, активируется каждое из них по шине CS. Аналогично и I2C, с той лишь разницей, что у каждого ведомого есть свой адрес, и мы обращаемся к каждому устройству на шине по его уникальному адресу.





