Подключаем акселерометр / гироскоп MPU-6050 (GY-521) к ARDUINO и серво двигателям (стабилизатор для камеры)

Квадрокоптеры
Содержание
  1. Ардуино леонардо подключился к mpu6500 с программой go для получения данных
  2. Выбор гироскопа: частота опроса и шумы
  3. Гироскоп и акселерометр полетного контроллера
  4. Гироскоп-акселерометр gy-521 при помощи arduino uno управляет работой коллекторного двигателя
  5. Гоночные полетные контроллеры
  6. Инвентированный сигнал и uart
  7. Кнопка для перехода в режим прошивки
  8. Контроллеры для автономных полетов
  9. Контроллеры для съемки видео и фото с дрона
  10. Общие сведения.
  11. Плата разводки питания (pdb)
  12. Подключаем акселерометр / гироскоп mpu-6050 (gy-521) к arduino и серво двигателям (стабилизатор для камеры)
  13. Подключение gy-521 к arduino
  14. Подключение к arduino
  15. Порт uart в полетном контроллере
  16. Процессор полетного контроллера
  17. Прошивки полетного контроллера, их виды
  18. Работа с arduino и mpu6050
  19. Размеры платы полетного контроллера
  20. Регулятор напряжения (bec)
  21. Регуляторы оборотов (esc)
  22. Сколько бывает портов uart на полетном контроллере?
  23. Тестирование
  24. Тестовая установка
  25. Типы коннекторов
  26. Характеристики:
  27. Черный ящик (blackbox)
  28. Заключение

Ардуино леонардо подключился к mpu6500 с программой go для получения данных

#include <Wire.h>
#include <TimerOne.h>

#define MPU9250_ADDRESS 0x68
#define MAG_ADDRESS 0x0C

#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)
{
// Set register address
Wire.beginTransmission(Address);
Wire.write(Register);
Wire.endTransmission();

// Read Nbytes
Wire.requestFrom(Address, Nbytes);
uint8_t index=0;
while (Wire.available())
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)
{
// Set register address
Wire.beginTransmission(Address);
Wire.write(Register);
Wire.write(Data);
Wire.endTransmission();
}

Смотрите про коптеры:  Please Wait...

// Initial time
long int ti;
volatile bool intFlag=false;

// Calcul the speed
int16_t Speed(int16_t Axyz, int16_t vi, int16_t t){
int16_t vf;
vf = vi (Axyz*t);
return vf;
}

int16_t Position(int16_t Vxyz, int16_t pi, int16_t t){
int16_t pf;
pf = pi (Vxyz*t);
return pf;
}

// Initializations
void setup()
{
// Arduino initializations
Wire.begin();
Serial.begin(115200);

// 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);

pinMode(13, OUTPUT);
Timer1.initialize(10000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt

// Store initial value
ti=millis();
}

// Counter
long int cpt=0;

void callback()
{
intFlag=true;
digitalWrite(13, digitalRead(13) ^ 1);
}

// Main loop, read and display data
void loop()
{
while (!intFlag);
intFlag=false;

// Display time
Serial.print (millis()-ti,DEC);
Serial.print («t»);

// _______________
// ::: Counter :::

// Display data counter
Serial.print (cpt ,DEC);
Serial.print («t»);

// ____________________________________
// ::: accelerometer and gyroscope :::

// Read accelerometer and gyroscope
uint8_t Buf[14];
I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);

// Create 16 bits values from 8 bits data

// Accelerometer
int16_t ax=-(Buf[0]<<8 | Buf[1]);
int16_t ay=-(Buf[2]<<8 | Buf[3]);
int16_t az=Buf[4]<<8 | Buf[5];

// Speed
int16_t vx= 0;
vx = Speed(ax,0,millis()-ti);
int16_t vy= 0;
vy = Speed(ay,0,millis()-ti);
int16_t vz= 0;
vz = Speed(az,0,millis()-ti);

//Position
int16_t px= 0;
px = Position(vx,0,millis()-ti);
int16_t py= 0;
py = Position(vy,0,millis()-ti);
int16_t pz= 0;
pz = Position(vz,0,millis()-ti);

// Gyroscope
int16_t gx=-(Buf[8]<<8 | Buf[9]);
int16_t gy=-(Buf[10]<<8 | Buf[11]);
int16_t gz=Buf[12]<<8 | Buf[13];

// Display values

// Accelerometer
//Serial.print («ax : «);
Serial.print (ax,DEC);
Serial.print (» «);
//Serial.print («ay : «);
Serial.print (ay,DEC);
Serial.print (» «);
//Serial.print («az : «);
Serial.print (az,DEC);
Serial.print (» «);

// Speed
// Serial.print («vx : «);
Serial.print (vx,DEC);
Serial.print (» «);
//Serial.print («vy : «);
Serial.print (vy,DEC);
Serial.print (» «);
// Serial.print («vz : «);
Serial.print (vz,DEC);
Serial.print (» «);

// Postion
//Serial.print («px : «);
Serial.print (px,DEC);
Serial.print (» «);
// Serial.print («py : «);
Serial.print (py,DEC);
Serial.print (» «);
// Serial.print («pz : «);
Serial.print (pz,DEC);
Serial.print (» «);

/*

// Gyroscope
Serial.print («gx : «);
Serial.print (gx,DEC);
Serial.print («t»);
Serial.print («gy : «);
Serial.print (gy,DEC);
Serial.print («t»);
Serial.print («gz : «);
Serial.print (gz,DEC);
Serial.print («t»);
*/

// _____________________
// ::: Magnetometer :::

// Read register Status 1 and wait for the DRDY: Data Ready

uint8_t ST1;
do
{
I2Cread(MAG_ADDRESS,0x02,1,&ST1);
}
while (!(ST1&0x01));

// Read magnetometer data
uint8_t Mag[7];
I2Cread(MAG_ADDRESS,0x03,7,Mag);

// Create 16 bits values from 8 bits data

// Magnetometer
int16_t mx=-(Mag[3]<<8 | Mag[2]);
int16_t my=-(Mag[1]<<8 | Mag[0]);
int16_t mz=-(Mag[5]<<8 | Mag[4]);

/*
// Magnetometer
Serial.print («mx : «);
Serial.print (mx 200,DEC);
Serial.print («t»);
Serial.print («my : «);
Serial.print (my-70,DEC);
Serial.print («t»);
Serial.print («mz : «);
Serial.print (mz-700,DEC);
Serial.print («t»);
*/

// End of line
Serial.println(«»);
delay(1000);

}

Выбор гироскопа: частота опроса и шумы

Есть два критерия, которые нужно учитывать при выборе полетного контроллера с конкретным гироскопом, это частота работы и чувствительность к шумам (электро- и механическим).

На сегодня самыми популярными и надежными считаются гироскопы MPU6000, у них частота работы 8KHz, а также они достаточно не чувствительны к шумам. Советуем не покупать полетные контроллеры с гироскопами MPU6500 и MPU9250, у них хоть и частота выше, но они больше подвержены воздействию шумов.

Серия гироскопов ICM работает лучше и плавнее, чем MPU6000 на 32KHz, но из-за шумных двигателей и регуляторов оборотов производительность ICM будет ниже, чем MPU6000. Например, ICM20602 на Raceflight Revolt V2 или ICM20689 на Kakute F4, оба этих гироскопа могут работать на частоте 32KHz, но с регуляторами оборотов, которые генерируют много шума, они работать будут хуже, чем MPU6000. По этой причине на полетные контроллеры устанавливают сетевые фильтры для частичного удаления шумов.

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

Гироскоп и акселерометр полетного контроллера

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

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

Гироскоп же выполняет роль определения положения квадрокоптера в пространстве.

Какие самые популярные гироскопы используются в полетных контроллерах? Смотрим таблицу ниже:

Гироскоп Протокол коммуникации (BUS) Макс. частота работы гироскопа
MPU6000 SPI, i2c 8K
MPU6050 i2c 4K
MPU6500 SPI, i2c 32K
MPU9150* i2c 4K
MPU9250* SPI, i2c 32K
ICM20602 SPI, i2c 32K
ICM20608 SPI, i2c 32K
ICM20689 SPI, i2c 32K

MPU9150 — это MPU6050 со встроенным магнитометром AK8975, а MPU9250 — это MPU6500 и тоже с магнитометром.

Номер и название гироскопа можно найти на самом чипе, например это — MPU-6000:

Гироскоп-акселерометр gy-521 при помощи arduino uno управляет работой коллекторного двигателя

Хочу вам, любителям помастерить, продемонстрировать свою наработку подключения коллекторного, в меру мощного электро двигателя в реверсивном режиме при помощи: драйвера двигателя BTS7960 43А, 27В

контроллера ARDUINO UNO
гироскопа-акселерометра GY-521 (MPU-6050)
скетча (программа для Arduino)
аккумулятора 24В
Электродвигателя МЭ 252Б

Электродвигатель МЭ 252Б насосного агрегата предпускового подогревателя дизельных двигателей КАМАЗ, УРАЛ, производитель СССР, а не Китай или РФ . Двигатель коллекторный, подсоединение обмоток параллельное. Чтобы вращение было реверсивным при смене полярности питания, катушку статора запитал через диодный мост KBPC5010 700В 50 А за 155 руб., исключив переполюсовку. Номинальная частота вращения, об/мин. — 6500

Управляет мотором драйвер двигателя BTS7960, мне обошелся в 1000 руб. с пересылкой. Он управляет одним коллекторным двигателем рассчитанным на напряжение от 5,5 до 27,5 В постоянного тока до 43 А. С помощью данного драйвера можно управлять скоростью двигателя, направлением его движения, выполнять торможение и контролировать нагрузку которую испытывает двигатель.

Назначение выводов
«M » и «M-» — Выходы для подключения мотора.
«M-» Выход левого плеча H-моста (чип U3).
«M » Выход правого плеча H-моста (чип U2).
«S » и «S-» — Питание мотора.
«Vcc» и «GND» — Питание логики.
«L_IS» — Выход состояния левого плеча H-моста (чип U3).
Вывод является флагом ошибки (если она есть), иначе с этого выхода можно снимать уровень напряжения пропорциональный току протекающему через мотор, а значит контролировать силу нагрузки приложенной к мотору.
«R_IS» — Выход состояния правого плеча H-моста (чип U2).
Вывод является флагом ошибки (если она есть), иначе с этого выхода можно снимать уровень напряжения пропорциональный току протекающему через мотор, а значит контролировать силу нагрузки приложенной к мотору.
«L_EN» — Вход разрешения работы левого плеча H-моста (чип U3).
Сброс в 0 — отключает выход мотора «M-» (переводит его в состояние высокого импеданса).
Установка в 1 — разрешает работу выхода мотора «M-».
«R_EN» — Вход разрешения работы правого плеча H-моста (чип U2).
Сброс в 0 — отключает выход мотора «M » (переводит его в состояние высокого импеданса).
Установка в 1 — разрешает работу выхода мотора «M ».
«L_PWM» — Вход установки потенциала на выходе левого плеча H-моста (чип U3).
Сброс в 0 — устанавливает на выходе «M-» потенциал вывода «S-».
Установка в 1 — устанавливает на выходе «M-» потенциал вывода «S ».
Установка потенциалов «S » или «S-» на выходе «M-» возможна только если установлена 1 на входе «L_EN».
«R_PWM» — Вход установки потенциала на выходе правого плеча H-моста (чип U2).
Сброс в 0 — устанавливает на выходе «M » потенциал вывода «S-».
Установка в 1 — устанавливает на выходе «M » потенциал вывода «S ».
Установка потенциалов «S » или «S-» на выходе «M » возможна только если установлена 1 на входе «R_EN»

ARDUINO UNO 700 руб. (

купить на Али

) это мозги — комбинация аппаратной и программной частей для простой разработки электроники. Для Ардуино есть огромное количество инструкций и готовых скетчей. Легко сможете повторить любой проект, доработать его или адаптировать под свои нужны.

MPU-6050 GY-521 стоимостью 151 руб. (купить на Али) – компактный и легкий модуль 3х осевого акселерометра и 3х осевой гироскоп. Отличное решение для систем балансировки и ориентирования роботов и полуавтоматических устройств типа вертолётов, самолётов, квадрокоптеров. Сопрягается с Arduino и прочими микроконтроллерными устройствами по шине I2C.

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

В ARDUINO UNO надо вставить программу. Для этого ищем в интернете arduino-1.8.12-windows, скачиваем и устанавливаем в компьютер.

Там же в интернете находим I2Cdev, MPU6050 и вставляем в библиотеку. Переносим скетч

скетч от Circuit Magic слегка уменьшил задержку

#include 
#include
#include 
MPU6050 mpu; 
int16_t ax, ay, az;
int16_t gx, gy, gz;
#define pin1 3
#define pin2 5 
void setup(){
 Serial.begin(9600);
 Serial.println("Initialize MPU");
 mpu.initialize();
 //Serial.println(mpu.testConnection() ? "Connected" : "Connection failed"); pinMode(pin1,OUTPUT);
 pinMode(pin2,OUTPUT);
} 
void loop(){
 mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
 ax = map(ax, -17000, 17000, -1500, 1500);
 //Serial.println(ax);
 if(ax &gt; 0){
  if(ax&lt;255){
  Serial.println(ax);
  analogWrite(pin2,ax);
 }
 else{
  Serial.println(" 255");
  analogWrite(pin2,255);
 }
 }
 if(ax&lt;0){
  if(ax&gt;-255){
  Serial.println(ax);
  analogWrite(pin1, ax-ax-ax);
 }
 else{
  Serial.println("-255");
  analogWrite(pin1, 255);
 }
 }
 delay(100);
}

Схема подключения

Проверим как работает ARDUINO UNO и Гироскоп-акселерометр с загруженной программой. Правильно ли скетч обрабатывает полученную информацию от гироскопа в ARDUINO UNO. То есть любой наклон в пространстве должен вызвать активность эл. двигателя

Как видим все работает исправно. Можете применять скетч, проблем не будет. Спасибо за внимание

Гоночные полетные контроллеры

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

Naze32, также на базе этого контроллера есть SP Racing F3:

На нем присутствуют все стандартные датчики – гироскоп и акселерометр, а в расширенной версии DELUXE также есть барометр и компас.

Гироскоп и акселерометр определяют текущее расположение дрона в пространстве. Барометр определяет высоту по давлению (чтобы удерживать высоту, например), компас для удержания направления полета.

На сегодня, полетные контроллеры серии F4 являются самыми популярными полетными контроллерами для мини и гоночных квадрокоптеров, так как прекрасно работают с такими программами, как CleanFlight, Betaflight и Raceflight. На их смену уже выходит серия F7, становясь все более популярной.

Разработка прошивок для полетного контроллера F3 уже прекратилась из-за ограничения ресурсов, поэтому выбирайте для покупки F4 или F7:

Betaflight прекращает разработку ПО для полетных контроллеров F3 c STM32F3

Также еще два популярных контроллера:

KISS – прошивать своей прошивкой нельзя. Имеет графический интерфейс с минимумом настроек.

LUX – такой же гибкий, как Naze32, но все же уступает ему. Прошивать можно.

Инвентированный сигнал и uart

Инвентированный сигнал поддерживают полетные контроллеры 3-го и 7-го поколения, а вот 1-е и 4-е поколения не могут.

Передатчики FrSky с протоколом работы SBUS и SmartPort на выходе инвертируют свой сигнал, и их могут обработать только процессоры нового поколения, такие установлены на 7-м и 3-м поколении (F3 и F7), так как у них уже есть встроенный инвертор.

А вот для устаревших поколений (F1 и F4) нужно перед портом UART устанавливать инвертор, который будет обрабатывать и преобразовывать сигнал и передавать его уже в UART. Хотя в некоторых полетных контроллерах F4 производители сразу устанавливают инверторы для SBUS и SmartPort, пилоту можно сразу подключать приемник к ПК.

Если у вас закончились UART порты, то можно воспользоваться функцией в Betaflight «soft-serial», благодаря которой можно создавать виртуальные UART. С помощью ПО Betaflight создается эмуляция этого порта, как будто он есть физически, но на самом деле его нет.

Кнопка для перехода в режим прошивки

Без такой кнопки не обойтись ни одному полетному контроллеру. Для прошивки замыкают 2 контакта, затем подключают к компьютеру и запускают Betaflight конфигуратор или любой другой. Есть два типа:

С кнопкой удобнее — нажал отверткой и все, а вот для контактов нужно использовать пинцет или скрепку, чтобы закоротить их.

Контроллеры для автономных полетов

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

MultiWii Pro — дешевый и доступный, позволяет отлично стабилизировать коптер, также на нем есть барометр, магнитометр и GPS.

Теперь, после краткого обзора типов полетных контроллеров, перейдем к полному описанию.

Контроллеры для съемки видео и фото с дрона

Полетный контроллер, для чего он нуженСамым популярным в этом сегменте коптеров является DJI NAZA-M V2: тот самый, что стоит в Фантомах. Идеальный контроллер для фото- и видеосъемки с качественной стабилизацией. На нем спокойно сможет летать новичок, который до этого ни разу не брал пульт в руки. В настройки полета лезть не требуется, все уже настроено, нужно будет просто откалибровать. Даже без навыков у новичка-пилота получится отличный кадр.

Поддерживает весь набор датчиков (GPS, телеметрию, OSD  и т.д.)

ArduPilot AMP поддерживает GPS и автономный полет по заданным координатам. Тоже достаточно популярный контроллер, но стоит дороже обычных из-за наличия более важных датчиков.

Vector Flight Controller-  профессиональный полетный контроллер с встроенной системой Eagle Tree.

Новичок тоже сможет на таком летать. Эти контроллеры стоят дорого, а вес и размер стремятся к идеалу для аэросъемки.

Общие сведения.

Основная микросхема модуль GY-521 чип MPU-6050 , который содержит в себе акселерометр и гироскоп, а так же датчик температуры. Обработка данных осуществляется с помощью 16-битное АЦП (Аналого-цифровой преобразователь) на каждый канал, поэтому он обрабатывает значение x, y и z одновременно.

Встроенный датчик температуры предназначен для измерения температуры и имеет диапазон измерений от -40 ° С до 85 ° С.Для взаимодействия с Arduino используется шина I2C и датчик MPU-6050 всегда выступает в качестве подчиненного устройства. Но кроме обычной шины I2C, есть собственный контроллер I2C, в котором MPU-6050 ведомый, выводы SDAи XDA и с помощью это шины можно управлять например магнитометром и передавать данные на Arduino.

Датчика MPU-6050 работает от напряжение ~2.4 — 3.5 В и чтобы стабилизировать питание, на модуле GY-521 добавили стабилизатор напряжения на 3.3 В с малым падением напряжении, поэтому модуль можно подключить к напряжению 5 В и 3.3 В.

Назначение выводов:►  VCC – « » питание модуля 3.3 В до 5 В ►  GND – «-» питание модуля►  SCL – линия синхронизации для протокола I2C►  SDA – линия передачи данных протокола I2C►  XDA – линия передачи данных протокола при работе в режиме мастера►  XCL – линия синхронизации для протокола I2C при работе в режиме мастера►  AD0 – если вывод лог «0» адрес I2C будет 0x68, если вывод лог «1» адрес I2C будет 0x69►  INT – прерывание

Плата разводки питания (pdb)

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

Подключаем акселерометр / гироскоп mpu-6050 (gy-521) к arduino и серво двигателям (стабилизатор для камеры)

Немного информации по проекту : 

Датчик  MPU-6050 содержит в себе интегрированный 3х-осевой акселерометр и построен на базе MEMS  3х-осевом MEMS-гироскопе. С помощью гироскопа мы можем измерить угловое ускорение тела на собственной оси, а с помощью акселерометра мы можем измерить ускорение тела вдоль одного направления. Он очень точен, поскольку он имеет 16-разрядный AD (от аналого-цифрового) преобразователя для каждого канала. Поэтому он захватывает оси  x, y и z одновременно. Датчик имеет стандартный протокол связи I²C, поэтому его легко подключить к ардуино .

Датчик MPU-6050 даже не стоит дорого, возможно, он самый дешевый на рынке, особенно учитывая тот факт, что он сочетает в себе акселерометр и гироскоп.

Я отобрал самые дешевые варианты на алиэкспресс :

Купить  MPU-6050   http://ali.pub/26g64n 

Для удобства ардуино уно http://ali.pub/26g69b  

Сервоприводы SG 90  http://ali.pub/26g6ek  

(Я рекомендую использовать более с мет. шестернями )

  VG996R     http://ali.pub/26g6jf 

Комплект из 4 штук — дешевле http://ali.pub/26g6mc 

Схематика и характеристики датчика гироскопа :

mpu6050-assi

Вот некоторые особенности датчика MPU-6050:

Чип со встроенным 16-разрядным АЦП-преобразователем

Диапазон измерения гироскопа: ± 250, 500, 1000 и 2000 ° / с

Диапазон измерения акселерометра: 2, 4, 8, 16 г

Интерфейс: I²C

Питание: от 3 до 5 В

Вы можете найти спецификацию MPU-6050 ЗДЕСЬ.

Для моих тестов я купил модуль GY-521 — плату с обвесом . Ниже приведена схема подключения модуля GY-521 для тех, кто хочет разобраться :

GY-521

Рассмотрим подробнее работу датчика с платой Ардуино :

           

Ардуино , гироскоп и 2 серво привода :      Prog_GY-521_Servo_Schema

GY-521 Arduino Uno
VCC 3.3V
GNS GND
SCL A5
SDA A4

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

Prog_GY-521_Servo_BreadBoard


Как видно из электрической схемы, я приводил в действие два серводвигателя с внешним источником питания 5 В (это связано с тем, что  сервомоторы вместе потребляют более 500 мА (500 мА = максимальный ток, поставляемый USB-портом версии 2.0 )). Теперь перейдем к коду, чтобы загрузить в  Arduino.

// MPU6050 & Servo

// byDenisGeek

#include <SPI.h>

#include <Wire.h>

#include <Servo.h>

#define MPU 0x68  // I2C address of the MPU-6050

Servo ServoX, ServoY;

double AcX,AcY,AcZ;

int Pitch, Roll;

void setup(){

  Serial.begin(9600);

  ServoX.attach(8);

  ServoY.attach(9);

  init_MPU(); // Inizializzazione MPU6050

}

void loop()

{

  FunctionsMPU(); // Acquisisco assi AcX, AcY, AcZ.

  Roll = FunctionsPitchRoll(AcX, AcY, AcZ);   //Calcolo angolo Roll

  Pitch = FunctionsPitchRoll(AcY, AcX, AcZ);  //Calcolo angolo Pitch

  int ServoRoll = map(Roll, -90, 90, 0, 179);

  int ServoPitch = map(Pitch, -90, 90, 179, 0);

  ServoX.write(ServoRoll);

  ServoY.write(ServoPitch);

  Serial.print(«Pitch: «); Serial.print(Pitch);

  Serial.print(«t»);

  Serial.print(«Roll: «); Serial.print(Roll);

  Serial.print(«n»);

}

void init_MPU(){

  Wire.begin();

  Wire.beginTransmission(MPU);

  Wire.write(0x6B);  // PWR_MGMT_1 register

  Wire.write(0);     // set to zero (wakes up the MPU-6050)

  Wire.endTransmission(true);

  delay(1000);

}

//Funzione per il calcolo degli angoli Pitch e Roll

double FunctionsPitchRoll(double A, double B, double C){

  double DatoA, DatoB, Value;

  DatoA = A;

  DatoB = (B*B) (C*C);

  DatoB = sqrt(DatoB);

  Value = atan2(DatoA, DatoB);

  Value = Value * 180/3.14;

  return (int)Value;

}

//Funzione per l’acquisizione degli assi X,Y,Z del MPU6050

void FunctionsMPU(){

  Wire.beginTransmission(MPU);

  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)

  Wire.endTransmission(false);

  Wire.requestFrom(MPU,6,true);  // request a total of 14 registers

  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     

  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)

  AcZ=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)

}



Я надеюсь этот материал вам был полезен , так же с вопросами и предложениями можно ко мне в группу : 

Подписывайся на Geek каналы :

➤ VK — https://vk.com/denis_geek

➤ VK — https://vk.com/club_arduino

➤ VK — https://vk.com/chinagreat

➤ VK — https://vk.com/solar_pover

➤ VK — https://vk.com/my_vedroid

➤ VK — https://vk.com/3dprintsumy

➤ Youtube — http://www.radiocopter.ru/c/Danterayne

★ Моя партнёрка с Aliexpress ★

http://ali.pub/1j9ks1 

★ Получай 10.5% скидку с любой покупки на Aliexpress! ★

http://ali.pub/1lx67o

★ Полезное браузерное приложение для кэшбэка  ★

http://ali.pub/1lx637

Подключение gy-521 к arduino

Необходимые детали:► Arduino UNO R3 x 1 шт.► Провод DuPont, 2,54 мм, 20 см x 1 шт.► Кабель USB 2.0 A-B x 1 шт.► 3-осевой гироскоп акселерометр GY-521 x 1 шт.

Подключение:В примере будем использовать только первые четыре контакта VCC, GND, SDA и SCL. Сначала подключаем VCC и GND модуля GY-521 к 5V и GND. Далее нужно установить соединение I2C между модулем GY-521 и Arduino, для этого подключите вывод SCL модуля к выводу А4 Arduino и вывод модуля SCL к выводу A5 Arduino. Для удобства приведу схему подключение.

Подключение к arduino

Для интерфейса

I2C

у Ардуино имеются контакты A4 (SDA) и A5 (SCL), да-а, это те, которые расположены чёрти-где (на одной плате у меня они были справа от контроллера, на другой с левого края). В коде нужно использовать библиотеку Wire, прочитать о ней можно

. Минимальная схема во Fritzing такая:

… а значит у нас уже не 8 лишних штырьков, а целых двенадцать!

Порт uart в полетном контроллере

Аббревиатура UART с английского расшифровывается как (Universal Asynchronous Receiver/Transmitter) — универсальный асинхронный приемник/передатчик.

К порту UART подключаются различные периферийные устройства, такие как, приемник, различная телеметрия и так далее. У порта есть два контакта для обмена данными — прием и передача.

На фото ниже вы можете увидеть пример UART порта и их настройки в Betaflight, точнее, вы можете назначить в этой вкладке порту любое устройство, которое поддерживает обмен данными:

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

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

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

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

Прошивки полетного контроллера, их виды

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

Как уже написано выше, на сегодня самыми популярными прошивками являются:

Что из себя представляет программное обеспечение полетного контроллера — прошивка? Это набор правил и алгоритмов, которые обрабатывает процессор.

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

Работа с arduino и mpu6050


Для достижения максимальной точности измерений нужно откалибровать акселерометр и гироскоп. Калибровка акселерометра позволяет выставить “ноль” для вектора силы тяжести, а калибровка гироскопа уменьшает его “дрифт”, то есть статическое отклонение в режиме покоя. Идеально откалиброванный и лежащий горизонтально датчик должен показывать ускорение ~16384 по оси Z и нули по всем остальным осям ускорения и угловой скорости. Но это фантастика =)

Максимально правильно использовать калибровку в проекте нужно так: калибровка по запросу (кнопка, меню, и т.д.), затем запись калибровочных значений в EEPROM. При запуске – чтение и настройка оффсетов из. Рассмотрим несколько примеров калибровки, первый – из библиотеки. Калибрует долго, но максимально точно. При малых вибрациях и движениях датчика в процессе калибровки (даже от громкого звука) калибровка может не закончиться. Второй вариант – мой упрощённый алгоритм калибровки, калибрует быстро, без возможности зависнуть при тряске, но даёт менее точный результат. Я делюсь примерами, в свой проект их нужно будет переносить вручную и аккуратно =)

// положи датчик горизонтально, надписями вверх
// ДАЖЕ НЕ ДЫШИ НА НЕГО
// отправь любой символ в сериал, чтобы начать калибровку
// жди результатов

// --------------------- НАСТРОЙКИ ----------------------
const int buffersize = 70;     // количество итераций калибровки
const int acel_deadzone = 10;  // точность калибровки акселерометра (по умолчанию 8)
const int gyro_deadzone = 6;   // точность калибровки гироскопа (по умолчанию 2)
// --------------------- НАСТРОЙКИ ----------------------

#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

MPU6050 mpu(0x68);

int16_t ax, ay, az, gx, gy, gz;

int mean_ax, mean_ay, mean_az, mean_gx, mean_gy, mean_gz, state = 0;
int ax_offset, ay_offset, az_offset, gx_offset, gy_offset, gz_offset;

///////////////////////////////////   SETUP   ////////////////////////////////////
void setup() {
  Wire.begin();
  Serial.begin(9600);
  mpu.initialize();

  // ждём очистки сериал
  while (Serial.available() && Serial.read()); // чистим
  while (!Serial.available()) {
    Serial.println(F("Send any character to start sketch.n"));
    delay(1500);
  }
  while (Serial.available() && Serial.read()); // чистим ещё на всякий

  Serial.println("nMPU6050 Calibration Sketch");
  delay(2000);
  Serial.println("nYour MPU6050 should be placed in horizontal position, with package letters facing up. nDon't touch it until you see a finish message.n");
  delay(3000);
  // проверка соединения
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  delay(1000);
  // сбросить оффсеты
  mpu.setXAccelOffset(0);
  mpu.setYAccelOffset(0);
  mpu.setZAccelOffset(0);
  mpu.setXGyroOffset(0);
  mpu.setYGyroOffset(0);
  mpu.setZGyroOffset(0);
}

///////////////////////////////////   LOOP   ////////////////////////////////////
void loop() {
  if (state == 0) {
    Serial.println("nReading sensors for first time...");
    meansensors();
    state  ;
    delay(1000);
  }

  if (state == 1) {
    Serial.println("nCalculating offsets...");
    calibration();
    state  ;
    delay(1000);
  }

  if (state == 2) {
    meansensors();
    Serial.println("nFINISHED!");
    Serial.print("nSensor readings with offsets:t");
    Serial.print(mean_ax);
    Serial.print("t");
    Serial.print(mean_ay);
    Serial.print("t");
    Serial.print(mean_az);
    Serial.print("t");
    Serial.print(mean_gx);
    Serial.print("t");
    Serial.print(mean_gy);
    Serial.print("t");
    Serial.println(mean_gz);
    Serial.print("Your offsets:t");
    Serial.print(ax_offset);
    Serial.print(", ");
    Serial.print(ay_offset);
    Serial.print(", ");
    Serial.print(az_offset);
    Serial.print(", ");
    Serial.print(gx_offset);
    Serial.print(", ");
    Serial.print(gy_offset);
    Serial.print(", ");
    Serial.println(gz_offset);
    Serial.println("nData is printed as: acelX acelY acelZ giroX giroY giroZ");
    Serial.println("Check that your sensor readings are close to 0 0 16384 0 0 0");
    Serial.println("If calibration was succesful write down your offsets so you can set them in your projects using something similar to mpu.setXAccelOffset(youroffset)");
    while (1);
  }
}

///////////////////////////////////   FUNCTIONS   ////////////////////////////////////
void meansensors() {
  long i = 0, buff_ax = 0, buff_ay = 0, buff_az = 0, buff_gx = 0, buff_gy = 0, buff_gz = 0;

  while (i < (buffersize   101)) { // read raw accel/gyro measurements from device mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); if (i > 100 && i <= (buffersize   100)) { //First 100 measures are discarded
      buff_ax = buff_ax   ax;
      buff_ay = buff_ay   ay;
      buff_az = buff_az   az;
      buff_gx = buff_gx   gx;
      buff_gy = buff_gy   gy;
      buff_gz = buff_gz   gz;
    }
    if (i == (buffersize   100)) {
      mean_ax = buff_ax / buffersize;
      mean_ay = buff_ay / buffersize;
      mean_az = buff_az / buffersize;
      mean_gx = buff_gx / buffersize;
      mean_gy = buff_gy / buffersize;
      mean_gz = buff_gz / buffersize;
    }
    i  ;
    delay(2);
  }
}

void calibration() {
  ax_offset = -mean_ax / 8;
  ay_offset = -mean_ay / 8;
  az_offset = (16384 - mean_az) / 8;

  gx_offset = -mean_gx / 4;
  gy_offset = -mean_gy / 4;
  gz_offset = -mean_gz / 4;
  while (1) {
    int ready = 0;
    mpu.setXAccelOffset(ax_offset);
    mpu.setYAccelOffset(ay_offset);
    mpu.setZAccelOffset(az_offset);

    mpu.setXGyroOffset(gx_offset);
    mpu.setYGyroOffset(gy_offset);
    mpu.setZGyroOffset(gz_offset);

    meansensors();
    Serial.println("...");

    if (abs(mean_ax) <= acel_deadzone) ready  ;
    else ax_offset = ax_offset - mean_ax / acel_deadzone;

    if (abs(mean_ay) <= acel_deadzone) ready  ;
    else ay_offset = ay_offset - mean_ay / acel_deadzone;

    if (abs(16384 - mean_az) <= acel_deadzone) ready  ;
    else az_offset = az_offset   (16384 - mean_az) / acel_deadzone;

    if (abs(mean_gx) <= gyro_deadzone) ready  ;
    else gx_offset = gx_offset - mean_gx / (gyro_deadzone   1);

    if (abs(mean_gy) <= gyro_deadzone) ready  ;
    else gy_offset = gy_offset - mean_gy / (gyro_deadzone   1);

    if (abs(mean_gz) <= gyro_deadzone) ready  ;
    else gz_offset = gz_offset - mean_gz / (gyro_deadzone   1);

    if (ready == 6) break;
  }
}
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
MPU6050 mpu;

#define BUFFER_SIZE 100

int16_t ax, ay, az;
int16_t gx, gy, gz;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  mpu.initialize();

  mpu.setXAccelOffset(0);
  mpu.setYAccelOffset(0);
  mpu.setZAccelOffset(0);
  mpu.setXGyroOffset(0);
  mpu.setYGyroOffset(0);
  mpu.setZGyroOffset(0);

  Serial.println(F("Send any character to start sketch"));
  delay(100);
  while (1) {  						  //входим в бесконечный цикл
    if (Serial.available() > 0) {     //если нажата любая кнопка
      Serial.read();                  //прочитать (чтобы не висел в буфере)
      break;                          //выйти из цикла
    }
  }
  delay(1000);
}


void loop() {
  // выводим начальные значения
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  Serial.print(ax); Serial.print(" ");
  Serial.print(ay); Serial.print(" ");
  Serial.print(az); Serial.print(" ");
  Serial.print(gx); Serial.print(" ");
  Serial.print(gy); Serial.print(" ");
  Serial.println(gz);

  calibration();

  // выводим значения после калибровки
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  Serial.print(ax); Serial.print(" ");
  Serial.print(ay); Serial.print(" ");
  Serial.print(az); Serial.print(" ");
  Serial.print(gx); Serial.print(" ");
  Serial.print(gy); Serial.print(" ");
  Serial.println(gz);
  delay(20);

  while (1);
}

// ======= ФУНКЦИЯ КАЛИБРОВКИ ======= 
void calibration() {
  long offsets[6];
  long offsetsOld[6];
  int16_t mpuGet[6];

  // используем стандартную точность
  mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
  mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);

  // обнуляем оффсеты
  mpu.setXAccelOffset(0);
  mpu.setYAccelOffset(0);
  mpu.setZAccelOffset(0);
  mpu.setXGyroOffset(0);
  mpu.setYGyroOffset(0);
  mpu.setZGyroOffset(0);
  delay(10);
  Serial.println("Calibration start. It will take about 5 seconds");

  for (byte n = 0; n < 10; n  ) {     // 10 итераций калибровки
    for (byte j = 0; j < 6; j  ) {    // обнуляем калибровочный массив
      offsets[j] = 0;
    }
    for (byte i = 0; i < 100   BUFFER_SIZE; i  ) { // делаем BUFFER_SIZE измерений для усреднения mpu.getMotion6(&mpuGet[0], &mpuGet[1], &mpuGet[2], &mpuGet[3], &mpuGet[4], &mpuGet[5]); if (i >= 99)                         // пропускаем первые 99 измерений
        for (byte j = 0; j < 6; j  ) {
          offsets[j]  = (long)mpuGet[j];   // записываем в калибровочный массив
        }
    }
    for (byte i = 0; i < 6; i  ) {      
      offsets[i] = offsetsOld[i] - ((long)offsets[i] / BUFFER_SIZE); // учитываем предыдущую калибровку
      if (i == 2) offsets[i]  = 16384;                               // если ось Z, калибруем в 16384
      offsetsOld[i] = offsets[i];
    }
    // ставим новые оффсеты
    mpu.setXAccelOffset(offsets[0] / 8);
    mpu.setYAccelOffset(offsets[1] / 8);
    mpu.setZAccelOffset(offsets[2] / 8);
    mpu.setXGyroOffset(offsets[3] / 4);
    mpu.setYGyroOffset(offsets[4] / 4);
    mpu.setZGyroOffset(offsets[5] / 4);
    delay(2);
  }
  /*
  // выводим в порт
  Serial.println("Calibration end. Your offsets:");
  Serial.println("accX accY accZ gyrX gyrY gyrZ");
  Serial.print(mpu.getXAccelOffset()); Serial.print(", ");
  Serial.print(mpu.getYAccelOffset()); Serial.print(", ");
  Serial.print(mpu.getZAccelOffset()); Serial.print(", ");
  Serial.print(mpu.getXGyroOffset()); Serial.print(", ");
  Serial.print(mpu.getYGyroOffset()); Serial.print(", ");
  Serial.print(mpu.getZGyroOffset()); Serial.println(" ");
  Serial.println(" ");
  */
}
// калибровка и запись в EEPROM
// при запуске настраиваем оффсеты

// послать символ в сериал - начать повторную калибровку

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include "EEPROMex.h"
MPU6050 mpu;

#define BUFFER_SIZE 100
#define START_BYTE 1010

int16_t ax, ay, az;
int16_t gx, gy, gz;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  mpu.initialize();

  //----------------- ВСПОМИНАЕМ ОФФСЕТЫ ------------------------
  int offsets[6];
  for (byte i = 0; i < 6; i  ) { // обнуляем калибровочный массив // по умолч оффсеты хранятся в ячейках 1010, 1012, 1014, 1016, 1018, 1020 offsets[i] = EEPROM.readInt(START_BYTE   i * 2); } // ставим оффсеты из памяти mpu.setXAccelOffset(offsets[0]); mpu.setYAccelOffset(offsets[1]); mpu.setZAccelOffset(offsets[2]); mpu.setXGyroOffset(offsets[3]); mpu.setYGyroOffset(offsets[4]); mpu.setZGyroOffset(offsets[5]); //----------------- ВСПОМИНАЕМ ОФФСЕТЫ ------------------------ Serial.println(F("Send any character to start sketch")); delay(100); while (1) { //входим в бесконечный цикл if (Serial.available() > 0) {     //если нажата любая кнопка
      Serial.read();                  //прочитать (чтобы не висел в буфере)
      break;                          //выйти из цикла
    }
  }
  delay(1000);
}

void loop() {
  calibration();

  Serial.println("Current offsets:");
  Serial.println("accX accY accZ gyrX gyrY gyrZ");
  Serial.print(mpu.getXAccelOffset()); Serial.print(", ");
  Serial.print(mpu.getYAccelOffset()); Serial.print(", ");
  Serial.print(mpu.getZAccelOffset()); Serial.print(", ");
  Serial.print(mpu.getXGyroOffset()); Serial.print(", ");
  Serial.print(mpu.getYGyroOffset()); Serial.print(", ");
  Serial.print(mpu.getZGyroOffset()); Serial.println(" ");
  Serial.println(" ");  

  // выводим значения после калибровки
  Serial.println("Readings:");
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  Serial.print(ax); Serial.print(" ");
  Serial.print(ay); Serial.print(" ");
  Serial.print(az); Serial.print(" ");
  Serial.print(gx); Serial.print(" ");
  Serial.print(gy); Serial.print(" ");
  Serial.println(gz);
  delay(20);

  while (1);
}

// =======  ФУНКЦИЯ КАЛИБРОВКИ И ЗАПИСИ В ЕЕПРОМ ======= 
void calibration() {
  long offsets[6];
  long offsetsOld[6];
  int16_t mpuGet[6];

  // используем стандартную точность
  mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
  mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);

  // обнуляем оффсеты
  mpu.setXAccelOffset(0);
  mpu.setYAccelOffset(0);
  mpu.setZAccelOffset(0);
  mpu.setXGyroOffset(0);
  mpu.setYGyroOffset(0);
  mpu.setZGyroOffset(0);
  delay(5);

  for (byte n = 0; n < 10; n  ) {     // 10 итераций калибровки
    for (byte j = 0; j < 6; j  ) {    // обнуляем калибровочный массив
      offsets[j] = 0;
    }
    for (byte i = 0; i < 100   BUFFER_SIZE; i  ) { // делаем BUFFER_SIZE измерений для усреднения mpu.getMotion6(&mpuGet[0], &mpuGet[1], &mpuGet[2], &mpuGet[3], &mpuGet[4], &mpuGet[5]); if (i >= 99)                         // пропускаем первые 99 измерений
        for (byte j = 0; j < 6; j  ) {
          offsets[j]  = (long)mpuGet[j];   // записываем в калибровочный массив
        }
    }
    for (byte i = 0; i < 6; i  ) {
      offsets[i] = offsetsOld[i] - ((long)offsets[i] / BUFFER_SIZE); // учитываем предыдущую калибровку
      if (i == 2) offsets[i]  = 16384;                               // если ось Z, калибруем в 16384
      offsetsOld[i] = offsets[i];
    }
    // ставим новые оффсеты
    mpu.setXAccelOffset(offsets[0] / 8);
    mpu.setYAccelOffset(offsets[1] / 8);
    mpu.setZAccelOffset(offsets[2] / 8);
    mpu.setXGyroOffset(offsets[3] / 4);
    mpu.setYGyroOffset(offsets[4] / 4);
    mpu.setZGyroOffset(offsets[5] / 4);
    delay(2);
  }

  // запись в память
  for (byte i = 0; i < 6; i  ) {    // обнуляем калибровочный массив
    // оффсеты хранятся в ячейках 1010, 1012, 1014, 1016, 1018, 1020
    if (i < 3)
      EEPROM.updateInt(START_BYTE   i * 2, offsets[i] / 8);
    else
      EEPROM.updateInt(START_BYTE   i * 2, offsets[i] / 4);
  }
}

Также в библиотеке есть готовые функции для калибровки акселя и гиро, они принимают количество итераций калибровки (до 15):

mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);

Функции блокирующие, выполняются и автоматически выставляют оффсеты, т.е. датчик сразу калибруется. Для чтения оффсетов (например для записи в EEPROM) можно воспользоваться тем же способом, что и раньше:

mpu.getXAccelOffset();
mpu.getYAccelOffset();
mpu.getZAccelOffset();
mpu.getXGyroOffset();
mpu.getYGyroOffset();
mpu.getZGyroOffset();

Размеры платы полетного контроллера

Монтажная схема полетного контроллера — это расстояние между отверстиями для крепления ПК к раме дрона. В этом вопросе есть стандарт, который состоит из 3 схем:

  • 30,5 × 30,5 мм,
  • 20 × 20 мм,
  • 16 × 16 мм.

Размер платы соответствует размеру дрона, который вы будете собирать, например, 30,5 х 30,5 мм устанавливаются в рамы размером от 200 мм и больше, а на меньшие рамы устанавливаются последующие размеры полетных контроллеров.

Регулятор напряжения (bec)

На современных (да и не только) ПК есть отдельные контакты для подключения источника потребления на 5V и на 12V, иногда встречаются даже на 9. Хоть сейчас почти все FPV-компоненты рассчитаны на ток в широком диапазоне и их можно подключать даже к аккумулятору, мы все же рекомендуем подключать их к отдельному входу на полетном контроллере, где ток подается стабильным, тогда как в аккумуляторе он будет постоянно «скакать» от нагрузки.

Регуляторы оборотов (esc)

Наверняка вы уже слышали или видели регуляторы оборотов 4 в 1, такая квадратная плата вместо 4 плат. Инженеры решили интегрировать регуляторы сразу в полетный контроллер и теперь, если вы купите такой ПК, вам можно будет припаять двигатели напрямую к ПК. О целесообразности такого выбора решать только вам.

Сколько бывает портов uart на полетном контроллере?

UART портов много не бывает — чем больше, тем более гибко можно будет настраивать ваш квадрокоптер, а также они будут дублировать друг друг в случае поломки.

Но само количество портов зависит от размеров платы полетного контроллера и от того, как расположены на ней компоненты, а также от типа процессора, который использует ПК. 3-е и 4-е поколение полетных контроллеров (F3-F4) имеют от 3 до 5 UART, а 7-е поколение — 7 и более. Оно и понятно, слабый процессор не сможет физически обрабатывать столько периферии.

F1 F3 F4 F7
2 UART 3-5 UART 3-6 UART 7 UART

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

Термометр тестировать проще всего: залил скетч

, открыл монитор порта, выставил скорость на 9600, —

Вследствие нагревания феном для волос, значение

Tmp =

взлетело до 80. Далее покрутили в пространстве платкой — другие показания тоже изменяются, но это не наглядно.

Данные, выводимые вторым скетчем

InvenSense MPU-6050

June 2023

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, -2023, -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,

Более приятный глазу пример описан

Тестовая установка

, о котором

, был пересмотрен, урезан и сокращён (кстати, на этом фото заметно отличие в качестве металлизации отверстий обозреваемой платы и дешевой платы Ардуино):

если отсоединить

тентакли

шлейф от креплений, то откроются два ряда контактов, у которых нужно «поотламывать половинки», — в результате получится разъем, удобно вставляющийся в отверстия макетной платы. Для пущей надёжности, нужно проклеить корпус, т.к. держаться на одних контактах конструкция не будет.

всё ещё может напугать, но на самом деле бояться нечего:

спаял с обратной стороны контакты, прозвонил их тестером — и можно подключать. Лично моя практика показывает, что лучше потратить пару секунд на предварительную проверку, чем ткнуть «не туда» и спалить девайс… Я так спалил Orange Pi PC =)

Товар предоставлен для написания обзора магазином. Обзор опубликован в соответствии с п.18 Правил сайта.

Типы коннекторов

Это, конечно, не функция, но не рассказать об этом нельзя. На полетном контроллере есть 3 типа соединений между периферией:

  • Пластиковые коннекторы
  • Контактные площадки для припаивания
  • Отверстия для припаивания

Пластиковые коннекторы в основном используются для подключения периферии, которую иногда нужно отключать и снимать, в этом их плюс — быстро снять/подключить. Они не очень прочные, но удобные.

Контактные площадки для припаивания удобны в использовании, но если контакт сильно нагреется во время использования, то есть вероятность, что он оторвется. То же самое и в вопросе о разрыве при сильном натяжении.

Отверстия для припаивания удобны тем, что провод гораздо прочнее будет «сидеть» в пазу. Также можно использовать угловые штифты для более удобного подключения периферии.

Характеристики:

— 16-битный АЦП,

— напряжение питания 3-5В,

— поддержка протокола «IIC» (может, I2C ?),

— диапазон ускорений: ± 2 ± 4 ± 8 ± 16g,

— диапазон «гиро»: ± 250 500 1000 2000 ° / s,

— покрытие иммерсионным золотом вместо лужения,

— ток при работе последнего примера составил 5.3 мА и 1.2 мА когда устройство не успело стартовать (питание на модуль было подано после выполнения setup() контроллером)

Черный ящик (blackbox)

Черный ящик нужен для записи логов работы квадрокоптера, туда записываются всевозможные данные, которые обрабатывает полетный контроллер. Есть два места, куда можно вести запись логов, это флеш-память полетного контроллера и SD-карта (флешка).

Плюсывстроенной флеш-памяти:

  • Экономия места,
  • Не нужен отдельный разъем.

Минусы встроенной флеш-памяти:

  • Маленький размер хранилища,
  • Маленькая скорость обмена данными (скачивание логов).

Заключение

Как вы заметили, полетный контроллер — это очень важный узел в квадрокоптере и занимает очень много места в теории. И на вопрос, как правильно выбрать полетный контроллер, у вас не должно оставаться этих самых вопросов, а если остались, вы должны понять, для чего вам нужен квадрокоптер, для каких нужд.

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

Также стоит учитывать бюджет, который вы можете потратить, так как цены очень сильно разнятся. Например, SP Racing F7 с OSD для гоночных дронов стоит от 1600 до 2500 рублей, а вот DJI A3 для профессиональной фото- и видеосъемки стоит 50 000 – 60 000 тысяч рублей.

Подведем итоги:

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

Оцените статью
Радиокоптер.ру
Добавить комментарий