В этой статье мы рассмотрим создание цифрового измерителя уровня (Inclinometer, инклинометр, креномер, уклономер) своими руками (DIY) на основе платы Arduino и MPU6050.
MPU6050 представляет собой 3-х осевой акселерометр и 3-х осевой гироскоп, объединенных в одну микросхему. Также он имеет в своем составе датчик температуры и цифровой канал с памятью, что позволяет с его помощью решать достаточно сложные задачи. Этот датчик часто используется при создании дронов и различных роботов с дистанционным управлением, в особенности самобалансирующихся роботов.
Как мы знаем, измеритель уровня обычно используется для того чтобы проверить ровная поверхность или нет. Выпускаются цифровые измерители уровня и механические (на основе пузырька воздуха – наверняка все вы его видели).
Также в этой статье мы будем удаленно считывать показания измерителя уровня – на экране смартфона. Это очень удобно, когда, к примеру, MPU6050 размещен на дроне или в другом труднодоступном месте.
На нашем сайте вы также можете прочитать статью о подключении гироскопа MPU6050 к плате Arduino.
Необходимые компоненты
- Плата Pro-mini (5V) (купить на AliExpress).
- Гироскоп MPU6050 (купить на AliExpress).
- Bluetooth модуль HC-05 или HC-06 (купить на AliExpress).
- FTDI board (плата).
- Макетная плата.
- Соединительные провода.
- Смартфон.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Работа схемы
Схема измерителя уровня на основе платы Arduino и MPU6050 представлена на следующем рисунке. Схема достаточно простая и ее сравнительно легко можно собрать на макетной плате.
Взаимодействие с датчиком MPU6050 будет осуществляться по протоколу I2C, поэтому его контакт SDA подключен к контакту A4 платы Arduino, а контакт SCL - к контакту A5 платы Arduino. Bluetooth модуль HC-06 работает по порту последовательной связи, его контакт Rx подключен к контакту D11 платы Arduino, а его контакт Tx - к контакту D10 платы Arduino. Контакты D10 и D11 платы Arduino в программе конфигурируются так, чтобы работать как порт последовательной связи. Модуль HC-05 и датчик MSP6050 работают от напряжения +5V, поэтому в схеме они запитаны от контакта Vcc платы Arduino.
После того как вы соберете всю конструкцию на макетной плате она у вас должна получиться примерно следующего вида.
Как запитать схему
Вы можете подать питание на схему с помощью платы программирования FTDI (как сделали мы) или использовать батарейку на 9V или адаптер на 12V – в этом случае вы должны подсоединить их к контакту Raw платы Arduino pro mini – эта плата имеет в своем составе встроенный регулятор напряжения, который трансформирует поступающее входное напряжение в постоянное напряжение +5V.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же рассмотрим его наиболее важные фрагменты.
Сначала мы должны подключить гироскоп MPU6050 к плате Arduino, для этой цели мы будем использовать библиотеку, разработанную Korneliusz Jarzebski и которую можно скачать по ссылке - MPU6050 Liberty.
Скачайте ZIP файл библиотеки по приведенной ссылке и добавьте ее в вашу Arduino IDE. После этого запустите пример из скачанной библиотеки по адресу File->Examples->Arduino_MPU6050_Master -> MPU6050_gyro_pitch_roll_yaw. Загрузите программу этого примера в Arduino Pro mini. В результате работы этого примера у вас будет установлена последовательная связь со скоростью 115200 бод/с и в окне монитора последовательной связи вы должны наблюдать примерно следующую картину.
В исходном состоянии эти три значения будут равны 0, но как только вы будете перемещать вашу макетную плату в пространстве вы заметите как будут изменяться их значения. Если они изменяются, значит, все работает нормально, если нет – ищите ошибку в соединениях схемы. Чтобы сбросить показания датчика можно нажать кнопку сброса на Arduino. Следующая картинка поможет вам понять принцип изменения значений Pitch, Roll и Yaw в зависимости от перемещения датчика MPU6050 в пространстве.
Нас из этих параметров будут интересовать только параметры Roll и Pitch. Значение параметра Roll будет говорить нам о наклоне по оси X, а значение параметра Pitch – о наклоне по оси Y. Эти данные будут поступать в плату Arduino через Bluetooth.
Для начала нам в программе необходимо подключить библиотеки, которые будут использоваться в процессе работы программы.
1 2 3 |
#include <Wire.h> //библиотеки для связи по протоколу IIC #include <MPU6050.h> //библиотека для взаимодействия с MPU6050 #include <SoftwareSerial.h>// библиотека последовательной связи, позволяет задействовать последовательную связь на любых цифровых контактах Arduino |
Далее с помощью библиотеки последовательной связи (Software Serial library) мы задействуем последовательную связь на контактах D10 и D11, которые используются в данном случае для взаимодействия с модулем Bluetooth.
1 |
SoftwareSerial BT(10, 11); // RX, TX |
Далее мы должны инициализировать необходимые переменные и последовательные порты для связи с модулем Bluetooth и монитором последовательной связи. Для взаимодействия с модулем Bluetooth (HC-05 или HC-06) мы будем использовать скорость 9600 бод/с. Далее мы проверяем наличие соединения по протоколу IIC с датчиком MPU6050 и если его нет, то печатаем предупреждение в окне монитора последовательной связи. Далее запускаем калибровку гироскопа и выставляем ему чувствительность.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void setup() { Serial.begin(115200); BT.begin(9600); //инициализируем последовательную связь с модулем Bluetooth со скоростью 9600 бод/с // инициализируем MPU6050 while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { Serial.println("Could not find a valid MPU6050 sensor, check wiring!"); delay(500); } mpu.calibrateGyro(); // старт калибровки гироскопа mpu.setThreshold(3); //управление чувствительностью } |
Команда “mpu.calibrateGyro();” производит калибровку MPU6050 на его текущей позиции. Эту команду в программе можно вызывать много раз – при ее выполнении значения показателей гироскопа будут выставляться в 0. Команда “mpu.setThreshold(3);” определяет на какую величину будут изменяться значения показателей гироскопа при его перемещении. Не выставляйте очень маленькую чувствительность (малое значение в функции) поскольку это может привести к увеличению шумов.
Далее в функции loop() мы будем непрерывно считывать значения с гироскопа, рассчитывать рассмотренные выше показатели pitch, roll и yaw и передавать их на Bluetooth модуль. Следующие две строки в программе будут считывать значения гироскопа с датчика и значение температуры.
1 2 |
Vector norm = mpu.readNormalizeGyro(); temp = mpu.readTemperature(); |
Затем мы рассчитываем показатели pitch, roll и yaw путем умножения данных с гироскопа на шаг времени (time step) и прибавляя к ним предыдущие значения. timeStep здесь у нас – это просто время между успешными считываниями данных с датчика.
1 2 3 |
pitch = pitch + norm.YAxis * timeStep; roll = roll + norm.XAxis * timeStep; yaw = yaw + norm.ZAxis * timeStep; |
Чтобы лучше понять что собой представляет временной шаг (timeStep) давайте посмотрим на следующую приведенную ниже строчку программы. Эта строчка помещает считываемые значения с MPU6050 точно в интервал 10 миллисекунд (мс), или 0.01 секунды. То есть значение timeStep у нас будет равно 0.01. Задержка в этой строчке используется чтобы немного замедлить выполнение программы. Если использовать только (millis() – timer()), то программа будет выполняться слишком быстро. Мы просто вычитаем значение этого выражения из 0.01 секунды и оставшееся время просто ждем с помощью использования функции delay.
1 |
delay((timeStep*1000) - (millis() - timer)); |
После того как мы считали и рассчитали необходимые данные мы можем передавать их через Bluetooth. Но не все так просто в этом проекте. Дело в том, что Bluetooth модуль за один раз может передавать только 1 байт (8 бит) информации, то есть число от 0 до 255. То есть мы должны разделить наши значения и упаковать (map) их в этот диапазон. Это мы будем делать с помощью следующих строчек кода:
1 2 3 4 5 6 |
if (roll>-100 && roll<100) x = map (roll, -100, 100, 0, 100); if (pitch>-100 && pitch<100) y = map (pitch, -100, 100, 100, 200); if (temp>0 && temp<50) t = 200 + int(temp); |
То есть значение показателя roll упаковывается в диапазон от 0 до 100 и помещается в переменную x, а значение показателя pitch упаковывается в диапазон от 100 до 200 и помещается в диапазон y. Значение температуры упаковывается в диапазон от 200 до 250 и помещается в переменную t. Аналогичным образом эти данные потом распаковываются на приемном конце. Далее мы передаем эти данные по Bluetooth с помощью следующих строчек кода:
1 2 3 |
BT.write(x); BT.write(y); BT.write(t); |
Подготовка приложения на Android
Приложение на Android для нашего проекта мы разработали с помощью бесплатной программной среды Processing IDE, программирование в которой очень похоже на программирование в Arduino. Ранее на нашем сайте программную среду Processing мы использовали в следующих проектах:
В этом проекте вы можете скачать либо готовый APK файл приложения, не утруждая себя погружением в среду Processing, либо можете скачать исходные коды приложения если все таки хотите в нее погрузиться и изменить что либо в нашей программе.
По следующей ссылке вы можете скачать готовый APK файл приложения для проектируемого нами измерителя уровня (правая кнопка мыши на ссылке и выбирайте сохранить как):
Android APK File for Arduino Inclinometer.
Примечание: это приложение будет корректно работать если только Bluetooth устройство имеет имя “HC-06”. Чтобы установить приложение на смартфон разрешите в нем установку приложений из непроверенных источников.
Объяснение кода приложения для Android
Для тех, кто все же хочет разобраться в коде приложения, мы попытаемся объяснить несколько наиболее важных фрагментов этого кода. Для работы в Processing нам необходимо будет задействовать в нем Android режим, чтобы работать с нашими Android SDK. Исходные коды приложения для Android вы можете скачать по следующей ссылке:
Processing program ZIP file for Arduino Inclinometer.
Внутри скачанного ZIP файла вы найдете папку, в которой находятся все изображения и другие данные, необходимые для работы android приложения.
В следующей строке кода программы мы указываем с каким Bluetooth устройством необходимо автоматически соединиться приложению.
1 |
bt.connectToDeviceByName("HC-06"); |
Внутри функции draw(), которая представляет собой бесконечный цикл, мы будем рисовать изображения и печатать текст на экране смартфона в зависимости от данных, принимаемых по Bluetooth.
1 2 3 4 5 6 7 8 9 |
void draw() //The infinite loop { background(0); imageMode(CENTER); image(logo, width/2, height/1.04, width, height/12); load_images(); textfun(); getval(); } |
Также помните о том, что в программе для Arduino мы разделили передаваемые данные на три части и поместили их все в диапазон от 0 до 255. Здесь же мы должны распаковать эти данные и вернуть им нормальные значения.
1 2 3 4 5 6 7 |
if (info<100 && info>0) x = map(info, 0, 100, -(width/1.5)/3, +(width/1.5)/3);//x = info; else if (info<200 && info>100) y = map(info, 100, 200, -(width/4.5)/0.8, +(width/4.5)/0.8);//y = info; else if (info>200) temp = info -200; println(temp,x,y); |
Тестирование работы измерителя уровня
После того как аппаратная часть проекта будет готова загрузите программу (приведенную в конце статьи) в плату Arduino. В коде программы вы можете снять комментарии со строк Serial.println и наблюдать за ходом выполнения программы в окне монитора последовательной связи.
После загрузки кода программы в плату Arduino запустите Android приложение для этого проекта на вашем смартфоне. Приложение должно автоматически установить соединение с вашим модулем HC-06 и на экране смартфона должна высветиться надпись “Connect to: HC-06” как показано на следующем рисунке.
Сначала все значения гироскопа будут установлены в 0 поскольку в программе мы первым делом производим калибровку гироскопа. Далее, по мере того, как вы будете наклонять конструкцию в разные стороны, значения гироскопа также будут меняться. А значения температуры с самого начала будут показываться реальные. Более подробно работа проекта показана на видео, приведенном в конце статьи.
Теперь вы можете помещать макетную плату с собранным устройством на любые поверхности и проверять действительно ли они являются ровными.
Исходный код программы
Перед загрузкой кода программы в плату Arduino не забудьте скачать и установить библиотеку для работы с гироскопом MPU6050.
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 64 65 66 67 68 69 70 |
/* MPU6050 Library: https://github.com/jarzebski/Arduino-MPU6050 (c) 2014 by Korneliusz Jarzebski */ #include <Wire.h> //библиотека для связи по протоколу IIC #include <MPU6050.h> //библиотека для работы с MPU6050 #include <SoftwareSerial.h>// библиотека последовательной связи SoftwareSerial BT(10, 11); // RX, TX MPU6050 mpu; unsigned long timer = 0; unsigned long timer2 = 0; float timeStep = 0.01; float pitch = 0; float roll = 0; float yaw = 0; float temp =0; void setup() { Serial.begin(115200); BT.begin(9600); // инициализируем последовательную связь с модулем Bluetooth на скорости 9600 бод/с // инициализируем MPU6050 while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { Serial.println("Could not find a valid MPU6050 sensor, check wiring!"); delay(500); } mpu.calibrateGyro(); // старт калибровки гироскопа mpu.setThreshold(3); // устанавливаем чувствительность гироскопа } void loop() { timer = millis(); //считываем данные температуры и гироскопа Vector norm = mpu.readNormalizeGyro(); temp = mpu.readTemperature(); // рассчитываем показатели Pitch, Roll и Yaw pitch = pitch + norm.YAxis * timeStep; roll = roll + norm.XAxis * timeStep; yaw = yaw + norm.ZAxis * timeStep; // Print values Serial.print(" Pitch = "); Serial.print(pitch); Serial.print(" Roll = "); Serial.print(roll); Serial.print(" Yaw = "); Serial.print(yaw); Serial.print(" Temp = "); Serial.print(temp); Serial.println(" *C"); delay((timeStep*1000) - (millis() - timer)); // используем интервал 0.01 секунды для считывания данных if ((millis()-timer2) > 200) send_BT(); } void send_BT() { int t; int x; int y; if (roll>-100 && roll<100) x = map (roll, -100, 100, 0, 100); if (pitch>-100 && pitch<100) y = map (pitch, -100, 100, 100, 200); if (temp>0 && temp<50) t = 200 + int(temp); BT.write(x); BT.write(y); BT.write(t); timer2 = millis(); } |
Как заставить работать с модулем hc-05
Ну так в проекте использован модуль hc-05
Что требуется сделать чтобы запустить на версии arduino nano?
Просто подключайте arduino nano к компьютеру через USB, а плата FTDI будет не нужна