1. Подключаемся. Согласно собственной спецификации, гироскоп-акселерометр GY-521, на одной микросхеме MPU6050 имеет в составе гироскоп на три координаты, акселерометр на три координаты, подтягивающие резисторы на плате и датчик температуры. Работает по шине IIS (I2C). Напряжение питания датчика - 3.3 вольта. Что это значит? Это значит, что если вы используете Arduino Pro mini, с логикой, работающей при макс. напряжении 3.3 вольта, то без особенных на то проблем вы датчик подключите.
Даже приведу схему подключения GY-521 к Arduino Pro Mini
Многие на форумах советуют между выводами SCL и GND, а так же SDA и GND поставить по подтягивающему резистору на 2.2 кОм. Это не лишено смысла. Возможно, они понадобятся. По крайней мере, хуже не станет. Если вы планируете повесить наоднушину несколькоустройств,то резисторы понадобятся обязательно.
Однако, если у вас другая плата, то потребуется немного похимичить, так как потребуется конвертер логических уровней.
Линейка плат Arduino начиная с маленькой Nano и кончая большой Mega работает с логикой, основывающейся на напряжении в 5 вольт. Это означает, что, как минимум, ваш датчик, рассчитанный на 3.3 В работатьоткажется, как максимум - сгорит. Чтобы этого не произошло, напряжение на шине нужно конвертировать в нужное.
Рассмотрим пример: Наверняка вам известно, что бинарнаялогика давно не оперирует такими величинами, как наличие и отсутствие напряжения. То есть, скажем, при передачи бита "1" в электронике применяется один уровень напряжения, а при передаче "0" - отнюдь не его отсутствие, а несколько пониженный уровень. В случае с Arduino - это 5в при передаче бита "1" и, поправьте меня, если это не так, 3.5в при передаче "0". В то же время датчик, работающий намаксимуме в 3.3в будет передавать "1" как 3.3в, а "0" как, скажем, 2.5в. Налицо несовпадение. Почему бы не поставить на выводы по резистору, скажете вы, и не превратить напряжение 5в в 3.3, и не напрягаться? Действительно, это будет работать, но в одну сторону - из Arduino в датчик. В обратную сторону, из датчика информация придти не сможет вовсе, поскольку даже единица в свои хилые 3.3 вольта, потеряясь на резисторе, не даст даже "0" для Arduino.
Чтобы разрешить этупроблему, потребуется двусторонний конвертер логических уровней, который можно купить здесь .
Но, это достаточно простое устройство, и его можно собрать самому. Потребуется всего лишь 4 резистора на 2.2 кОм и два МОСФЕТ-транзистора, типа 2N7000, или, на самом деле, любых других, рассчитанных на 5в. Схема сборки приведена здесь: https://www.sparkfun.com/products/8745
Поискав в интернете, можно найти схему на четырех транзисторах, для бедных, или даже на восьми диодах для совсем бедных, но это уже другая история.
Дело в другом - имея конвертер, мы можем с одной стороны работать с логикой на 5в, а с другой стороны - на 3в.
Подключается конвертер просто. Вывод конвертера GND - к выводу GND Arduino и к выводу GND датчика Вывод конвертера 5в - к выводу 5в Arduino Вывод конвертера 3.3в - к выводу 3.3в Arduino и к выводу VCC датчика Вывод конвертера SCL 5в - к выводу A5 Arduino (выводу 21 Mega) Вывод конвертера SDA 5в - к выводу A4 Arduino (выводу 20 Mega) Вывод конвертера SCL 3.3в - к выводу датчика SCL Вывод конвертера SDA 3.3в - к выводу датчика SDA Опционально: цифровой вывод 2 Arduino через резистор 2.2кОм к выводу INT датчика.
На этом все. Теперь можно загрузить скетч для проверки наличия устройств.
Код
// -------------------------------------- // i2c_scanner // // This program (or code that looks like it) // can be found in many places. // For example on the Arduino.cc forum. // The original author is not know. // // This sketch tests the standard 7-bit addresses // from 0 to 127. Devices with higher bit address // might not be seen properly. // // Adapted to be as simple as possible by Arduino.cc user Krodal // // June 2012 // Using Arduino 1.0.1 //
nDevices = 0; for(address = 0; address <= 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission();
if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !");
nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n");
delay(8000); // wait 8 seconds for next scan }
При выполнении скетча в мониторе порта вы должны увидеть хотя бы одно устройство. Либо "No I2C devices found", если конвертер либо устройство не работают. Если же устройство найдено, можно переходить к следующему шагу.
Добавлено (15.01.2013, 03:19) --------------------------------------------- 2. Получим, наконец, данные.
Если вы думаете, что все сразу и просто, то... Нет, не все так просто. Чтобы работать с устройством, понадобится библиотека для работы с этим устройством. Библиотеку с примерами вы можете скачать здесь: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 Ну, или просто скачать все библиотеки одним архивом отсюда: https://github.com/jrowberg/i2cdevlib/archive/master.zip Вытащить из архива две директории - I2Cdev и MPU6050 и положить в директорию среды разработки arduino/libraries
Теперь, перезапустив среду, вы можете выбрать из группы примеров MPU6050 два примера работы с датчиком.
Рассмотрим первый - DMP6. Первый потому, что сложный и потребует подключения вывода INT. Зато дает очень точные данные. Но на любителя, поскольку подойдет лишь для неподвижного устройства. Для устройств движущихся и вибрирующих при этом, такая точность необязательна.
Рассмотрим второй - RAW. Пример достаточно примитивен, но с некоторой долей ухищрения позволяет получить достаточно точные данные. Дело в том, что Arduino и датчик работают с разными частотами, и в момент чтения данных с датчика при несовпадении напряжений данные получаются с погрешностями. При использовании вывода INT частота получения данных задается как раз принудительно, поэтому данные получаются точнее.
Тем не менее, фильтрацию и отсеивание глюков рассмотрим в третьей части, а пока просто что-то получим.
Согласно примеру, можно получить голые данные с датчика таким образом:
Ну теперь самое простое, применить Фильтр Калмана и в бой ))).
Добавлено (29.01.2013, 01:23) --------------------------------------------- http://yadi.sk/d/QqbTn46_2BAnW Вот библиотека фильтра Кальмана А вот пример применения
/* Calculate the angls based on the different sensors and algorithm */ accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG; accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
// The accelerometer's maximum samples rate is 1kHz } void i2cWrite(uint8_t registerAddress, uint8_t data){ Wire.beginTransmission(IMUAddress); Wire.write(registerAddress); Wire.write(data); Wire.endTransmission(); // Send stop } uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) { uint8_t data[nbytes]; Wire.beginTransmission(IMUAddress); Wire.write(registerAddress); Wire.endTransmission(false); // Don't release the bus Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading for(uint8_t i = 0; i < nbytes; i++) data [i]= Wire.read(); return data; }
cmept-27, А как эти данные применить например к сервам? Например наклонил по оси Y повернулась одна серва Наклонил по оси Х повернулась другая серва? Если не сложно приведите пример.... Ну не знаю я