Blog

Шаг 1. Компоненты для подключения акселерометра к Arduino

Для проекта понадобятся несколько компонентов:

Микроконтроллер Arduino UNO R3

МК создан с использованием материалов контроллера ATmega328:

  1. цифровые входы и выходы в количестве 14 штук, причем половина приходится на ШИМ-выходы;
  2. аналогичные входы, количество – 6 штук;
  3. резонатор на основе кварца, мощностью 16 МГц;
  4. встроен usb-вход;
  5. контакт для подключения питания;
  6. на МК располагается кнопка, с помощью которой возможен сброс данных и кода;
  7. контакт для программирования данных, находящихся внутри схемы, именуемый ICSP.

Старт работы начинается с подачи электрического питания в плату. Пользователь подключает к плате со схемой блок питания или зарядное устройство. Также процедура осуществляется с помощью usb-кабеля, который подключен к компьютеру и микроконтроллеру. Для разработки программы понадобится бесплатная среда программирования – Arduino IDE.

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

Язык, на котором программируется код, Wiring максимально приближен к популярному среди программистов языку – C++. Кроме того МК поддерживает версии для осей Виндовс, Мак ОС и Линукс

Пользователь создает в бесплатной среде код, затем его компилирует и загружает проработанную программу в пространство памяти в Ардуино. Язык, на котором программируется код, Wiring максимально приближен к популярному среди программистов языку – C++. Кроме того МК поддерживает версии для осей Виндовс, Мак ОС и Линукс.

Модуль датчика для гироскопа акселерометра на Аrduino с 3 осями – GY-521 (MPU-6050)

В основе компонента лежит микросхема MPU-6050. В комплект входят 2 предмета – гироскоп и акселерометр. Данные устройства перед конструированием обрабатываются и затем переносятся прямиком в микроконтроллер через интерфейс

Модуль датчика помогает определять место и перемещение инструмента в пространстве. Измеряются дифферент и углы крена посредством вектора силы тяжести и скорости в процессе вращения. Также включена функция измерения температурного режима. Перемещение определяется линейным ускорением и угловой скоростью. Полная картина рисуется по 3 осям.

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

Макетная плата, предназначенная для прототипирования

Отладка – неотъемлемая часть построения электронных схем. Макетная плата незаменима для конструкции электронной аппаратуры. Ранее в изобретательстве использовали традиционные макетные платы, но сейчас широко распространены макетные платы, которые удобны тем, что не требуют дополнительных спаек.

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

Материал для изготовления беспаечных макетных плат – пластик. Кроме того, все контакты надежно скреплены к плате, поэтому частые переключения не испортят элемент.

Соединительные провода папа-папа

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

Объяснение программы для Arduino

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Вначале в программе подключим библиотеку для работы с ЖК дисплеем по протоколу I2C. Для работы с акселерометром ADXL335 не требуется никакой библиотеки поскольку у него аналоговый выход.

Arduino

#include <LiquidCrystal_I2C.h>

1 #include <LiquidCrystal_I2C.h>

После этого объявим контакты платы Arduino, к которым подключен акселерометр.

Arduino

const int xpin = A1;
const int ypin = A2;
const int zpin = A3;

1
2
3

constintxpin=A1;

constintypin=A2;

constintzpin=A3;

Зададим границу (граничное значение) для срабатывания счетчика шагов – с ней будет сравниваться рассчитанный вектор ускорения.

Arduino

float threshold = 6;

1 floatthreshold=6;

Внутри функции void setup будем запускать функцию калибровки.

Arduino

calibrate();

1 calibrate();

Внутри функции void loop мы будем считывать значения осей X, Y и Z на протяжении 100 отсчетов.

Arduino

for (int a = 0; a < 100; a++)
{
xaccl = float(analogRead(xpin) — 345);
delay(1);
yaccl = float(analogRead(ypin) — 346);
delay(1);
zaccl = float(analogRead(zpin) — 416);
delay(1);

1
2
3
4
5
6
7
8

for(inta=;a<100;a++)

{

xaccla=float(analogRead(xpin)-345);

delay(1);

yaccla=float(analogRead(ypin)-346);

delay(1);

zaccla=float(analogRead(zpin)-416);

delay(1);

После этого мы будем рассчитывать суммарный вектор ускорения при помощи вычисления квадратного корня из суммы квадратов значений осей X, Y и Z.

Arduino

totvect = sqrt(((xaccl — xavg) * (xaccl — xavg)) + ((yaccl — yavg) * (yaccl — yavg)) + ((zval — zavg) * (zval — zavg)));

1 totvecta=sqrt(((xaccla-xavg)*(xaccla-xavg))+((yaccla-yavg)*(yaccla-yavg))+((zvala-zavg)*(zvala-zavg)));

Затем мы будем рассчитывать среднее от максимального и минимального значений вектора ускорения.

Arduino

totave = (totvect + totvect) / 2 ;

1 totavea=(totvecta+totvecta-1)2;

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

Arduino

if (totave > threshold && flag == 0)
{
steps = steps + 1;
flag = 1; }

1
2
3
4

if(totavea>threshold&&flag==)

{

steps=steps+1;

flag=1;}

Если среднее ускорение больше граничного значения, но флаг уже установлен, то не делаем ничего.

Arduino

else if (totave > threshold && flag == 1)
{
// Don’t Count
}

1
2
3
4

elseif(totavea>threshold&&flag==1)

{

// Don’t Count

}

Если среднее ускорение меньше граничного значения и флаг установлен, то сбрасываем флаг.

Arduino

if (totave < threshold && flag == 1)
{
flag = 0;
}

1
2
3
4

if(totavea<threshold&&flag==1)

{

flag=;

}

Выводим подсчитанное значение шагов в окно монитора последовательной связи и на экран ЖК дисплея.

Arduino

Serial.println(steps );
lcd.print(«Steps: «);
lcd.print(steps);

1
2
3

Serial.println(steps);

lcd.print(«Steps: «);

lcd.print(steps);

Программы

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

Мы воспользуемся готовой библиотекой для Arduino MPU 6050, которую написал Джефф Роуберг.

В целом, многие поступают и другим путем, правда далеко не все умеют программировать на С++, поэтому перед пользователем, который хочет написать программу для работы с гироскопом, открывается два пути:

  1. Найти уже готовый шаблон или библиотеку. Для этого потребуется всего пара секунд и подключение к интернету, но не стоит забывать, что готовые решения пишутся, зачастую, столь же неопытными инженерами. Поэтому, по возможности, проверяйте, насколько качественный код вы скачиваете. Смотрите отзывы о библиотеке, если есть такая возможность, и старайтесь скачивать их на зарубежных форумах. Там и выбор будет больше, и куда выше вероятность найти действительно качественную библиотеку.
  2. Написать функции и методы для работы системы своими силами. Этот вариант подойдёт лишь тем, кто ранее имел дело с языком С++ и понимает все нюансы работы с Ардуино. Все необходимые вспомогательные библиотеки можно скачать в интернете, а всё остальное вы можете подогнать под свои нужды. Такой способ идеально подходит для тех, кто хочет реализовать собственный проект, не имеющий аналогов. Ведь в таком случае найти заготовленный код под него будет крайне сложно, даже если быть готовым править большую его часть.

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

Нужно распаковать/извлечь эту библиотеку, взять папку с именем «MPU6050» и поместить ее в папку «library» в Arduino. Для этого перейдите в место, где вы установили Arduino (Arduino -> libraries) и вставьте свою папку в папку библиотек. Возможно, вам также придется сделать то же самое, чтобы установить библиотеку I2Cdev, если у вас еще нет ее на вашем Ардуино. Для её установки выполните ту же процедуру, что и выше. Вы можете скачать I2Cdev на нашем сайте по этой ссылке.

Если вы всё сделали правильно, при открытии IDE Arduino вы можете увидеть «MPU6050» в:

Файл -> Примеры.

Затем откройте пример программы из меню:

Файл -> Примеры -> MPU6050 -> Примеры -> MPU6050_DMP6.

Затем вы должны загрузить этот код в свой Ардуино. После загрузки кода откройте последовательный монитор и установите скорость передачи в бодах как 115200. Затем проверьте, видите ли вы что-то вроде «Инициализация устройств I2C . » («Initializing I2C devices . «) на последовательном мониторе.

Если вы этого не сделаете, просто нажмите кнопку сброса. Теперь вы увидите строку с надписью «Отправить символы, чтобы начать программирование и демо DMP» («Send any character to begin DMP programming and demo»). Просто введите любой символ на последовательном мониторе и отправьте его, и вы должны начать видеть значения поступающие с MPU 6050.

Также можно, например, воспользоваться скетчем ниже, который пересчитывает координату X и Y и выводит в консоль (монитор последовательного порта):

Когда X и Y равны 180 — гироскоп в горизонтальной плоскости:

Вот вы определились с выбором и уже написали всё необходимое ПО, пришла пора его протестировать. Для этого, естественно, необходимо собрать всё вместе.

Высокотемпературные и динамические среды

До появления акселерометров, рассчитанных на эксплуатацию при высокой температуре или в жестких условиях окружающей среды, некоторые разработчики вынуждены были использовать микросхемы со стандартным температурным диапазоном, выходя за пределы указанных в документации характеристик. То есть конечный пользователь должен был взять на себя ответственность и риски, связанные с аттестацией компонента для работы при повышенных температурах, что дорого и требует много времени. Известно, что герметичные корпуса весьма надежны при повышенных температурах и обеспечивают защиту от влаги и загрязнений, вызывающих коррозию. Analog Devices предлагает ряд компонентов в герметичных корпусах, характеризующихся повышенной стабильностью и высокой производительностью в широком диапазоне температур. Компания провела значительную работу по изучению производительности компонентов в пластиковых корпусах при повышенных температурах, в частности оценивалась способность выводных рамок и выводов микросхем выдерживать высокотемпературные процессы пайки и обеспечивать надежное крепление, способное противостоять сильным ударам и вибрации. В результате Analog Devices предлагает 18 акселерометров, функционирующих в диапазоне температур –40…+125 °C, среди которых можно назвать ADXL206, ADXL354/ADXL355/ADXL356/ADXL357, ADXL1001/ADXL1002, ADIS16227/ADIS16228 и ADIS16209. Большинство конкурентов не предлагают емкостные МЭМС-акселерометры, способные работать в указанных температурных пределах или в жестких условиях окружающей среды — например, в составе тяжелого промышленного оборудования или при бурении и разведке скважин.

Выполнение измерений угла наклона в очень жестких условиях окружающей среды с температурой выше +125 °C — задача чрезвычайно сложная. ADXL206 представляет собой высокоточный (точность измерения угла наклона ±0,06°) малопотребляющий МЭМС-акселерометр, предназначенный для приложений с высокотемпературными и суровыми средами, таких как бурение и разведка скважин. Этот компонент имеет керамический корпус размером 13×8×2 мм с двумя рядами расположенных по бокам выводов, который способен функционировать в температурном диапазоне −40…+175 °C с ухудшением характеристик после +175 °C и 100%-ной восстановимостью при возобновлении работы при температурах ниже +175 °C.

Для измерения угла наклона в динамических средах, где присутствует вибрация, например в сельскохозяйственной технике или беспилотных летательных аппаратах, требуются акселерометры с более широким диапазоном измерения ускорений, в частности ADXL356/ADXL357. Выполнение измерений в ограниченном диапазоне может привести к отсечке результирующего значения, что вызывает дополнительное смещение к выходному сигналу. Отсечка может возникнуть из-за того, что ось измерения присутствует в гравитационном поле 1 g, или из-за ударов с быстрым временем нарастания и медленным затуханием. При измерениях в более широком диапазоне величина отсечки сокращается, что уменьшает смещение, это в свою очередь повышает точность определения угла наклона в динамических приложениях.

На рис. 6 показаны результаты измерения в ограниченном диапазоне ускорений по оси Z акселерометра ADXL356, причем гравитационное поле 1 g уже присутствует в этом диапазоне измерений.

Рис. 6. Ошибка VRE акселерометра ADXL356, смещение по оси Z от 1 g, диапазон измеряемых ускорений ±10 g, ориентация по оси Z = 1 g

На рис. 7 даны те же измерения, но диапазон расширен с ±10 до ±40 g. Эти графики четко демонстрируют, что смещение, вызванное отсечкой, значительно уменьшается за счет расширения диапазона измеряемых ускорений акселерометра.

Рис. 7. Ошибка VRE акселерометра ADXL356, смещение по оси Z от 1 g, диапазон измеряемых ускорений ±40 g, ориентация по оси Z = 1 g

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

2Работа с цифровым акселерометром ADXL345 по интерфейсу SPI

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

Работа с ADXL345 по SPI

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

Подключим акселерометр к отладочной плате и прочитаем регистр DEVID, в котором хранится постоянное значение-идентификатор акселерометра ADXL345. Значение идентификатора должно быть 0xE5.

ADXL345 соединён с отладочной платой на FT2232H

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

Чтение регистра ID акселерометра ADXL345 по SPI

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

Временная диаграмма чтения регистра ID акселерометра ADXL345 по SPI

Устройство отвечает, всё нормально. Теперь нам нужно перевести акселерометр в режим измерений. Для этого необходимо записать в регистр 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;
  readRegister(0x00, 1, id); // читаем регистр DEVID
  Serial.print("ID = ");
  Serial.println(id, HEX);
  
  writeRegister(0x2D, 0x08); // переводим ADXL345 в режим измерения
}

void loop() {
  byte buff;
  readRegister(0x32, 6, buff); // читаем значения по осям X, Y, Z
  
  int x = ((int)buff }

// записывает значение в регистр
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}

Вот так выглядит временная диаграмма работы этого скетча:

Временная диаграмма чтения значений по осям X, Y, Z акселерометра ADXL345

Ясно, почему первый байт передачи от Arduino при чтении значений ускорений по осям – число 0xF2? Это адрес первого регистра, с которого начинаем чтение (0x32), объединённый по ИЛИ с 0x80 – маркером чтения READ – и с 0x40 – маркером многобайтовой передачи MB: 0x32 OR 0x80 OR 0x40 = 0011_0010 OR 1000_0000 OR 0100_0000 = 1110_1101 = 0xF2

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

Скетч для акселерометра ADXL345

Ниже приведен код для чтения данных акселерометра ADXL345:

#include <Wire.h>  // подключение библиотеки Wire
int ADXL345 = 0x53; // Адрес I2C датчика ADXL345
float X_out, Y_out, Z_out;  // Выходы

void setup() {
  Serial.begin(9600);
  Wire.begin(); // Инициализация библиотеки Wire 
  // Установите ADXL345 в режим измерения
  Wire.beginTransmission(ADXL345); // Начать общение с устройством 
  Wire.write(0x2D); // работа с регистром  POWER_CTL  - 0x2D
  // Включить измерение
  Wire.write(8); // (8dec -> 0000 1000 двоичный) Бит D3 High для разрешения измерения
  Wire.endTransmission();
  delay(10);
}

void loop() {
// === Считать данные акселерометра === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Начать с регистра 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Чтение всех 6 регистров, значение каждой оси сохраняется в 2 регистрах
  X_out = ( Wire.read()| Wire.read() << 8); // Значение по оси X
  X_out = X_out/256; //Для диапазона + -2g нам нужно разделить необработанные значения на 256 в соответствии с datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Значение по оси Y
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Значение по оси Z
  Z_out = Z_out/256;

  Serial.print("Xa= ");
  Serial.print(X_out);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  Serial.print("   Za= ");
  Serial.println(Z_out);
}

Описание: Итак, сначала нам нужно подключить библиотеку Wire.h, которая используется для связи по I2C. Каждое устройство, использующее I2C связь, имеет уникальный I2C адрес, и этот адрес можно найти в datasheet на ADXL345.

Итак, после того как мы определили адрес и переменные для трех выходов (X, Y, Z), в функции setup() нам нужно инициализировать библиотеку Wire, а затем перевести акселерометр в режим измерения. Для этого, если мы еще раз взглянем в datasheet, мы увидим, что нам нужно установить бит D3 в регистре POWER_CTL в HIGH.

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

// Установите ADXL345 в режим измерения
Wire.beginTransmission(ADXL345); // Начать общение с устройством 
Wire.write(0x2D); // работа с регистром  POWER_CTL  - 0x2D
// Включить измерение
Wire.write(8); // (8dec -> 0000 1000 двоичный) Бит D3 High для разрешения измерения
Wire.endTransmission();

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

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

// === Считать данные акселерометра === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Начать с регистра 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Чтение всех 6 регистров, значение каждой оси сохраняется в 2 регистрах
  X_out = ( Wire.read()| Wire.read() << 8); // Значение по оси X
  X_out = X_out/256; //Для диапазона + -2g нам нужно разделить необработанные значения на 256 в соответствии с datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Значение по оси Y
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Значение по оси Z
  Z_out = Z_out/256;

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

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

How ADXL345 Accelerometer Works

To begin with, let’s take a look how the ADXL345 sensor works. This is a 3-axis accelerometer which can measure both static and dynamic forces of acceleration. The earth gravitational force is a typical example of static force, while dynamic forces can be caused by vibrations, movements and so on.

The unit of measurement for acceleration is meter per second squared (m/s^2). However, accelerometer sensors usually express the measurements in “g” or gravity. One “g” is the value of the earth gravitational force which is equal to 9.8 meters per second squared.

So, if we have an accelerometer positioned flat, with its Z-axis pointing upwards, opposite to the gravitational force, the Z-axis output of the sensor will be 1g. On the other hand, the X and Y outputs will be zero, because the gravitational force is perpendicular to these axes and doesn’t affect them at all.

If we flip the sensor upside down, then the Z-axis output will be -1 g. This means that the outputs of the sensor due to its orientation to gravity can vary from -1g to +1g.

So according to this data and using some trigonometry math, we can calculate the angle at which the sensor is positioned.

Why not ±90°?

Why can’t the ADXL345 accelerometer indicate ±90°?

If you run the program below you will see that the accelerometer is
extremely good at indicating tilt at low angles (on a flat surface) to
about 70°, but does not reach ±90°. In fact it can’t seem to reach that magic number ±90°!

At first, I thought there was something wrong with the accelerometer
since no one seems to talk about this. Why should it not be possible to
measure all angles?

If you think about holding a piece of wood — the maximum force on it
is when you hold it horizontally. The more you point it upwards, to the
vertical position, the less gravity can affect it, hence — the
accelerometer becomes less sensitive.

So it turns out that the sensitivity of the accelerometer decreases with
increasing angle and follows a near sinusoidal response, and accuracy decreases the closer you get to ±90° of tilt.

«The sensor is a polysilicon surface-micromachined structure built on
top of a silicon wafer. Polysilicon springs suspend the structure over
the surface of the wafer and provide a resistance against forces due to
applied acceleration.» 

You can imagine the sensor as a beam suspended on springs, with the
capacitance between the beam and the support base giving the
acceleration measurement. When the beam is perpendicular to the
acceleration field small tilt changes will have a large effect as gravity
acts over a larger area.

As the beam tilts vertically, the sensor becomes
less sensitive (interacting with the gravity vector less) until, at full
vertical orientation, it can not return a reading since the gravity
vector has no effect on the beam.

There is a very good discussion of accelerometer sensitivity in Analogue Devices Application note AN-1057 by C Fisher here. The following diagram is from that application note:

The diagram shows that around 0° ~ 23° tilt you only need a
sensitivity of 16mg/LSB to resolve 1° steps, and around 60° tilt you need 8mg, and around
80° you need 4mg.  This is why the ADXl345 can not display 90° as
its sensitivity is too coarse to resolve tilt at that angle (3.8mg). So
the ADXL345 is good for tilt up to about ±80°. This is for the case
where you want to resolve tilt measurement to within 1°.

TIP: Increase resolution by oversampling to resolve smaller angles.

Акселерометр ADXL335

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

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

На следующем рисунке показан внешний вид передней и задней частей акселерометра.

Назначение контактов акселерометра ADXL335:Vcc – контакт для подачи напряжения постоянного тока 5 В.X-OUT – выход акселерометра по оси x.Y-OUT – выход акселерометра по оси y.Z-OUT – выход акселерометра по оси z.GND – общий провод (земля).ST – этот контакт используется для установки чувствительности датчика.

На нашем сайте вы можете посмотреть следующие проекты с использованием акселерометра ADXL335:

  • игра в Ping Pong с использованием Arduino и акселерометра;
  • робот на Arduino управляемый с помощью жестов рук и акселерометра;
  • система предупреждения об авариях автомобилей с использованием Arduino, GPS и GSM.

Таблица значений, возвращаемых датчиками

Тип датчика Количество значений Содержание значений Примечание
TYPE_ACCELEROMETER 3 value: ось X (поперечная)value: ось Y (продольная)value: ось Z (вертикальная) Ускорение (м/с2) по трём осям.Константы SensorManager.GRAVITY_*
TYPE_GRAVITY 3 value: ось X (поперечная)value: ось Y (продольная)value: ось Z (вертикальная) Сила тяжести (м/с2) по трём осям.Константы SensorManager.GRAVITY_*
TYPE_RELATIVE_HUMIDITY 1 value:относительная влажность Относительная влажность в процентах (%)
TYPE_LINEAR_ACCELERATION 3 value: ось X (поперечная)value: ось Y (продольная)value: ось Z (вертикальная) Линейное ускорение (м/с2) по трём осям без учёта силы тяжести
TYPE_GYROSCOPE 3 value: ось Xvalue:ось Yvalue: ось Z Скорость вращения (рад/с) по трём осям
TYPE_ROTATION_VECTOR 4 values: x*sin(q/2)values: y*sin(q/2)values: z*sin(q/2)values: cos(q/2) Положение устройства в пространстве.Описывается в виде угла поворота относительно оси в градусах
TYPE_MAGNETIC_FIELD 3 value: ось X (поперечная)value: ось Y (продольная)value: ось Z (вертикальная) Внешнее магнитное поле (мкТл)
TYPE_LIGHT 1 value: освещённость Внешняя освещённость (лк).Константы SensorManager.LIGHT_*
TYPE_PRESSURE 1 value: атм.давление Атмосферное давление (мбар)
TYPE_PROXIMITY 1 value: расстояние Расстояние до цели
TYPE_AMBIENT_TEMPERATURE 1 value: температура Температура воздуха в градусах по Цельсию
TYPE_POSE_6DOF 15 см. документацию
TYPE_STATIONARY_DETECT 1 value 5 секунд неподвижен
TYPE_MOTION_DETECT 1 value В движении за последние 5 секунд
TYPE_HEART_BEAT 1 value

Печать корпуса и сборка

Возьмите скользящие контакты и поместите его в верхнюю часть корпуса. Убедитесь, что вращающаяся часть кольца находится на верхней стороне корпуса, чтобы она вращалась одновременно с диском. Теперь установите шаговый мотор, который фиксируется к корпусу двумя 3M винтами и гайкам. Крышка готова:

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

Теперь пропускаем провода от скользящих контактов через отверстие вращающегося диска:

После чего берём датчик и припаиваем к нему 4 провода (+5V, GND, SCL и SDA) от скользящих контактов:

С помощью двух болтов М3 закрепляем модуль дальномера на корпусе вращающегося диска:

Если у вас модуль с другим расстоянием между крепёжными отверстиями, модуль можно закрепить только одним болтом. Если крепёжных отверстий совсем нет, модуль можно приклеить (двустороння липкая лента, термоклеем с помощью клеевого пистолета и т.д.).

Когда датчик будет закреплён, вращающийся диск надевается на подшипник:

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

Магнит служит для того, чтобы на него на него срабатывал датчик Холла и в этот момент в коде происходит установка переменной «угол» в некоторое значение. Если магнит по размерам позволяет наклеить его по центру под датчиком, это будет самый лучший вариант, т.к. при срабатывании переменной «угол» нужно будет присвоить значение 0. Если нет, магнит можно наклеить возле датчика. Тогда переменной «угол» нужно будет присвоить не 0, а соответствующее значение (на какой угол относительно магнита повёрнут датчик). Если магнит находится с противоположной стороны, нужно присвоить 180. Если угол составляет 20 градусам (на фото выше угол немного больше):

Тогда переменной «угол» нужно присвоить 20 и т.д.

На макетную плату по схеме, приведенной ранее, запаиваем конденсатор, драйвер мотора, 10K резистор, датчик Холла, провода от Arduino и стабилизатора питания:

Всё припаяно, теперь закрепляем (двусторонней липкой лентой, клеем, термоклеем и т.д.) Arduino Nano внутри корпуса и наш лидар почти готов:

Осталось вплавить в нижнюю крышку корпуса три вставные гайки, затем прикрутить крышку корпуса, надеть на шкив пасик и можно переходить к программированию и экспериментам.

Преобразование показаний ADXL335 в ускорение (g)

Следующий фрагмент кода является наиболее важной частью программы. Он преобразует аналоговые выходные напряжения датчика в ускорение свободного падения (g)

Встроенная в IDE функция выполняет фактическое преобразование. Таким образом, когда мы вызываем , значение будет преобразовываться в -3000, значение – в 3000, а значения между ними – в промежуточные значения.

Значения -3000 и 3000 не являются произвольными. Они фактически представляют ускорение свободного падения (в милли-g, которое составляет 1/1000 g), измеренное датчиком, то есть ± 3g (от -3000 до 3000 милли-g).

Например,

  • Когда датчик выдает 0 вольт на оси x, то есть = 0, функция возвращает -3000, представляющие -3g.
  • Когда датчик выдает 3,3 вольта по оси x, то есть = 1023, функция вернет 3000, представляющие +3g.
  • Когда датчик выдает 1,65 В на оси x, т.е. = 511, функция вернет 0, представляющий 0g.

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

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

На следующих рисунках показан вывод данных акселерометра в монитор последовательного порта в разных положениях.

Рисунок 8 – Вывод акселерометра ADXL335 на оси X —Рисунок 9 – Вывод акселерометра ADXL335 на оси Y +Рисунок 10 – Вывод акселерометра ADXL335 на X +Рисунок 11 – Вывод акселерометра ADXL335 на оси Y —Рисунок 12 – Вывод акселерометра ADXL335 на оси Z +Рисунок 13 – Вывод акселерометра ADXL335 на оси Z —

Код Arduino – чтение показаний акселерометра ADXL335

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

Скетч начинается с объявления аналоговых входных выводов Arduino, к которым подключены выходные выводы X, Y и Z датчика.

Далее мы определяем минимальные и максимальные значения, которые Arduino собирается предоставить. Поскольку плата Arduino содержит 10-разрядный аналого-цифровой преобразователь, она отобразит выходные напряжения датчика в диапазоне от 0 до 3,3 В в целочисленные значения в диапазоне от 0 до 1023. Именно поэтому для установлено значение 0, а для установлено значение 1023.

Переменная указывает Arduino брать 10 отсчетов каждого преобразования, чтобы получить более точные результаты.

В функции мы должны установить аналоговое опорное напряжение на , так как мы подключили 3,3 В к выводу AREF на Arduino. Это делается путем вызова .

Кроме этого, мы инициализируем здесь и последовательную связь с компьютером.

ПРЕДУПРЕЖДЕНИЕ

Если вы не вызовите , вы закоротите вместе активный источник опорного напряжения (внутренний) и вывод AREF, что, возможно, приведет к повреждению микроконтроллера на плате Arduino..

В функции мы считываем аналоговые выходы датчика каждые 200 мс. Вместо вызова функции мы вызываем пользовательскую функцию . Эта функция просто берет 10 выборок АЦП и возвращает среднее значение.

What is accelerometer anyway?

Short answer, a device that measures the acceleration in a specific direction from gravity and movement. In our case ADXL345 is a 3 axis accel, basically it can measure acceleration in 3 directions simultaneously. On Earth, accelerometer when placed on a flat surface will always measure 9.81m/s2.In most cases you’ll find that acceleration is measured in g-forces, which is basically acceleration felt as weight. Obviously at Earth surface and in restful condition we experience 1G.

In most cases the acceleration is used as a vector quantity, which can be used to sense the orientation of the device, more precisely pitch and roll. Because when you turn the device, the 1G component is distributed among those 3 axes. With simple vector math we can calculate the angle of the device.  

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Семинар по технике
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: