Как подключить цифровой акселерометр 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.
Download attachments:
- Скачать библиотеку Arduino для акселерометра ADXL345 (2839 Downloads)
Поблагодарить автора:
Поделиться
Related items
2 comments
-
Dima Среда, 29 Апрель 2020 13:50 Ссылка на комментарий
Доброго день, интересует, как вы подключили несколько датчиков и к контроллеру?
-
aave1 Среда, 29 Апрель 2020 18:27 Ссылка на комментарий
Dima, здравствуйте!
Как SPI, так и I2C интерфейсы поддерживают режим "один ведущий - много ведомых". Вероятно, Вы имеете в виду это? К одному SPI master можно подключить несколько подчинённых устройств, активируется каждое из них по шине CS. Аналогично и I2C, с той лишь разницей, что у каждого ведомого есть свой адрес, и мы обращаемся к каждому устройству на шине по его уникальному адресу.