Съдържание:
- Стъпка 1: Модул MPU-6050
- Стъпка 2: Изчисления
- Стъпка 3: Връзки MPU6050-Atmega328p
- Стъпка 4: Кодове и обяснения
- Стъпка 5: Разбиране на ъгъла на накланяне
Видео: MPU 6050 Gyro, комуникация с акселерометър с Arduino (Atmega328p): 5 стъпки
2024 Автор: John Day | [email protected]. Последно модифициран: 2024-01-30 07:50
MPU6050 IMU има 3-осен акселерометър и 3-осен жироскоп, интегрирани в един чип.
Жироскопът измерва скоростта на въртене или скоростта на промяна на ъгловото положение във времето, по оста X, Y и Z.
Изходите на жироскопа са в градуси в секунда, така че за да получим ъгловата позиция, просто трябва да интегрираме ъгловата скорост.
От друга страна, акселерометърът MPU6050 измерва ускорението, като измерва гравитационното ускорение по трите оси и с помощта на математика на тригонометрията можем да изчислим ъгъла, под който е разположен сензорът. Така че, ако обединим или комбинираме данните за акселерометъра и жироскопа, можем да получим много точна информация за ориентацията на сензора.
3-осен жироскоп MPU-6050 се състои от 3-осен жироскоп, който може да открие скоростта на въртене по оста x, y, z с микроелектромеханична система (MEMS). Когато сензорът се завърти по която и да е ос, се получава вибрация поради ефекта на Кориолис, който се открива от MEMS. 16-битов ADC се използва за дигитализиране на напрежението, за да се вземе проба от всяка ос. +/- 250, +/- 500, +/- 1000, +/- 2000 са пълният обхват на изхода. Ъгловата скорост се измерва по всяка ос в градуси за секунда.
Полезна връзка: …………….
Arduino Board:. ……….
MPU6050 IMU ……………
Стъпка 1: Модул MPU-6050
Модулът MPU-6050 има 8 пина,
INT: Прекъснете изхода за цифров изход.
AD0: I2C подчинен адрес LSB щифт. Това е 0-и бит в 7-битов подчинен адрес на устройството. Ако е свързан към VCC, той се чете като логика и адресът на slave се променя.
XCL: Щифт за спомагателен сериен часовник. Този щифт се използва за свързване на други SCL щифтове с активиран I2C интерфейс към MPU-6050.
XDA: ПИН за спомагателни серийни данни. Този щифт се използва за свързване на други сензори с активиран I2C интерфейс SDA щифт към MPU-6050.
SCL: ПИН за сериен часовник. Свържете този щифт към SCL щифт на микроконтролери. SDA: ПИН за серийни данни. Свържете този щифт към щифт SDA на микроконтролери.
GND: Заземяващ щифт. Свържете този щифт към земната връзка.
VCC: Захранващ щифт. Свържете този щифт към +5V DC захранване. Модулът MPU-6050 има подчинен адрес (когато AD0 = 0, т.е. не е свързан към Vcc) като, Адрес за подчинен запис (SLA+W): 0xD0
Адрес за четене на подчинен (SLA+R): 0xD1
Стъпка 2: Изчисления
Данните на сензора за жироскоп и акселерометър на модула MPU6050 се състоят от 16-битови необработени данни във формата на 2 за допълване.
Данните за температурния сензор на модула MPU6050 се състоят от 16-битови данни (не във форма за допълване на 2).
Да предположим, че сме избрали,
- - Пълният диапазон на акселерометъра от +/- 2g с коефициент на скала на чувствителността 16, 384 LSB (брой)/g.
- - Жироскоп пълен мащаб от +/- 250 °/s с коефициент на скала на чувствителност 131 LSB (брой)/°/s. тогава,
За да получим необработени данни от сензора, първо трябва да извършим комплекта 2 върху сензорните данни на акселерометъра и жироскопа. След като получим необработени данни от сензора, можем да изчислим ускорението и ъгловата скорост, като разделим необработените данни от сензора с техния коефициент на скала на чувствителността, както следва-
Стойности на акселерометъра в g (g сила)
- Ускорение по оста X = (Акселерометър X ос необработени данни/16384) g.
- Ускорение по оста Y = (Акселерометър Y ос необработени данни/16384) g.
- Ускорение по оста Z = (Акселерометър Z ос необработени данни/16384) g.
Стойности на жироскопа в °/s (градуси в секунда)
- Ъглова скорост по оста X = (необработени данни от жироскоп X ос/131) °/s.
- Ъглова скорост по оста Y = (необработени данни по оста Y на жироскоп/131) °/s.
- Ъглова скорост по оста Z = (необработени данни от жироскоп Z ос/131) °/s.
Температурна стойност в °/c (градус на Целзий)
Температура в градуси C = ((данни от температурния сензор)/340 + 36,53) °/c.
Например, Да предположим, че след 2’допълнение получаваме сурова стойност на оси на акселерометър X = +15454
Тогава Ax = +15454/16384 = 0.94 g.
Повече ▼,
Така че знаем, че работим с чувствителност +/- 2G и +/- 250deg/s, но как нашите стойности съответстват на тези ускорения/ъгли.
И двете са праволинейни графики и от тях можем да разберем, че за 1G ще четем 16384, а за 1 градус/сек ще четем 131.07 (въпреки че.07 ще бъде игнориран поради двоично) тези стойности бяха просто разработени чрез изчертаване на праволинейна графика с 2G при 32767 и -2G при -32768 и 250/-250 при същите стойности.
Така че сега знаем нашите стойности на чувствителност (16384 и 131.07), просто трябва да намалим отклоненията от нашите стойности и след това да разделим на чувствителността.
Те ще работят добре за стойностите X и Y, но тъй като Z е записано на 1G, а не на 0, ще трябва да намалим 1G (16384), преди да разделим на нашата чувствителност.
Стъпка 3: Връзки MPU6050-Atmega328p
Просто свържете всичко, както е дадено на диаграмата …
Връзките са дадени, както следва:-
MPU6050 Arduino Nano
VCC 5v изход
GND Заземяващ щифт
SDA A4 пин // серийни данни
SCL A5 пин // сериен часовник
Изчисляване на височината и наклона: Roll е въртенето около оста x, а стъпката е въртенето по оста y.
Резултатът е в радиани. (конвертирайте в градуси, като умножите по 180 и разделите на pi)
Стъпка 4: Кодове и обяснения
/*
Arduino и MPU6050 Урок за акселерометър и сензор за жироскоп от Dejan, https://howtomechatronics.com */#include const int MPU = 0x68; // MPU6050 I2C адрес float AccX, AccY, AccZ; поплавък GyroX, GyroY, GyroZ; float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; поплавъчна ролка, стъпка, криволичене; float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ; float elapsedTime, currentTime, previousTime; int c = 0; void setup () {Serial.begin (19200); Wire.begin (); // Инициализиране на комуникацията Wire.beginTransmission (MPU); // Започнете комуникация с MPU6050 // MPU = 0x68 Wire.write (0x6B); // Говорете с регистъра 6B Wire.write (0x00); // Направете нулиране - поставете 0 в регистъра 6B Wire.endTransmission (вярно); // прекратяване на предаването/* // Конфигуриране на чувствителността на акселерометъра - пълен мащаб (по подразбиране +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Говорете с регистъра ACCEL_CONFIG (1C шестнадесетица) Wire.write (0x10); // Задайте регистърните битове като 00010000 (+/- 8g пълен мащаб) Wire.endTransmission (true); // Конфигуриране на чувствителност на жироскоп - пълен мащаб (по подразбиране +/- 250deg/s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Говорете с регистъра GYRO_CONFIG (1B шестнадесетичен) Wire.write (0x10); // Задайте регистърните битове като 00010000 (1000deg/s пълен мащаб) Wire.endTransmission (true); забавяне (20); */ // Извикайте тази функция, ако трябва да получите стойностите на IMU грешки за вашия модул Calculate_IMU_error (); забавяне (20); } void loop () {// === Четене на данни за ускорител === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Започнете с регистър 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, вярно); // Прочетете общо 6 регистри, всяка стойност на оста се съхранява в 2 регистри // За диапазон от +-2g, трябва да разделим необработените стойности на 16384, съгласно листа с данни AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // стойност на оста X AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // стойност на оста Y AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Стойност на оста Z // Изчисляване на Roll and Pitch от данните за акселерометъра accAngleX = (atan (AccY / sqrt (pow (AccX, 2) + pow (AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~ (0.58) Вижте персонализираната функция Calcu_MU_error () за повече подробности accAngleY = (atan (-1 * AccX / sqrt (pow (AccY, 2) + pow (AccZ, 2))) * * 180 / PI) + 1,58; // AccErrorY ~ (-1.58) // === Четене на данни от жироскоп === // previousTime = currentTime; // Предишното време се съхранява преди действителното време за четене currentTime = millis (); // Текущо време действително време за четене elapsedTime = (currentTime - previousTime) / 1000; // Делим на 1000, за да получим секунди Wire.beginTransmission (MPU); Wire.write (0x43); // Адрес на първия регистър на жироскопични данни 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, вярно); // Прочетете общо 4 регистъра, всяка ос се съхранява в 2 регистри GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // За диапазон от 250deg/ s трябва първо да разделим суровата стойност на 131.0, съгласно листа с данни GyroY = (Wire.read () << 8 | Wire.read ())/ 131.0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131.0; // Коригирайте изходите с изчислените стойности на грешка GyroX = GyroX + 0,56; // GyroErrorX ~ (-0,56) GyroY = GyroY - 2; // GyroErrorY ~ (2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0.8) // В момента необработените стойности са в градуси за секунди, deg/s, така че трябва да умножим по sendonds (s), за да получим ъгъла в градуси gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime; // Допълнителен филтър - комбинирайте ускорителя и стойностите на ъгъла на жироскопа roll = 0.96 * gyroAngleX + 0.04 * accAngleX; стъпка = 0,96 * gyroAngleY + 0,04 * accAngleY; // Отпечатайте стойностите на серийния монитор Serial.print (roll); Serial.print ("/"); Serial.print (стъпка); Serial.print ("/"); Serial.println (извиване); } void Calculate_IMU_error () {// Можем да извикаме тази функция в раздела за настройка, за да изчислим грешката на акселерометъра и жироскопа. От тук ще получим стойностите на грешките, използвани в горните уравнения, отпечатани на серийния монитор. // Обърнете внимание, че трябва да поставим IMU плосък, за да получим правилните стойности, така че след това да можем правилните стойности // Прочетете стойностите на акселерометъра 200 пъти докато (c <200) {Wire.beginTransmission (MPU); Wire.write (0x3B); Wire.endTransmission (невярно); Wire.requestFrom (MPU, 6, вярно); AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Сумира всички показания AccErrorX = AccErrorX + ((atan ((AccY) / sqrt (pow ((AccX), 2) + pow ((AccZ), 2))) * 180 / PI)); AccErrorY = AccErrorY + ((atan (-1 * (AccX) / sqrt (pow ((AccY), 2) + pow ((AccZ), 2))) * * 180 / PI)); c ++; } // Разделете сумата на 200, за да получите стойността на грешката AccErrorX = AccErrorX /200; AccErrorY = AccErrorY / 200; с = 0; // Прочетете стойностите на жироскопа 200 пъти докато (c <200) {Wire.beginTransmission (MPU); Wire.write (0x43); Wire.endTransmission (невярно); Wire.requestFrom (MPU, 6, вярно); GyroX = Wire.read () << 8 | Wire.read (); GyroY = Wire.read () << 8 | Wire.read (); GyroZ = Wire.read () << 8 | Wire.read (); // Сумира всички показания GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c ++; } // Разделете сумата на 200, за да получите стойността на грешката GyroErrorX = GyroErrorX /200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Отпечатайте стойностите на грешките на Serial Monitor Serial.print ("AccErrorX:"); Serial.println (AccErrorX); Serial.print ("AccErrorY:"); Serial.println (AccErrorY); Serial.print ("GyroErrorX:"); Serial.println (GyroErrorX); Serial.print ("GyroErrorY:"); Serial.println (GyroErrorY); Serial.print ("GyroErrorZ:"); Serial.println (GyroErrorZ); } ------------------------------------------------- ---------------------------------------------- Резултати:-X = Y = Z = --------------------------------------------- ----------------------------------------------- Важна забележка: -----------------
В раздела за цикъл започваме с четене на данните от акселерометъра. Данните за всяка ос се съхраняват в 2 байта или регистри и можем да видим адресите на тези регистри от листа с данни на сензора.
За да ги прочетем всички, започваме с първия регистър и използвайки функцията requiestFrom () искаме да прочетем всички 6 регистри за осите X, Y и Z. След това четем данните от всеки регистър и тъй като изходите се допълват две, ние ги комбинираме подходящо, за да получим правилните стойности.
Стъпка 5: Разбиране на ъгъла на накланяне
Акселерометър
Земната гравитация е постоянно ускорение, при което силата винаги е насочена надолу към центъра на Земята.
Когато акселерометърът е успореден на гравитацията, измереното ускорение ще бъде 1G, когато акселерометърът е перпендикулярен на гравитацията, той ще измерва 0G.
Ъгълът на наклон може да се изчисли от измереното ускорение, като се използва това уравнение:
θ = sin-1 (измерено ускорение / ускорение на тежестта)
GyroGyro (известен още като сензор за скорост) се използва за измерване на ъгловата скорост (ω).
За да получим ъгъла на наклон на робот, трябва да интегрираме данните от жироскопа, както е показано в уравнението по -долу:
ω = dθ / dt, θ = ∫ ω dt
Сливане на сензор за жироскоп и акселерометър След като изучихме характеристиките както на жироскопа, така и на акселерометъра, знаем, че те имат свои силни и слаби страни. Изчисленият ъгъл на наклон от данните за акселерометъра има бавно време за реакция, докато интегрираният ъгъл на наклон от данните на жироскопа е подложен на отклонение за определен период от време. С други думи, можем да кажем, че данните за акселерометъра са полезни в дългосрочен план, докато данните от жироскопа са полезни за краткосрочни.
Връзка за по -добро разбиране: Щракнете тук
Препоръчано:
DIY MPU-6050 USB джойстик: 5 стъпки
DIY MPU-6050 USB джойстик: С Microsoft Flight Simulator 2020 бързо разбрах колко е трудно да се използва клавиатура, за да се изпълни план. Търсейки онлайн, не можах да намеря джойстик на разумна цена за закупуване. Повечето онлайн търговци на дребно ги нямаха на склад. Популярността на М
Sistema De Prevenção De Deslizamentos Com Sensor MPU-6050: 6 стъпки
Sistema De Prevenção De Deslizamentos Com Sensor MPU-6050: O сензор MPU-6050 е чип с чип, който може да бъде използван за алармерен и гироскопичен тип MEMS. São 3 eixos para o acelerômetro e 3 eixos para o giroscópio, sendo ao todo 6 graus de liberdade (6DOF) .Vamos aprender a desenvolver um protótipo de um system de preven
Как да измервате ъгъла с MPU-6050 (GY-521): 3 стъпки
Как да измерваме ъгъла с MPU-6050 (GY-521): В тази инструкция ще измерваме ъгъла с Arduino. Нуждаем се от някои кабели, Arduino UNO и GY-521 (MPU-6050), за да измерим ъгъла
Регистриране на данни в реално време MPU-6050/A0 с Arduino и Android: 7 стъпки (със снимки)
Регистриране на данни в реално време MPU-6050/A0 с Arduino и Android: Интересувах се от използването на Arduino за машинно обучение. Като първа стъпка искам да изградя в реално време (или доста близо до него) дисплей и регистратор на данни с устройство с Android. Искам да записвам данни за акселерометър от MPU-6050, така че проектирам
Предварително* SPI на Pi: Комуникация с 3-осен акселерометър SPI с помощта на Raspberry Pi: 10 стъпки
Предварително* SPI на Pi: Комуникация с 3-осен акселерометър SPI с помощта на Raspberry Pi: Стъпка по стъпка ръководство за това как да настроите Raspbian и да комуникирате с SPI устройство с помощта на bcm2835 SPI библиотека (НЕ бит ударена!) Това все още е много предварително … Трябва да добавя по -добри снимки на физическо свързване и да преработя някои от неудобния код