MPU 9250 и Arduino – схема подключения
MPU 9250 выполняет функции сразу нескольких датчиков: это и гироскоп, и акселерометр, и магнитометр – все три устройства в одном, что очень удобно.
Остановимся немного подробнее на каждом из них.
Гироскоп – это сенсор, реагирующий на изменение углов ориентации в пространстве. В тех же квадрокоптерах его используют, чтобы стабилизировать положение аппарата в воздухе и защитить его от ветра.
Например, во время рыбалки, мы закидываем удочки в водоем и на поверхности воды виден только поплавок.
Если погода достаточно ветреная, то поплавок постоянно будет уходить в разные стороны и наклоняться под случайным углом, что может помешать нам вовремя заметить клев рыбы. То же самое будет происходить и в воздухе.
Чтобы ваш квадрокоптер не находился постоянно в наклонном положении, его выравниванием и будет заниматься гироскоп.
В качестве иллюстрации, внизу вы можете наглядно посмотреть испытания DIY дрона вместе с установленным в его аппаратную часть гироскопом.
Акселерометр сравнивает проекцию ускорения объекта с гравитационным ускорением и способен замерять линейную скорость объекта, а вкупе с гироскопом – и положение в пространстве.
Магнитометр представляет собой устройство для измерения интенсивности ближайшего магнитного поля, действующего на объект (впрочем, название датчика говорит само за себя).
А еще, по некоторым данным, наш модуль MPU 9250 является самым миниатюрным в мире девятиосевым сенсором. Это говорит о высокой производительности микросхемы (по названию которой и назван наш “герой”), что было обеспечено применением технологии CMOS MEMS.
Состоит корпус модуля из двух мельчайших кристаллов, один из которых отвечает за гироскоп и акселерометр, а другой за магнитометр. Данные с них обрабатываются встроенным сигнальным процессором DMP с помощью алгоритмов Motion Fusion и передаются по интерфейсам I2C или SPI.
Помимо высокой производительности, модуль довольно популярен в среде ардуинщиков и тех, кто увлекается устройствами на дистанционном управлении, а также имеет низкие энергопотребление и стоимость.
Как уже было сказано ранее, подключать датчик к Arduino можно по шине I2C или SPI. Питать модуль можно от 5 В, так как на плате датчика имеется линейный стабилизатор для данного типа питания, но подавать питание можно и значением в 3,3 В.
Вы можете подключать модуль к вашему микроконтроллеру по четырем контактам через интерфейс I2C (5V, Gnd, SCL, SDA) или через SPI, используя 5 контактов на плате модуля (5V, Gnd, SCL, SDA, CS, SDO).
На картинке показано подключение через интерфейс I2C.
В качестве примеров для работы с модулем MPU 9250 можете воспользоваться предложенным ниже скетчем.
Данный код с использованием пары библиотек позволит считывать информацию (данные) со всех трех датчиков и выводить в порт. Здесь понадобится библиотека Wire 0. Она уже встроена в Arduino IDE , а, значит, ее отдельно скачивать устанавливать не нужно.
Библиотека TimerOne.h упрощает использование временных функций. Ее можно скачать по ссылке ниже:
Код считывания данных с датчиков и вывода их в порт
#define MPU9250_ADDRESS 0x68#define GYRO_FULL_SCALE_250_DPS 0x00#define GYRO_FULL_SCALE_500_DPS 0x08#define GYRO_FULL_SCALE_1000_DPS 0x10#define GYRO_FULL_SCALE_2000_DPS 0x18#define ACC_FULL_SCALE_2_G 0x00#define ACC_FULL_SCALE_4_G 0x08#define ACC_FULL_SCALE_8_G 0x10#define ACC_FULL_SCALE_16_G 0x18// This function read Nbytes bytes from I2C device at address Address.// Put read bytes starting at register Register in the Data array.void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data) Wire.beginTransmission(Address); Wire.requestFrom(Address, Nbytes); Data[index++]=Wire.read();// Write a byte (Data) in device (Address) at register (Register)void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data) Wire.beginTransmission(Address);volatile bool intFlag=false; // Arduino initializations // Set accelerometers low pass filter at 5Hz I2CwriteByte(MPU9250_ADDRESS,29,0×06); // Set gyroscope low pass filter at 5Hz I2CwriteByte(MPU9250_ADDRESS,26,0×06); // Configure gyroscope range I2CwriteByte(MPU9250_ADDRESS,27,GYRO_FULL_SCALE_1000_DPS); // Configure accelerometers range I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_4_G); // Set by pass mode for the magnetometers I2CwriteByte(MPU9250_ADDRESS,0x37,0x02); // Request continuous magnetometer measurements in 16 bits I2CwriteByte(MAG_ADDRESS,0x0A,0x16); Timer1.initialize(10000); // initialize timer1, and set a 1/2 second period Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt digitalWrite(13, digitalRead(13) ^ 1);// Main loop, read and display data Serial.print (millis()-ti,DEC); // Serial.print (cpt++,DEC); // ____________________________________ // ::: accelerometer and gyroscope ::: // Read accelerometer and gyroscope I2Cread(MPU9250_ADDRESS,0x3B,14,Buf); // Create 16 bits values from 8 bits data int16_t ax=-(Buf[0] |
Источник: https://Voltiq.ru/mpu-9250-and-arduino/
Подключение IMU 10DOF L3G4200D+ADXL345+HMC5883L+BMP085 – Популярная робототехника
10-DOF означает, что данный IMU позволяет отслеживать 10 параметров, определяющих его положение в пространстве.
Список этих параметров включает:
- проекция ускорения на три оси x,y,z (акселерометр ADXL345);
- скорость вращения вокруг трех осей x,y,z (гироскоп L3G4200D);
- проекции магнитного поля на три оси x,y,z (компас HMC5883L);
- атмосферное давление (барометр BMP085).
Здесь следует пояснить, что показания барометра можно легко преобразовать в высоту над уровнем моря, что также является одной из пространственных координат. Также, чип барометра имеет встроенный термодатчик, показания которого также могут быть сняты микроконтроллером.
Все расположенные на плате датчики соединены I2C шиной. Благодаря этому, устройство достаточно легко подключается ко всем распространенным платформам, включая Arduino, mbed и TI LaunchPad. Кроме того, такой вариант подключения высвобождает аналоговые входы микроконтроллера, количество которых ограничено.
Плата IMU имеет 11 выводов:
- M_DRDY – сигнал готовности измерений компаса HMC5883L;
- G_INT1,2 – программируемые прерывания гироскопа L3G4200D;
- A_INT1,2 – программируемые прерывания акселерометра ADXL345;
- P_EOC – завершение измерения температуры или давления в BMP085;
- P_XCLR – сброс всех регистров BMP085;
- SCL, SDA – I2C шина;
- VCC – питание +5В, +3.3В;
- GND – земля.
Для работы устройства требуется подключить только цепь питания и каналы шины I2C. Как обычно, эксперимент по оживлению устройства происходил при помощи mbed. Схема подключения изображена ниже.
Как видно на схеме, I2C линии “подтянуты” к напряжению питания сопротивлением 2.2КОм (рекомендуется 2.2 – 10КОм). Есть подозрение, что на плате IMU уже стоят соответствующие резисторы, обязательно проверю это предположение в следующий раз.
Что касается питания, то я подключил IMU к +3.3В, хотя согласно даташиту можно использовать и +5В.
Ввиду того, что указанный IMU содержит достаточно распространенные модели датчиков, найти соответствующие библиотеки для mbed не составило труда. Уверен, что для Arduino ситуация окажется аналогичной.
Единственные проблемы возникли при подключении гироскопа. Здесь следует помнить, что адреса I2C устройств на mbed сдвинуты на один бит влево относительно аналогичных адресов для Arduino.
Например, если Arduino использует для общения с гироскопом L3G4200D адреса 0x68 или 0x69, то при работе с mbed следует использовать 0xD1 или 0xD2, соответственно.
В коде библиотеки для данного гироскопа был установлен адрес 0xD2, и попробовать 0xD1 я догадался только после сканирования всей шины.
Код программы достаточно примитивен и почти полностью заимствован у одного из резидентов портала mbed.org.
#include “mbed.h”
#include “HMC5883L.h”
#include “ADXL345.h”
#include “L3G4200D.h”
#include “BMP085.h”
DigitalOut myled(LED1);
HMC5883L cmp(p9, p10); // sda, scl
ADXL345 acc(p9, p10); // sda, scl
L3G4200D gyr(p9, p10); // sda, scl
BMP085 alt(p9, p10); // sda, scl
Serial pc(USBTX, USBRX); // tx, rx
int main() {
pc.baud(19200);
int16_t data[3];
cmp.init();
wait(0.1);
// These are here to test whether any of the initialization fails. It will print the failure
if (acc.setPowerControl(0x00)){
pc.printf(“acc: didn't intitialize power control
“);
return 0; }
wait(.001);
//Resolution setup, +/-2g.
if(acc.setDataFormatControl( ADXL345_FULL_RES || ADXL345_2G )){
pc.printf(“didn't set data format
“);
return 0; }
wait(.001);
//3.2kHz data rate.
if(acc.setDataRate( ADXL345_3200HZ )){
pc.printf(“didn't set data rate
“);
return 0; }
wait(.001);
//Measurement mode.
if(acc.setPowerControl( MeasurementMode )){
pc.printf(“didn't set the power control to measurement
“);
return 0; }
alt.init();
while (1) {
cmp.getXYZ(data);
pc.printf(“C %+4i %+4i %+4i “,data[0],data[1],data[2]);
wait(0.1);
acc.getXYZ(data);
pc.printf(” A %+5i %+5i %+5i”,data[0],data[1],data[2]);
wait(0.1);
gyr.getXYZ(data);
pc.printf(” G %+5i %+5i %+5i”,data[0],data[1],data[2]);
wait(0.05);
pc.printf(” T %d”, alt.get_temperature());
pc.printf(” P %d”, alt.get_pressure());
pc.printf(” A %.2f
“, alt.get_altitude_m());
myled = !myled;
}
}
Ниже представлен скриношот выходных данных тестируемого IMU в приложении TeraTerm. Как можно заметить, в моей квартире температура воздуха составляет почти 28 градусов Цельсия. У меня нет другого градусника, но учитывая постоянное нытье гостей, я склонен верить этим показаниям.
Атмосферное давление – около 98 260 Паскалей, что соответствует 737 мм ртутного столба. Согласно данным об атмосферном давлении по городу, полученная величина примерно соответствует действительности.
Теперь что касается высоты над уровнем моря, которая рассчитывается исходя из показаний термометра и барометра по известным формулам (формулы есть в гугле и в даташите датчика).
Официально, город Екатеринбург расположен в 240 метрах над уровнем моря.
Учитывая холмистый рельеф города и тот факт, что измерения проводились на 16-м этаже, полученная величина в 258 метров выглядит вполне правдоподобно.
Я вполне доволен этим, относительно дешевым китайским IMU ($21 на ebay). Справедливости ради следует отметить, что китайского в нем только сама плата и обвязка.
Сами же датчики являются продуктом весьма солидных компаний, таких как Bosch, Pololu, Analog Devices и Honeywell.
Плата изготовлена качественно, все чипы расположены строго параллельно друг другу, что очень важно в подобных составных устройствах, которые используются для точного позиционирования в пространстве.
В ближайшем будущем, именно этот IMU заменит аналоговые гироскоп и акселерометр, которые сейчас установлены на моем квадрокоптере.
Источник: http://www.poprobot.ru/home/podklucenieimu10dofl3g4200dadxl345hmc5883lbmp085
GY-521 – модуль с гироскопом, акселерометром и термометром MPU-6050 для Ардуино
- Магазины Китая
- BANGGOOD.COM
- Радиотовары
- Пункт №18
Датчики определения положения в пространстве широко используются в мобильных устройствах, а для самоделок чаще всего применяются в квадрокоптерах.
Также, его можно применить в светящемся шлеме! Удобно, не правда ли? Наклонил голову вправо — загорелось правое «полушарие» =) влево — левое, согнул голову в шее — сзади на шлеме высветился стоп-сигнал! Вот только, думаю, моей шеи хватит минут на 5 таких упражнений, потом — коллдаун, в виде боли на неделю обеспечен.
Итак, заказал — прислали, теперь нужно разобраться и продемонстрировать функционал для Вас, уважаемые читатели Муськи. Пришло с треком, не известно, почему, но в Киеве посылку держали неделю (или это глюки системы треккинга). Дошла чуть менее, чем за три недели. Упаковано в три слоя утеплителя — для амортизации.
Сам модуль — внутри запаянного пакетика со штрих-кодом на наклейке:Размеры платы: 20×16мм. В комплекте два набора штыревых контактов: ровные и загнутые — удобно, не придется гнуть или ровнять.
…
Большие отверстия не металлизированы, как на картинке в магазине, поэтому, если Вы будите их прикручивать болтами к «минусу», эффекта не будет. Я заливаю их термоклеем, а он, образуя «шапочки», надёжно фиксирует плату.
Отвертия контактов металлизированы отлично, паяются без проблем. Модуль GY-521 включает понижающий линейный стабилизатор для питания от 5В, красный светодиод питания и обвязку, обеспечивающую работу по протоколу I2C.
Схема
Взята из статьи про такой же модуль — cxem.net/mc/mc324.php
MPU-6050 снабжен акселерометром, гироскопом и термометром. Зачем нужен термометр — не понятно, вероятно, его было удобно разместить в этой микросхеме.
Или, действительно, есть такие варианты применения, о которых я не знаю, где тебя вертят и греют нужно вертеться в пространстве и знать температуру =) Или, в процессе интенсивной работы с устройством, оно может нагреваться и нужно контролировать его температуру и нагрузку.
— 16-битный АЦП, — напряжение питания 3-5В, — поддержка протокола «IIC» (может, I2C ?), — диапазон ускорений: ± 2 ± 4 ± 8 ± 16g, — диапазон «гиро»: ± 250 500 1000 2000 ° / s, — покрытие иммерсионным золотом вместо лужения, — ток при работе последнего примера составил 5.3 мА и 1.
2 мА когда устройство не успело стартовать (питание на модуль было подано после выполнения setup() контроллером) Для интерфейса I2C у Ардуино имеются контакты A4 (SDA) и A5 (SCL), да-а, это те, которые расположены чёрти-где (на одной плате у меня они были справа от контроллера, на другой с левого края).
В коде нужно использовать библиотеку Wire, прочитать о ней можно туточки. Минимальная схема во Fritzing такая:
… а значит у нас уже не 8 лишних штырьков, а целых двенадцать! Термометр тестировать проще всего: залил скетч отсюда, открыл монитор порта, выставил скорость на 9600, —
побежали такие строки
AcX = 1624 | AcY = -808 | AcZ = 15176 | Tmp = 25.14 | GyX = 11 | GyY = 314 | GyZ = -138 AcX = 1584 | AcY = -876 | AcZ = 15112 | Tmp = 25.00 | GyX = 0 | GyY = 193 | GyZ = -163 AcX = 1616 | AcY = -904 | AcZ = 15172 | Tmp = 25.05 | GyX = -2 | GyY = 264 | GyZ = -181 AcX = 1648 | AcY = -836 | AcZ = 14948 | Tmp = 25.09 | GyX = 3 | GyY = 146 | GyZ = -192 AcX = 1792 | AcY = -800 | AcZ = 15216 | Tmp = 25.09 | GyX = 27 | GyY = -181 | GyZ = -218 AcX = 1864 | AcY = -900 | AcZ = 14932 | Tmp = 25.09 | GyX = 11 | GyY = 48 | GyZ = -206 AcX = 2144 | AcY = -796 | AcZ = 14860 | Tmp = 25.05 | GyX = 8 | GyY = 100 | GyZ = -191 AcX = 2088 | AcY = -916 | AcZ = 14952 | Tmp = 25.14 | GyX = 11 | GyY = 158 | GyZ = -189 AcX = 2180 | AcY = -752 | AcZ = 14964 | Tmp = 25.14 | GyX = 6 | GyY = 334 | GyZ = -182 AcX = 2296 | AcY = -796 | AcZ = 15076 | Tmp = 25.05 | GyX = -3 | GyY = 184 | GyZ = -189 AcX = 2160 | AcY = -788 | AcZ = 15176 | Tmp = 25.14 | GyX = -8 | GyY = 184 | GyZ = -172 AcX = 2036 | AcY = -852 | AcZ = 14988 | Tmp = 25.09 | GyX = 3 | GyY = 292 | GyZ = -172 AcX = 1984 | AcY = -836 | AcZ = 14892 | Tmp = 25.09 | GyX = 38 | GyY = 90 | GyZ = -205 AcX = 2136 | AcY = -708 | AcZ = 14976 | Tmp = 25.19 | GyX = -5 | GyY = 270 | GyZ = -148 AcX = 2000 | AcY = -788 | AcZ = 14888 | Tmp = 25.14 | GyX = -35 | GyY = 239 | GyZ = -157 AcX = 2008 | AcY = -784 | AcZ = 15048 | Tmp = 25.19 | GyX = -3 | GyY = 342 | GyZ = -183 AcX = 1884 | AcY = -868 | AcZ = 15140 | Tmp = 25.19 | GyX = -3 | GyY = 214 | GyZ = -194 AcX = 2072 | AcY = -820 | AcZ = 15020 | Tmp = 25.28 | GyX = 41 | GyY = 157 | GyZ = -205 AcX = 2008 | AcY = -780 | AcZ = 15144 | Tmp = 25.24 | GyX = 0 | GyY = 220 | GyZ = -204 AcX = 1924 | AcY = -828 | AcZ = 14968 | Tmp = 25.24 | GyX = -9 | GyY = 254 | GyZ = -187 AcX = 1920 | AcY = -828 | AcZ = 14936 | Tmp = 25.33 | GyX = 7 | GyY = 253 | GyZ = -185 AcX = 2012 | AcY = -728 | AcZ = 14904 | Tmp = 25.14 | GyX = 16 | GyY = 190 | GyZ = -167 AcX = 1900 | AcY = -744 | AcZ = 15048 | Tmp = 25.42 | GyX = -4 | GyY = 162 | GyZ = -177 AcX = 1940 | AcY = -780 | AcZ = 14992 | Tmp = 25.28 | GyX = -34 | GyY = 271 | GyZ = -191 AcX = 1960 | AcY = -900 | AcZ = 15080 | Tmp = 25.38 | GyX = 2 | GyY = 194 | GyZ = -182
AcX = 1840 | AcY = -952 | AcZ = 15012 | Tmp = 25.38 | GyX = 19 | GyY = 272 | GyZ = -167
Вследствие нагревания феном для волос, значение Tmp = взлетело до 80. Далее покрутили в пространстве платкой — другие показания тоже изменяются, но это не наглядно.
Данные, выводимые вторым скетчем
InvenSense MPU-6050 June 2012 WHO_AM_I: 68, error = 0 PWR_MGMT_1: 40, error = 0 MPU-6050 Read accel, temp and gyro, error = 0 accel x,y,z: 12180, 9468, -9168 temperature: 22.153 degrees Celsius gyro x,y,z: -462, -5303, -490, MPU-6050 Read accel, temp and gyro, error = 0 accel x,y,z: 13204, 8928, -7420 temperature: 22.482 degrees Celsius gyro x,y,z: 282, -2012, -956, MPU-6050 Read accel, temp and gyro, error = 0 accel x,y,z: -1276, 7932, -16232 temperature: 22.435 degrees Celsius gyro x,y,z: -1168, 1159, 1258, MPU-6050 Read accel, temp and gyro, error = 0 accel x,y,z: 6216, 10604, -12796 temperature: 22.576 degrees Celsius gyro x,y,z: -2161, 4363, 2176,
Более приятный глазу пример описан в этой статье. Там реализована трансляция положения предмета в реальном времени! Для повторения эксперимента, нужно скачать по ссылкам в конце той статьи:
скетч для Ардуино — GY_521_send_serial (в atmega128 у меня залилось без проблем)
и прогу для 3D-рендеринга ShowGY521Data.
Последнюю нужно запускать в IDE Processing, статья была написана в 2013 году и для нормальной работы, качать лучше версию 1.5.1, в исходнике нужно подправить номер порта:
short portIndex = 1;
в строке 15 вместо 1 поставить порядковый номер COM-порта, но не номер из его имени (у меня, при подключении программатора, появляется один порт «COM15», я исправил на , если у Вас, допустим, есть порты «COM8» и «COM10», причем, последний соединён с Ардуино, то ничего исправлять не надо);
myPort = new Serial(this, portName, 38400);
в строке 42 поставить скорость, которая была в скетче для Ардуино — 19200. Запускаем программу…
видим три объекта, моделирующих гироскоп, акселерометр и нечто «средне».
При отклонении платы, объекты синхронно пляшут, акселерометр подёргивается реще
После определённого времени кручения платой, показания гироскопа сбиваются:это нормально и об этом написано в статье, упомянутой выше.
Примечательно, что если нажать ресет и перезагрузить плату в произвольном положении, то реальное положение в пространстве будет показывать акселерометр, гироскоп же сориентироваться в изначальное положение:Суть этого вяления раскрыта в первом комментарии к этой статье от AndyBig.
Думаю, можно будет реализовать с помощью этого модуля какую-нибудь «неваляшку», шлем обклеивать светодиодами как-то рука не поднимается.
Тентаклиевый монстр
, о котором я писал ранее, был пересмотрен, урезан и сокращён (кстати, на этом фото заметно отличие в качестве металлизации отверстий обозреваемой платы и дешевой платы Ардуино):
если отсоединить тентакли шлейф от креплений, то откроются два ряда контактов, у которых нужно «поотламывать половинки», — в результате получится разъем, удобно вставляющийся в отверстия макетной платы. Для пущей надёжности, нужно проклеить корпус, т.к. держаться на одних контактах конструкция не будет.
всё ещё может напугать, но на самом деле бояться нечего:
спаял с обратной стороны контакты, прозвонил их тестером — и можно подключать. Лично моя практика показывает, что лучше потратить пару секунд на предварительную проверку, чем ткнуть «не туда» и спалить девайс… Я так спалил Orange Pi PC =)
猫
Даташит на сенсор MPU-6050
Описание регистров MPU-6050
Неплохая статья
Товар предоставлен для написания обзора магазином. Обзор опубликован в соответствии с п.18 Правил сайта.
Планирую купить +39 Добавить в избранное Обзор понравился +20 +36
Источник: https://mysku.ru/blog/china-stores/40178.html
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” теперь возвращают корректные значения углов.
Глобальные переменные
Данный заголовочный файл включает в себя следующие глобальные переменные:
int accel_x_OC – Содержит измерения положения акселерометра относительно оси x при калибровке
int accel_y_OC – Содержит измерения положения акселерометра относительно оси y при калибровке
int accel_z_OC – Содержит измерения положения акселерометра относительно оси z при калибровке
int gyro_x_OC – Содержит измерения положения гироскопа относительно оси x
int gyro_y_OC – Содержит измерения положения гироскопа относительно оси y
int gyro_z_OC – Содержит измерения положения гироскопа относительно оси z
float temp_scalled – Содержит абсолютное значение температуры в градусах цельсия
float accel_x_scalled – данные оси x акселерометра минус данные калибровки
float accel_y_scalled – данные оси y акселерометра минус данные калибровки
float accel_z_scalled – данные оси z акселерометра минус данные калибровки
float gyro_x_scalled – данные гироскопа относительно оси x минус данные калибровки
float gyro_y_scalled – данные гироскопа относительно оси y минус данные калибровки
float gyro_z_scalled – данные гироскопа относительно оси z минус данные калибровки
Функции в программе Arduino для работы с mpu6050
MPU6050_ReadData()
Эта функция считывает данные с акселлерометра, гироскопа и датчика температуры. После считывания данных, значения переменных (temp_scalled, accel_x_scalled, accel_y_scalled, accel_z_scalled, gyro_x_scalled, gyro_y_scalled and gyro_z_scalled) обновляются.
MPU6050_ResetWake()
Эта функция сбрасывает настройки чипа на значения по-умолчанию. Рекомендуется использовать сброс настроек перед настройкой чипа на выполнения определенной задачи.
MPU6050_SetDLPF(int BW)
Эта функция настраивает встроенный фильтр низких частот. Переменная int BW должна содержать значения (0-6). Пропускная способность фильтра будет изменяться в соответствии с представленной ниже таблицей.
Если int BW не в диапазоне 0-6, фильтр низких частот отключается, что соответствует установке – бесконечность.
MPU6050_SetGains(int gyro,int accel)
Эта функция используется для установки максимального значения шкалы измерений
MPU6050_ReadData()
Эта функция использует масштабные коэффициенты для расчета результата. Если не используются значения (0-3), MPU6050_ReadData() отобразит необработанные значения с датчика с погрешностью калибровки. Для получения обработанных значений, установите переменные для калибровки (accel_x_OC, accel_y_OC, accel_z_OC, gyro_x_OC, gyro_y_OC and gyro_z_OC) в нуль.
MPU6050_OffsetCal()
Эта функция позволяет откалибровать акселерометр и гироскоп. Рассчитанные значения записываются в переменные accel_x_OC, accel_y_OC, accel_z_OC, gyro_x_OC, gyro_y_OC и gyro_z_OC для дальнейшей коррекции.
Для проведения калибровки необходимо расположить оси x и y axes платы MPU6050 в горизонтальной плоскости, а ось z – перпендикулярно к основанию. Даже незначительные перемещения платы во время калибровки понижают точность расчета базовой точки.
Ось z калибруется относительно силя земного притяжения – 9.81 м/с2 (1g), что учтено в коде.
Калибровка mpu6050
Калибровка гироскопа и акселерометра – это очень важный шаг. Приведенные значения для гироскопа имеют вид: “gyro_x_scalled = ”, так как для получения угла поворота относительно оси по данным угловой скорости, необходимо провести интегрирование.
Если “gyro_x_scalled” содержит ошибку или неверно выбрана база, эта ошибка также интегрируется и превращается в значительную погрешность в результате. Так что в идеале измерения должны показывать нуль, если гироскоп не движется вокруг каких-либо осей координат.
На практике добиться идеала практически невозможно, так что наша задача – минимизировать эту ошибку.
Кроме того, для компенсации «дрифта», можно использовать акселерометр для расчета угла наклона, сравнения полученных данных с результатами гироскопа и последующей компенсацией данной погрешности. Расчет угла будет рассмотрен в этой статье отдельно ниже.
На рисунках далее показано использование функции MPU6050_OffsetCal() непосредственно в программе в Arduino IDE.
Скетч Arduino для калибровки платы акселерометра/гироскопа MPU6050:
Результат работы скетча для калибровки в серийном мониторе
Расчет угла с помощью гироскопа 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 с).
Погрешность гироскопа – «дрифт» (drift)
Из-зза неидеальной калибровки гироскопа, “gyro_x_scalled” никогда не равна нулю и со временем “angle_x_gyro” изменяет свои значения.
Для решения данной проблемы, проводится расчет угла с помощью акселерометра и полученные значения сравнывиются с углом гироскопа. Так как модуль MPU6050 располагается горизонтально, ускорение по оси z равно 1g (то есть, 9.
81) как это показано на рисунке. Мы можем использовать этот вектор ускорения и его проекцию на ось y для расчета угла между осями x и y.
Угол, который рассчитывается с помощью акселерометра, рассчитывается по зависимости:
Основными проблемами при определении угла наклона с помощью акселерометра являются: сильная зашумленность сигнала и очень сильная чувствительность к вибрациям, без которых ни один механизм не работает.
Более того, еслипри перемещении MPU6050 вдоль одной из осей координат, полученные значения будут мешать расчету угла.
Так что для лучшего результата, углы с гироскопа и акселерометра объединяются с помощью фильтра:
Окончательно уравнение для определения угла наклона принимает вид:
На рисунке ниже приведена имплементация полученных зависимостей в оболочке Arduino IDE
Окончательный расчет угла наклона и подбор коэффициентов усиления для фильтра
Результаты снимались для различных параметров коэффициентов усиления фильтра и приведены на рисунках по порядку. Коэффициент усиления 1 означает, что фактически идут измерения только с гироскопа. Можно заметить, что в конце angle_x и angle_y отклоняются от значений, рассчитанных с помощью значений с акселерометра.
В моем случае, для дальнейшего проекта использовался коэффициент усиления 0.95. В зависимости от динамики системы, можно его повышать, но не до 1, так как значения будут сильно отклоняться от истинных.
Источник: http://arduino-diy.com/arduino-MPU6050-dlya-opredeleniya-ugla-naklona
Акселерометр и гироскоп MPU6050
Прежде чем приступить к рассмотрению модуля гироскопа и акселерометра, думаю, будет не лишним коротко разобраться что это такое. Гироскоп представляет собой устройство, реагирующее на изменение углов ориентации контролируемого тела. В классическом представлении это какой-то инерционный предмет, который быстро вращается на подвесах.
Как результат вращающийся предмет всегда будет сохранять свое направление, а по положению подвесов можно определить угол отклонения. На самом же деле электронные гироскопы построены по другой схеме и устроены немного сложнее (вращающийся волчок впихнуть в микросхему было бы не просто).
Акселерометр – это устройство, которое измеряет проекцию кажущегося ускорения, то есть разницы между истинным ускорением объекта и гравитационным ускорением. На простом примере такая система представляет собой некоторую массу, закрепленную на подвесе, обладающим упругостью (пружина для хорошего примера).
Так вот если такую систему повернуть под каким-то углом, или бросить, или предать линейное ускорение, то упругий подвес отреагирует на движение под действием массы и отклонится и вот по этому отклонению определяется ускорение.
Таким образом, гироскоп реагирует на изменение в пространстве независимо от направление движения, с помощью акселерометра же может измерять линейные ускорения предмета, а так же и искусственно рассчитываемое расположение предмета в пространстве. Каждое устройство имеет свои достоинства и недостатки.
Микросхема MPU6050 содержит на борту как акселерометр, так и гироскоп, а помимо этого еще и температурный сенсор. MPU6050 является главным элементом модуля GY-531.
Помимо этой микросхемы на плате модуля расположена необходимая обвязка MPU6050, в том числе подтягивающие резисторы интерфейса I2C, а также стабилизатор напряжения на 3,3 вольта с малым падением напряжения (при питании уже в 3,3 вольта на выходе стабилизатора будет 3 ровно вольта) с фильтрующими конденсаторами.
Ну и бонусом на плате распаян SMD светодиод с ограничивающим резистором как индикатор питающего напряжения. Размер платы модуля GY-521 10 х 20 мм.
Схема модуля представлена ниже (номиналы могут немного отличаться в разных версиях модуля):
Характеристики MPU6050:
- напряжения питания 2,375 – 3,46 вольт
- потребляемый ток до 4 мА
- интерфейс передачи данных – I2C
- максимальная скорость I2C – 400 кГц
- вход для других датчиков I2C
- внутренний генератор на 8 МГц (вне модуля возможность подключить внешний кварцевый резонатор на 32,768 кГц или 19,2 МГц)
Нужно отметить возможность MPU6050 работать в мастер режиме I2C для AUX выводов, к которым можно подключить еще один внешний датчик (например магнитометр). Честно говоря, я не понимаю для чего это вообще нужно, если проще подключать дополнительные датчики к общей шине I2C микроконтроллера.
Функции MPU6050:
- трех осевой MEMS гироскоп с 16 битным АЦП
- трех осевой MEMS акселерометр с 16 битным АЦП
- Digital Motion Processor (DMP)
- slave I2C для подключения к микроконтроллеру
- master I2C для подключения к микросхеме дополнительного датчика
- регистры данных датчиков
- FIFO
- прерывания
- температурный сенсор
- самопроверка гироскопа и акселерометра
- регистр идентификации устройства
Внешний вид модуля GY-521:
В комплекте идут штыревые соединения угловые и прямые. Припаян был прямой штыревой разъем.
Данные измерений датчиков можно считывать как из регистров хранения, так и пользоваться функциями FIFO.
Имеется отдельный регистр под названием Who am I, значение, записанное в этом регистре постоянно и его можно только считать, можно использовать как идентификатор устройства, значение в регистре 104 или 0х68.
Отдельным выводом является выход прерываний, который настраивается регистрами настройки под определенные события.
Датчики гироскопа и акселерометра изготовлены как MEMS (микроэлектромеханическая система) – внешнее воздействие на датчик сначала изменяет состояние механической части, затем изменение состояния механической части приводит к изменению сигнала электрической части.
Одним словом в одном корпусе собрана не только электроника, но и механика. В микросхеме MPU6050 содержится сразу два MEMS датчика, производитель утверждает, что их взаимное воздействие друг на друга сведено к минимуму. Ну что же, совсем не плохо за цену готового модуля порядка 2 уе.
Между прочим эти модули можно приобрести на торговых площадках aliexpress или ebay.
Разберемся как можно использовать датчики акселерометра и гироскопа. Температурный датчик трогать даже не будем – данные о температуре прочитали, перевели в человеческие значения и наслаждаемся. Гироскоп выдает значения мгновенной угловой скорости с разрешением, заданным в настройках, например 2000 градусов в секунду.
Если прошить микроконтроллер и смотреть на получаемые данные, то увидим только нули. Если начать крутить датчик, то получим мгновенные значения угловой скорости. Заметьте, что скорость мы получаем в градусах в секунду, а это значит, что линейные скорости не влияют на эти показания – показания будут изменяться только при повороте датчика в пространстве.
Далее с помощью этих данных можно получить ориентацию объекта в пространстве. Для этого нужно получить мгновенное значение угловой скорости и умножить его на промежуток времени между опросами датчика гироскопа.
Пример разрешение 2000 градусов в секунду, промежуток между опросами датчика 0,1 секунда, значение мгновенной скорости 300, значит 300*0,1=30 – за это время ось гироскопа была повернута на 30 градусов. Далее каждое полученное значение нужно сложить с предыдущим.
Если ось двигалась в одном направлении – значение 30 градусов, если в другом, то -30, таким образом, при возвращении датчика в исходное положение всегда (в идеале) будет 0, при отклонении от исходного положения, при выполнении вышеописанных действий, получим угол отклонения. Обрабатывая углы трех осей гироскопа можно получить ориентацию объекта в пространстве.
Таким образом, при интегрировании состояния угла положения, также интегрируется и погрешность – при длительном использовании можно получить уже абсолютно неправильные значения. Поэтому часто гироскоп используют в паре с акселерометром, образуя в простом варианте альфа-бета фильтр или комплементарный фильтр.
С акселерометром все проще. Измеряя ускорения трех осей датчика можно получить данные, преобразуя их с помощью геометрии, по которым можно также получить ориентацию объекта в пространстве.
Помимо этого акселерометр измеряет линейные ускорения, то есть ориентация объекта может искажаться при движении датчика в линейных направлениях. Также с помощью акселерометра можно определять движение объекта или его столкновение.
Например детектировать падение объекта или толчок о преграду, чтобы обходить это.
Данные от акселерометра получаем всегда достаточно точные, то есть нуль всегда остается нулем ни при каких воздействиях (имеется ввиду не зависит ни от времени, ни от характера воздействия), однако недостаток кроется в том, что данные идут шумом в некотором диапазоне данных, то есть до десятых долей градуса точно измерять угол не получится. Зато исходя из экспериментальных данных, точность до целых значений градуса держится вполне стабильно. Не забываем про влияние линейных ускорений.
Если датчик приобрели, можно переходить к рассмотрению внутренностей модуля, а именно главного элемента – микросхемы MPU6050. Информация хранится в регистрах микросхемы, которых более 100 (!). И вот тут то и кроется огромный подводный камень.
производитель не утрудился расписать в документации всю информацию, а привел лишь информацию о самом необходимом. На самом деле не известно даже сколько же всего там регистров, доступных для чтения или записи или того и другого. Также информации на некоторые регистры попросту нет, кроме его названия.
Ну что же, придется экспериментально определять влияния значений, записанных в некоторые регистры.
В конце статьи вы можете скачать исходный код примера использования данного модуля. Внутри вы найдете информацию о том как считывать данные датчиков модуля, а также инициализацию устройства или просто первоначальную настройку регистров для начала работы с модулем GY-521.
Интерфейс I2C работает по стандартной схеме. Адрес микросхемы может быть двух значений (без бита чтения / записи) в зависимости от состояния вывода AD0 – b1101000, если AD0 соединен с землей и b1101001, если AD0 соединен с источником питания. Соответственно плюс бит чтения или записи.
Микросхема содержит Digital Motion Processor (DMP), он необходим для того, чтобы обрабатывать данные, получаемые из датчиков гироскопа и акселерометра.
Все это делается для того, чтобы повысить точность получаемых данных, так как при обработке данных на микроконтроллере точность может пострадать из-за снижения скорости их обработки.
Как правило, алгоритмы обработки движения должны работать с достаточно высокой частотой, обычно 200 Гц, как утверждает документация.
Что касается регистров, то их достаточно большое количество, необходимая информация находится в карте регистров на MPU6050, документ прилагается к статье. Помимо этого прилагается исходник с настройками этих регистров.
Для демонстрации работы модуля была собрана схема:
Здесь использован микроконтроллер Atmega8, данные выводятся на ЖК дисплей 2004А (4 строки по 20 символов). На экран выводится следующая информация, полученная и преобразованная от микросхемы MPU6050 модуля: 1. значения по трем осям акселерометра, 2. значения по трем осям гироскопа, 3. температура, 4.
углы отклонения по данным акселерометра (рассчитаны ресурсами микроконтроллера), 5. поворот по оси Z по данным гироскопа (также путем подсчета микроконтроллером).
В первом и втором пункте данные имеют мгновенный характер – то есть именно то, что считывается из регистров хранения, это значит, что для гироскопа это скорость, в состоянии покоя все значения будут равны нулю.
Помимо этого, имеется 6 светодиодов, которые загораются в зависимости от положения датчика по оси Y акселерометра.
Модуль датчиков содержит уже стабилизатор на 3,3 вольта, поэтому его можно подключать как к 5 вольта, так и к 3,3 вольтам. Микроконтроллер запитывается от напряжения 3,3 вольта, чтобы не делать согласование уровней I2C.
Собранное устройство на макетной плате:
Для программирования микроконтроллера конфигурация фьюз битов (Atmega8):
Область применения таких датчиков достаточно широка. Данный модуль часто применяют для стабилизации полета квадрокоптера по причине совместного использования гироскопа и акселерометра.
Кроме этого модуль можно использовать для координации различных устройств – от просто детектора движения до системы ориентации различных роботов или управления движениями каким-либо устройствами.
Область подобных сенсорных устройств достаточно новая и интересная для изучения и применения в любительской технике.
В заключении хотелось бы отметить, что данные модуль – это недорогое и достаточно хорошее решение при необходимости использования гироскопа и / или акселерометра, большое количество настроек датчиков позволит настроить их под любые устройства, малые размеры модуля без труда позволят встраивать его в большинство схем.
К статье прилагается прошивка микроконтроллера, исходный код AVR Studio4, документация на MPU6050 и видео работы датчика в схеме.
Скачать список элементов (PDF)
Прикрепленные файлы:
Источник: http://cxem.net/mc/mc324.php
Библиотека Keypad для работы с клавиатурой на Arduino
Матричная клавиатура
Библиотека Keypad служит для использования совместно с Arduino клавиатур матричного типа. Текущая версия библиотеки (3.1) поддерживает множественные нажатия.
Данная библиотека была создана для создания уровня абстракции для аппаратного обеспечения. Она улучшает читаемость кода, скрывая от пользователя вызовы функций pinMode и digitalRead.
Версия 3.0 (опубликована 19 июля 2012) была переписана для поддержки по умолчанию множественных нажатий. Но для тех, кому всё еще изначальная функциональность с одиночными нажатиями, библиотека обеспечивает полную обратную совместимость.
Вам нет необходимости использовать внешние резисторы или диоды, так как библиотека использует внутренние подтягивающие резисторы в микроконтроллере на Arduino и дополнительно обеспечивает высокое входное сопротивление на всех неиспользуемых выводах столбцов.
Загрузка, установка и импорт
Данная библиотека сейчас доступна через менеджер библиотека в Arduino IDE. Если вы используете современную IDE (версия 1.6.2 и выше), то можете просто использовать меню:
Скетч → Подключить библиотеку → Управлять библиотеками… А затем найти Keypad.
Когда найдете, нажмите на записи, и появится кнопка «Установка». ZIP файл приведен ниже для старых версий IDE.
Скачать библиотеку Keypad версия 3.1.
Поместите каталок Keypad в “arduinolibraries”.
В Arduino IDE создайте новый скетч (или откройте существующий) и выберите в меню «Скетч → Импорт библиотеки → Keypad».
Когда библиотека импортирована, строка “#include ” появится в начале вашего скетча.
Создание
Конструкторы:
Keypad(makeKeymap(userKeymap), row[], col[], rows, cols)Создает объект Keypad, который использует (в примере ниже) выводы 5, 4, 3, 2 как выводы строк и выводы 8, 7, 6 как выводы столбцов. Эта клавиатура имеет 4 строки и 3 столбца, в итоге 12 кнопок.const byte rows = 4; // четыре строки const byte cols = 3; // три столбца char keys[rows][cols] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'#','0','*'} }; byte rowPins[rows] = {5, 4, 3, 2}; // подключить к выводам строк клавиатуры byte colPins[cols] = {8, 7, 6}; // подключить к выводам столбцов клавиатуры Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );
Функции
void begin(makeKeymap(userKeymap))Инициализирует внутреннюю раскладку клавиатуры, чтобы та соотвествовала userKeymap.char waitForKey()Данная функция будет ждать бесконечно, пока кто-нибудь не нажмет клавишу. Предупреждение: она блокирует весь остальной кода, пока кнопка не будет нажата.
Это означает, что не будет происходить ни мигание светодиода, ни обновление LCD дисплея, ничего, кроме выполнения функций прерываний.char getKey()Возвращает кнопку, которая нажата, если таковая имеется. Данная функция является неблокирующей.KeyState getState()Возвращает текущее состояние любой из клавиш. Возвращается одно из четырех состояний: IDLE, PRESSED, RELEASEDи HOLD.
boolean keyStateChanged()Дает вам знать, когда изменилось состояние кнопки. Например, вместо проверки нужной клавиши, вы можете проверить, когда клавиша была нажата.setHoldTime(unsigned int time)Устанавливает количество миллисекунд, которое пользователь должен удерживать кнопку нажатой, чтобы было вызвано состояние HOLD.
setDebounceTime(unsigned int time)Устанавливает количество миллисекунд, которое клавиатура ждет перед тем, как применить новое нажатие кнопки или событие кнопки. Это «время задержки» в методе обработки дребезга контактов.addEventListener(keypadEvent)Вызывает событие, если используется клавиатура.
#include const byte ROWS = 4; // четыре строки const byte COLS = 3; // три столбца char keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'} }; byte rowPins[ROWS] = {5, 4, 3, 2}; // подключить к выводам строк клавиатуры byte colPins[COLS] = {8, 7, 6}; // подключить к выводам столбцов клавиатуры Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); byte ledPin = 13; boolean blink = false; void setup(){ Serial.begin(9600); pinMode(ledPin, OUTPUT); // установить цифровой вывод на выход digitalWrite(ledPin, HIGH); // включить светодиод keypad.addEventListener(keypadEvent); // добавить слушателя события для данной клавиатуры } void loop(){ char key = keypad.getKey(); if (key) { Serial.println(key); } if (blink){ digitalWrite(ledPin,!digitalRead(ledPin)); delay(100); } } // обработать события: void keypadEvent(KeypadEvent key){ switch (keypad.getState()){ case PRESSED: switch (key){ case '#': digitalWrite(ledPin,!digitalRead(ledPin)); break; case '*': digitalWrite(ledPin,!digitalRead(ledPin)); break; } break; case RELEASED: switch (key){ case '*': digitalWrite(ledPin,!digitalRead(ledPin)); blink = false; break; } break; case HOLD: switch (key){ case '*': blink = true; break; } break; } }
Методы класса Keypadи определения для работы с множественными нажатиями:
Key key[LIST_MAX]Список активных клавиш. LIST_MAX (равен 10) задает максимальное количество клавиш в активном списке.bool getKeys()Заполняет массив keyактивных клавиш (до 10 значений). Возвращает trueпри наличии любых активных клавиш.bool isPressed(char keyChar)Возвращает true, если кнопка с кодом keyCharнажата.int findInList(char keyChar)Поиск клавиши по коду в списке активных клавиш. Возвращает -1, если клавиша не найдена, или индекс в массиве активных клавиш.
Пример
#include const byte ROWS = 4; //четыре строки const byte COLS = 3; //три столбца char keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'#','0','*'} }; byte rowPins[ROWS] = {5, 4, 3, 2}; //подключить к выводам строк клавиатуры byte colPins[COLS] = {8, 7, 6}; //подключить к выводам столбцов клавиатуры Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup(){ Serial.begin(9600); } void loop(){ char key = keypad.getKey(); if (key != NO_KEY){ Serial.println(key); } }
FAQ
Как я могу использовать несколько клавиатур?Keypad – это класс. Следовательно, для использования нескольких клавиатур вы должны создать объект класса для каждой из них. В примере выше экземпляр класса Keypad keypad был связан с цифровыми выводами 2, 3, 4, 5, 6, 7 и 8.
Чтобы добавить клавиатуру, подключенную к цифровым выводам 9, 10, 11, 12, 13, 14, 15 и 16, вы можете создать следующий объект keypad2:const byte ROWS2 = 4; // четыре строки const byte COLS2 = 4; // четыре столбца char keys2[ROWS2][COLS2] = { {'.
','a','d','1'}, {'g','j','m','2'}, {'p','t','w','3'}, {'*',' ','#','4'} }; byte rowPins2[ROWS2] = {12, 11, 10, 9}; // подключить к выводам строк клавиатуры byte colPins2[COLS2] = {16, 15, 14, 13}; // подключить к выводам столбцов клавиатуры Keypad keypad2 = Keypad( makeKeymap(keys2), rowPins2, colPins2, ROWS2, COLS2 );И теперь просто используйте нужные методы любой из клавиатур:void loop(){ char key1 = keypad.getKey(); char key2 = keypad2.getKey(); if (key1 != NO_KEY || key2 != NO_KEY){ Serial.print(“You pressed: “); Serial.print(key1 != NO_KEY ? key1 : “nothing on keypad”); Serial.print(” and “); Serial.print(key2 != NO_KEY ? key2 : “nothing on keypad2”); Serial.println(“.”); } }Как я могу использовать setDebounceTime(unsigned int time)?В Arduino IDE проследуйте по меню «Файл → Примеры → Keypad → DynamicKeypad». Когда скетч откроется, найдите функцию setup():void setup() { Serial.begin(9600); digitalWrite(ledPin, HIGH); // Включить светодиод. keypad.addEventListener(keypadEvent); // Добавить слушателя события. keypad.setHoldTime(500); // По умолчанию 1000 мс. keypad.setDebounceTime(250); // По умолчанию 50 мс. }Здесь показано, что время устранения дребезга контактов при нажатии кнопки устанавливается равным 250 миллисекунд. Если за это время происходит несколько нажатий на кнопку (что и происходит при дребезге контактов кнопки), то дополнительные нажатия просто игнорируются.
Оригинал статьи:
Источник: https://radioprog.ru/post/146