Датчики «ардуино»: описание, характеристики, подключение, отзывы

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

Полный текст программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты. Поскольку здесь используется программирование микроконтроллера ATtiny85 с помощью Arduino IDE, то для этого можно использовать USB программатор для ATtiny85 на основе загрузчика Digispark.

В коде программы мы будем использовать библиотеки TinyWireM.h и TinyOzOLED.h. Библиотеку TinyWireM можно непосредственно скачать из менеджера библиотек (Library Manager) Arduino IDE и установить ее оттуда же. Для этого откройте в Arduino IDE пункт меню Sketch < Include Library < Manage Libraries. После этого запустите поиск TinyWireM.h и установите ее. Эта библиотека написана компанией Adafruit.

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

Arduino

#include «TinyWireM.h»
#include «TinyOzOLED.h»

1
2

#include «TinyWireM.h»
#include «TinyOzOLED.h»

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

Arduino

intaccelX, accelY, accelZ;

1 intaccelX,accelY,accelZ;

Внутри функции setup() мы инициализируем связь по протоколу I2C, сбросим датчик MPU6050 при помощи регистра управления питанием. Также мы зададим ориентацию OLED дисплея и очистим его экран, а также введем адрес регистра для значений акселерометра и гироскопа.

Arduino

TinyWireM.begin();
OzOled.init();
OzOled.clearDisplay();
OzOled.setNormalDisplay();
OzOled.sendCommand(0xA1);
OzOled.sendCommand(0xC8);
TinyWireM.beginTransmission(mpu);
TinyWireM.write(0x6B);
TinyWireM.write(0b00000000);
TinyWireM.write(0x1B);

1
2
3
4
5
6
7
8
9
10

TinyWireM.begin();

OzOled.init();

OzOled.clearDisplay();

OzOled.setNormalDisplay();

OzOled.sendCommand(0xA1);

OzOled.sendCommand(0xC8);

TinyWireM.beginTransmission(mpu);

TinyWireM.write(0x6B);

TinyWireM.write(0b00000000);

TinyWireM.write(0x1B);

В функции getAccel() мы начнем считывание данных акселерометра. Данные для каждой оси сохраняются в двух байтах (верхний и нижний) регистра. Чтобы считать их все начните с первого регистра, а затем используя функцию requiestFrom() мы считаем все 6 регистров для осей X, Y, Z. Затем мы считываем данные из каждого регистра, и поскольку значение каждой оси состоит из двух слагаемых, мы комбинируем (объединяем) их соответствующим образом чтобы получить полные значения данных с акселерометра.

Arduino

voidgetAccel() {
TinyWireM.beginTransmission(mpu);
TinyWireM.write(0x3B);
TinyWireM.endTransmission();
TinyWireM.requestFrom(mpu, 6);
accelX = TinyWireM.read() << 8|TinyWireM.read();
accelY = TinyWireM.read() << 8|TinyWireM.read();
accelZ = TinyWireM.read() << 8|TinyWireM.read();
}

1
2
3
4
5
6
7
8
9

voidgetAccel(){

TinyWireM.beginTransmission(mpu);

TinyWireM.write(0x3B);

TinyWireM.endTransmission();

TinyWireM.requestFrom(mpu,6);

accelX=TinyWireM.read()<<8|TinyWireM.read();

accelY=TinyWireM.read()<<8|TinyWireM.read();

accelZ=TinyWireM.read()<<8|TinyWireM.read();

}

Затем, внутри функции loop мы будем считывать значения осей X, Y и Z акселерометра и рассчитывать результирующий вектор ускорения при помощи вычисления квадратного корня из суммы квадратов значений осей. Затем мы будем рассчитывать разницу между текущим и предыдущим векторами ускорения и если значение этой разницы будет больше 6 мы будем инкрементировать счетчик шагов.

Arduino

getAccel();
vector = sqrt( (accelX * accelX) + (accelY * accelY) + (accelZ * accelZ) );
totalvector = vector — vectorprevious;
if (totalvector> 6){
Steps++;
}
OzOled.printString(«Steps», 0, 4);
OzOled.printNumber(Steps, 0, 8, 4);
vectorprevious = vector;
delay(600);

1
2
3
4
5
6
7
8
9
10

getAccel();

vector=sqrt((accelX*accelX)+(accelY*accelY)+(accelZ*accelZ));

totalvector=vector-vectorprevious;

if(totalvector>6){

Steps++;

}

OzOled.printString(«Steps»,,4);

OzOled.printNumber(Steps,,8,4);

vectorprevious=vector;

delay(600);

Программы

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

Мы воспользуемся готовой библиотекой для 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 – гироскоп в горизонтальной плоскости:

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

Назначение связки гироскоп и акселерометр

Для начала давайте разберёмся, зачем Arduino mpu 6050 (Gy-521) вообще нужен и что собой представляет гироскоп-акселерометр в целом. Такой датчик все мы видели в смартфонах, и там он выполняет следующие функции:

  1. Позволяет замерять шаги. Акселерометр способен отслеживать резкие движения устройства, а в зависимости от его настройки и чувствительности, считать некоторые из них за шаг.
  2. Измеряет поворот экрана. Здесь уже оба устройства работают в паре. Ведь когда вы поворачиваете смартфон набок, картинка должна изменить свою ориентацию для пользователя, и лишь с помощью гироскопа удаётся определить угол наклона, под которым ПО это должно будет сделать.
  3. Компас, карты и навигация. Акселерометр с гироскопом позволяют определить ориентацию устройства в пространстве, что необходимо в различных приложениях для мобильной навигации.

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

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

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

Смотрите по теме: Подключаем гироскоп-акселерометр (MPU-6050) к плате Arduino

Чаще всего гироскоп для Ардуино применяется в системах автоматизации под так называемые «смартхаусы» (умные дома — прим. ред.), являясь своеобразным переключателем. Передавая определённые данные в МК, который затем отправляет их по блютуз-модулю к другому устройству, он может управлять всей техникой в доме.

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

4Чтение показаний датчика HTU21D без библиотек с помощью Arduino

Теперь, когда мы разобрались с протоколом обмена, давайте сделаем то же самое с помощью Arduino. Схему мы уже собирали. На этот раз давайте соберём схему без преобразователя уровня: если подключать датчик ненадолго, это не критично (нам же только провести один тест). В «боевой» схеме преобразователь уровня категорически рекомендуется. SCL и SDA шины I2C подтянем к питанию 3,3 В через резисторы номиналом 4,7…10 кОм.

Наименование семейства датчиков HTU2xx

А скетч будет такой:

Скетч чтения показаний температуры и влажности с HTU21D без библиотек (разворачивается)

#include <Wire.h>

const int htu21_addr = 0x40; // адрес датчика htu21d

void setup() {
  Serial.begin(9600);
  Wire.begin(); // инициализация i2c
}

void loop() {
  ReadTemperature();  
  ReadHumidity();
  delay(1000);
}

// Читает с датчика HTU21D температуру и выводит в COM-порт.
void ReadTemperature() {
  Wire.beginTransmission(htu21_addr); // начинаем общение с датчиком
  Wire.write(0xF3); // записываем команду на измерение температуры
  Wire.endTransmission(); // окончание передачи

  delay(100); // ждём готовности данных
  Wire.requestFrom(htu21_addr, 3); // запрашиваем 3 байта  

  int Stemp; // "сырые" данные температуры
  while (Wire.available()) { 
    int tmsb = Wire.read(); // читаем MSB температуры с датчика
    int tlsb = Wire.read() & 0xFC; // читаем LSB температуры с датчика и сбрасываем 2 младших бита
    int crc = Wire.read(); // читаем котрольную сумму    
    Stemp = tmsb * 256 + tlsb; // вычисляем значение Stemp
    // *256 это эквивалентно сдвигу на 8 бит влево: <<8 
    //Serial.println(Stemp, HEX);
  }
  double t = ConvertTemp(Stemp); // вычисляем температуру
  Serial.println("T = " + (String)t + "C"); // Выводим данные в COM-порт
}

// Преобразует температуру из "сырых" показаний датчика HTU21D в градусы Цельсия.
double ConvertTemp(int stemp){
  double t = stemp * 0.00268127 - 46.85; // 0.00268127 = 175.72/0x10000
  return t;
}

// Читает с датчика HTU21D относительную влажность и выводит в COM-порт.
void ReadHumidity() {
  Wire.beginTransmission(htu21_addr); // начинаем общение с датчиком
  Wire.write(0xF5); // записываем команду на измерение влажности
  Wire.endTransmission(); // окончание передачи

  delay(100); // ждём готовности данных
  Wire.requestFrom(htu21_addr, 3); // запрашиваем 3 байта  

  int Srh; // "сырые" данные влажности
  while (Wire.available()) { 
    int rmsb = Wire.read(); // читаем MSB влажность с датчика
    int rlsb = Wire.read() & 0xFC; // читаем LSB влажности с датчика и сбрасываем 2 младших бита
    int crc = Wire.read(); // читаем котрольную сумму
    Srh = rmsb * 256 + rlsb ; // вычисляем значение Srh
    //Serial.println(Srh, HEX);
  }
  double rh = ConvertRH(Srh); // вычисляем влажность
  Serial.println("RH = " + (String)rh + "%"); // Выводим данные в COM-порт
}

// Преобразует влажность из "сырых" показаний датчика HTU21D в проценты.
double ConvertRH(int srh) {
  double rh = srh * 0.0019073 - 6; // 0.0019073 = 125/0x10000
  return rh;
}

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

Вывод показаний датчика HTU21D в монитор порта

Как видно, мы научились читать и расшифровывать показания датчика HTU21D с помощью Ардуино и без применения сторонних библиотек.

Исходный код программы на С

Arduino

#include «TinyWireM.h»
#include «TinyOzOLED.h»
int accelX, accelY, accelZ;
char mpu = 0x68;
float vectorprevious;
float vector;
float totalvector;
int Steps = 0;
void setup() {
TinyWireM.begin();
OzOled.init();
OzOled.clearDisplay();
OzOled.setNormalDisplay();
OzOled.sendCommand(0xA1); // установки ориентации дисплея
OzOled.sendCommand(0xC8);
TinyWireM.beginTransmission(mpu);
TinyWireM.write(0x6B); // установка регистра питания
TinyWireM.write(0b00000000); // отключаем спящий режим
TinyWireM.endTransmission();
TinyWireM.beginTransmission(mpu);
TinyWireM.write(0x1B); // конфигурация регистров гироскопа
TinyWireM.write(0x00000000); // 250° per second range (default)
TinyWireM.endTransmission();
TinyWireM.beginTransmission(mpu); //адрес I2C гироскопа
TinyWireM.write(0x1C); // конфигурация регистров акселерометра
TinyWireM.write(0b00000000); // 2g range +/- (default)
TinyWireM.endTransmission();
}
void loop() {
getAccel();
vector = sqrt( (accelX * accelX) + (accelY * accelY) + (accelZ * accelZ) );
//OzOled.printString(«Vec:», 0, 2);
//OzOled.printNumber(vector, 0, 5, 2);
totalvector = vector — vectorprevious;
//OzOled.printString(«Pre:», 0, 4);
//OzOled.printNumber(vectorprevious, 0, 5, 4);
//OzOled.printString(«Diff:», 0, 6);
//OzOled.printNumber(totalvector, 0, 5, 6);
if (totalvector > 6){
Steps++;
}
//String Step_count = String(Steps);
//char data;
//Step_count.toCharArray(data, 2);
//OzOled.printBigNumber(data, 6, 2, 3);
OzOled.printString(«Steps», 0, 4);
OzOled.printNumber(Steps, 0, 8, 4);
vectorprevious = vector;
delay(600);
//OzOled.clearDisplay();
}
void getAccel() {
TinyWireM.beginTransmission(mpu); //адрес I2C гироскопа
TinyWireM.write(0x3B); // регистр данных акселерометра
TinyWireM.endTransmission();
TinyWireM.requestFrom(mpu, 6); // считываем 6 байт, 2 for each DoF
accelX = TinyWireM.read() << 8|TinyWireM.read();
accelY = TinyWireM.read() << 8|TinyWireM.read();
accelZ = TinyWireM.read() << 8|TinyWireM.read();
// OzOled.printNumber(accelX, 0, 0, 0);
// OzOled.printNumber(accelY, 0, 0, 2);
//OzOled.printNumber(accelZ, 0, 0, 4);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

#include «TinyWireM.h»
#include «TinyOzOLED.h»

intaccelX,accelY,accelZ;

charmpu=0x68;

floatvectorprevious;

floatvector;

floattotalvector;

intSteps=;

voidsetup(){

TinyWireM.begin();

OzOled.init();

OzOled.clearDisplay();

OzOled.setNormalDisplay();

OzOled.sendCommand(0xA1);// установки ориентации дисплея

OzOled.sendCommand(0xC8);

TinyWireM.beginTransmission(mpu);

TinyWireM.write(0x6B);//  установка регистра питания

TinyWireM.write(0b00000000);// отключаем спящий режим

TinyWireM.endTransmission();

TinyWireM.beginTransmission(mpu);

TinyWireM.write(0x1B);// конфигурация регистров гироскопа

TinyWireM.write(0x00000000);// 250° per second range (default)

TinyWireM.endTransmission();

TinyWireM.beginTransmission(mpu);//адрес I2C гироскопа

TinyWireM.write(0x1C);// конфигурация регистров акселерометра

TinyWireM.write(0b00000000);// 2g range +/- (default)

TinyWireM.endTransmission();

}

voidloop(){

getAccel();

vector=sqrt((accelX*accelX)+(accelY*accelY)+(accelZ*accelZ));

//OzOled.printString(«Vec:», 0, 2);

//OzOled.printNumber(vector, 0, 5, 2);

totalvector=vector-vectorprevious;

//OzOled.printString(«Pre:», 0, 4);

//OzOled.printNumber(vectorprevious, 0, 5, 4);

//OzOled.printString(«Diff:», 0, 6);

//OzOled.printNumber(totalvector, 0, 5, 6);

if(totalvector>6){

Steps++;

}
//String Step_count = String(Steps);
//char data;
//Step_count.toCharArray(data, 2);
//OzOled.printBigNumber(data, 6, 2, 3);

OzOled.printString(«Steps»,,4);

OzOled.printNumber(Steps,,8,4);

vectorprevious=vector;

delay(600);

//OzOled.clearDisplay();
}

voidgetAccel(){

TinyWireM.beginTransmission(mpu);//адрес I2C гироскопа

TinyWireM.write(0x3B);//  регистр данных акселерометра

TinyWireM.endTransmission();

TinyWireM.requestFrom(mpu,6);// считываем 6 байт, 2 for each DoF

accelX=TinyWireM.read()<<8|TinyWireM.read();

accelY=TinyWireM.read()<<8|TinyWireM.read();

accelZ=TinyWireM.read()<<8|TinyWireM.read();

// OzOled.printNumber(accelX, 0, 0, 0);

// OzOled.printNumber(accelY, 0, 0, 2);

//OzOled.printNumber(accelZ, 0, 0, 4);

}

Процессор полетного контроллера

От процессора будет зависеть то, насколько быстро будут обрабатываться поступающие к нему данные. Процессоры делятся по поколениям: F1, F3, F4, F6. Вот такие странные поколения, где пропущены 2-е и 6-е поколения. Отличаются они частотой работы и архитектурой:

  • F1 — 72MHz;
  • F3 — 72MHz;
  • F4 — 168MHz;
  • F7 — 216MHz.

Сейчас все новые полетные контроллеры поставляются с процессором 7-го поколения, так как обрабатывать фильтры и PID становится все труднее, прогресс шагает километровыми шагами в этой сфере. Но у многих пилотов ПК на процессорах 3-го поколения, так как F3 был самым (да и остается) массовым поколением со стабильной работой.

Шаг 4: Запустите симуляцию

Наконец, откройте файл приложения Processing, а затем

Файл -> Открыть -> следовать этому каталогу C: Program Files (x86) Arduino library MPU6050 examples MPU6050_DMP6 Processing MPUTeapot

и откройте файл MPUTeapot.

Нажмите кнопку воспроизведения, и система должна откалиброваться примерно на 20-30 секунд, оставив гироскоп в течение этого периода.

Теперь возьмите гироскоп и проверьте рыскание / тангаж / крен. Если вы довольны тем, что все работает правильно, вы можете начать экспериментировать с вашими собственными проектами. Если вы хотите в полной мере использовать библиотеки I2Cdev или MPU6050 и их функции, обратитесь к их заголовочным файлам.

Я надеюсь в ближайшее время сделать инструктаж по изготовлению беспилотника «Сделай сам», поэтому, если вы нашли его полезным, почему бы не остаться в курсе будущих проектов, следуя за мной на Instructables и в Facebook / Twitter / Google+.

PayPal: http://www.paypal.me/HobbyTransform

Bitcoin: 1Mqe7et24Lz4DY1RUN4iAQVHkvJsdFArKR

Ethereum: 0x6d8248db1cdea6a783cb6b41ae67bb8e6144f479

Litecoin: LW6PWESqsr8xHw6EJ9WLbsQsAyTvPnwnxJ

Тире: Xemv7jud697v8tQmKfNFoMxfkd17ZayH2t

Ваша поддержка очень ценится! С Днем DIY!

Расчет угла с помощью гироскопа mpu6050

Данные с гироскопа имеют вид:

В дальнейшем в статье мы будем рассматривать все на примере оси x. Для расчета угла необходимо проинтегрировать переменную “gyro_x_scalled”

является количеством итераций

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

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

Мы предполагаем, что начальные углы относительно осей x, y, z после калибровки равны 0, 0 и 90 градусов соответственно, так что для итерации n=0:

Значение T (время каждой итерации) и динамика самого гироскопа (как быстро и насколько нелинейно изменяются углы), значительным образом влияет на точность расчетов. Чем медленнее изменяются углы и чем меньше промежуток между итерациями, тем более точным будет результат. В этом смысле жаль, что платы Arduino достаточно медленные, кристаллы у них работают с частотой 16 МГц и снятие измерений каждые 10-20 мс становится достаточно затруднительным (учитывая тот факт, что процессор занят не только расчетом угла, но и другими параллельными задачами). Мы можем использовать T в виде переменной или константы, я, лично, предпочитаю использовать константу для каждого цикла. В проекте динамические факторы не учитывались, просто использовалась частота итераций с разрывом в 20 мс (0.02 с).

Как еще можно модернизировать квадрик

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

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

Выбор платы Arduino Uno обусловлен тем, что с нее можно довольно легко снять чип и поставить его на ProtoBoard. Это позволяет уменьшить вес дрона на 30 грамм, но придется включить в схему дополнительные конденсаторы. Подойдет и плата Arduino Pro Mini.

Что касается программы Arduino, то ее можно сравнительно легко изменить и дополнить новыми функциями. Главное, что с ее помощью дрон способен в автоматическом режиме стабилизовать свое положение.

На квадрокоптер могут быть установлены дополнительные модули, например, плата приемника, что позволит организовать дистанционное управление дроном.

Arduino и датчик MPU6050

Файл, приведенный ниже, будет работать с цифровыми датчиками ускорения MPU6050, которые подключены к плате Arduino через I2C протокол по адресу 0x68. Работоспособность проверена на платах Arduino Uno и Arduino Mega. Данный файл заголовка требует файл Wire.h перед добавлением “gyro_Accel.h”. Кроме того, перед вызовом встроенных функций, надо инициализировать шину I2Cс помощью команды Wire.begin();.

Программа для Arduino с файлом заголовка и примером расположены на Github

Логи версии:

Версия 0.1 beta (Дата:2014-06-22): Сам файл заголовка для калибровки и чтения данных с датчика MPU6050 через i2c протокол и пример использования заголовочного файла для расчета угла.

Версия 0.2 beta (Дата:2014-10-08): Исправлены баги в файле примера. “accel_x_scalled” и “accel_y_scalled” теперь возвращают корректные значения углов.

Тестирование

После отладки необходимо провести тестирование. В чём разница? При тестировании вы точно знаете, что программный код работает без лагов и багов, но вам необходимо убедиться, что в нём нет логических ошибок.

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

  • https://mysku.ru/blog/china-stores/40178.html
  • https://robotclass.ru/tutorials/arduino-accelerometer-mpu6050/
  • https://arduinoplus.ru/arduino-giroskop/

4Разбор показаний цифрового акселерометра ADXL345

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

Акселерометр ADXL345 на макетной плате

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

Данные ускорений по X, Y, Z акселерометра ADXL345 в мониторе последовательного порта Arduino IDE

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

Параметры датчика ADXL345

Напомню, что g – это ускорение свободного падения, численно равное примерно 9,81 метр в секунду за секунду (м/с2).

Диапазон по умолчанию – от −16g до &plus;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.