Рубрики
Схемы на Arduino

Определение ориентации с помощью акселерометра ADXL345 и Arduino

В данной статье мы научимся измерять угол и отслеживать ориентацию с помощью платы Arduino и датчика акселерометра ADXL345. Приведены схема, программа и видео, демонстрирующее работу проекта (в конце статьи). Сначала мы рассмотрим как работает датчик и как считывать с него данные, а затем с помощью среды разработки Processing мы сделаем 3D-визуализацию ориентации акселерометра.

Ранее на нашем сайте мы рассматривали подключение акселерометров к плате Arduino в следующих статьях:

Необходимые компоненты

  1. Плата Arduino Nano (купить на AliExpress).
  2. Акселерометр (ADXL345) (купить на AliExpress).
  3. Соединительные провода.

Как работает акселерометр ADXL345

Датчик ADXL345 представляет собой 3-осевой акселерометр, который может измерять как статические, так и динамические силы ускорения. Сила земного притяжения является типичным примером статической силы, тогда как динамические силы могут быть вызваны вибрациями, различными движениями и т. д.

Единицей измерения ускорения является метр на секунду в квадрате (м/с^2). Однако датчики акселерометра обычно выражают измерения в «g» или силе тяжести. Один «g» — это величина силы земного притяжения, равная 9,8 метра в секунду в квадрате.

Итак, если у нас есть акселерометр, расположенный горизонтально, с его осью Z, направленной вверх, в противоположность гравитационной силе, выход датчика по оси Z будет 1g. С другой стороны, выходы X и Y будут равны нулю, потому что гравитационная сила перпендикулярна этим осям и никак на них не влияет.

Если мы перевернем датчик вверх дном, то выход по оси Z будет равен -1g. Это означает, что выходные данные датчика из-за его ориентации на гравитацию могут варьироваться от -1g до +1g.

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

Схема проекта

Схема подключения акселерометра ADXL345 к плате Arduino Nano приведена на следующем рисунке.

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

Исходный код программы (скетча)

Объяснение работы программы

Первым делом в программе подключим библиотеку Wire.h, которая используется для связи по протоколу I2C. Каждое устройство, использующее связь по протоколу I2C, имеет уникальный адрес I2C, и этот адрес можно найти в техническом описании датчика (даташит на ADXL345 ). После того, как мы определили  I2C адрес и инициализировали переменные для трех его выходов, в функции setup() нам сначала необходимо инициализировать библиотеку Wire, а затем установить акселерометр в режим измерения. Для этого, если мы снова взглянем на таблицу данных, представленную на следующем рисунке, мы увидим, что нам нужно установить бит D3 регистра POWER_CTL в состояние HIGH.

Таким образом, используя функцию beginTransmission(), мы сначала запускаем связь, затем с помощью функции write() мы сообщаем, к какому регистру мы хотим получить доступ, и потом снова с помощью функции write() мы устанавливаем бит D3 в состояние HIGH, записывая число 8 в десятичные числа, которые соответствуют установке бита D3 в в состояние HIGH.

После этого в функции loop() мы будем считывать данные с датчика. Данные для каждой оси хранятся в двух байтах или регистрах. Адреса этих регистров мы можем узнать из даташита на датчик.

Чтобы прочитать их все, мы начинаем с первого регистра и затем с помощью функции requestionFrom() считываем 6 регистров. Далее, используя функцию read(), мы считываем данные из каждого регистра, и, поскольку выходные данные представляют собой дополнения до двух, мы соответствующим образом комбинируем их, чтобы получить правильные значения.

Выходные значения датчика фактически зависят от выбранной чувствительности, которая может варьироваться от +-2g до +-16g. Чувствительность по умолчанию составляет +-2g, поэтому нам нужно разделить выходное значение на 256, чтобы получить значения от -1 до +1g. 256 LSB/g означает, что у нас есть 256 отсчетов на грамм.

В зависимости от используемого приложения мы можем выбрать соответствующую чувствительность. В нашем случае для отслеживания ориентации подойдет чувствительность +-2g, но для приложений, где нам необходимо определять более высокую силу ускорения, например внезапные движения, удары и т. д., целесообразно выбрать другие диапазоны чувствительности, используя регистр DATA_FORMAT и его биты D1 и D0.

Калибровка акселерометра ADXL345

Первоначальный запуск акселерометра показал что считываемые с него данные имеют определенную погрешность, которая была особенно сильной по его оси Z — в районе 0,1g.

Чтобы решить эту проблему, нам нужно откалибровать акселерометр, используя для этого 3 его регистра калибровки смещения. Для этого нам нужно расположить датчик горизонтально и распечатать значения RAW («сырые»), не деля их на 256.

Теперь мы можем заметить насколько отклоняются значения с выходов, в нашем случае выход Z был около 283. То есть ошибка составляет +27 единиц. Теперь нам нужно разделить это значение на 4, и это даст нам число, которое нам нужно записать в регистр смещения оси Z. И если после этого мы загрузим код в плату, то выход датчика по оси Z будет ровно 256 или 1 g, как и должно быть.

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

Как только мы закончим с калибровкой, теперь мы можем, наконец, рассчитать значения Roll и Pitch, или вращения вокруг оси X и вращение вокруг оси Y в градусах, используя следующие две формулы.

3D-визуализация работы акселерометра ADXL345

Теперь сделаем пример 3D-визуализации акселерометра.

Для этого мы используем тот же самый код, который отправляет значения Roll и Pitch через последовательный порт. Вот полный код Arduino:

Теперь в среде разработки Processing нам нужно получить эти значения и использовать их для поворота 3D-объекта, который мы будем создавать. Вот полный код processing для этого:

Описание работы этого кода: итак, здесь нам нужно включить последовательную библиотеку, задать последовательный порт и скорость передачи данных, которая должна соответствовать скорости передачи скетча, загруженного в плату Arduino. Затем мы считываем поступающие данные и помещаем их в соответствующие переменные крена и тангажа. В основном цикле отрисовки мы используем эти значения для поворота 3D-объекта, и в данном случае это простое поле с определенным цветом и текстом на нем.

Если мы запустим скетч, появится 3D-объект, который будет отслеживать ориентацию датчика акселерометра. Здесь мы можем заметить, что объект на самом деле немного шатается, потому что акселерометр улавливает не только гравитационную силу, но и небольшие колебания, создаваемые движениями нашей руки. Чтобы получить более плавный результат, мы можем использовать простой фильтр нижних частот. Автор проекта реализовал в коде Arduino следующий фильтр, который берет 94% предыдущего состояния и добавляет 6% текущего состояния или угла.

С помощью этого фильтра мы можем заметить, что объект теперь движется намного более плавно, но есть и побочный эффект — более медленная реакция. Мы также можем заметить, что нам не хватает Yaw или вращения вокруг оси Z. Используя только данные 3-осевого акселерометра, мы не можем рассчитать рысканье, к сожалению.

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

Таким образом, для решения этой задачи мы можем либо использовать акселерометр ADXL345 в сочетании с гироскопом гироскопа, либо использовать MPU6050, который сочетает функции 3-осевого акселерометра и 3-осевого гироскопа, интегрированные в один чип.

Видео, демонстрирующее работу проекта

Источник статьи

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *