Самолет, радиоуправление на nrf24l01 + arduino nano
На основе проекта nRF24L01/Projects at master · AlexGyver/nRF24L01 · GitHub
всё хорошо работало, но захотелось лучшего. Подсоединил модуль GPS neo-6m, чтобы получать в пульт управления данные телеметрии полёта - скорость, высоту…, а в перспективе и автопиот, потому, что без автопилота плохо, самолёт далеко не летит и сталкивается с землёй, нужна будет стабилизация полёта.
Но сейчас проблема такая. На сигналы управления накладывается сильное дёрганье рулевых поверхностей и колебания оборотов двигателя. И это от GPS модуля. При выключеном передатчике тоже самое. Даже если тупо забить в приемник вместо полученных с пульта сигналов управления константы все сервы продолжают дёргаться.
Видео
Если вырубить GPS закоментировав строку (она у меня 58-я)
ss.begin(GPSBaud);
то всё приходит в норму, управление работает хорошо, но уже, естественно, без телеметрии.
Прошу помощи, как поправить скетч чтобы управление работало совместно с телеметрией?
Скетч приёмника:
//--------------------- НАСТРОЙКИ ----------------------
#define CH_NUM 0x60 // номер канала (должен совпадать с передатчиком)
//--------------------- НАСТРОЙКИ ----------------------
//--------------------- ДЛЯ РАЗРАБОТЧИКОВ -----------------------
// УРОВЕНЬ МОЩНОСТИ ПЕРЕДАТЧИКА
// На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
#define SIG_POWER RF24_PA_MIN
// СКОРОСТЬ ОБМЕНА
// На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
// должна быть одинакова на приёмнике и передатчике!
// при самой низкой скорости имеем самую высокую чувствительность и дальность!!
// ВНИМАНИЕ!!! enableAckPayload НЕ РАБОТАЕТ НА СКОРОСТИ 250 kbps!
#define SIG_SPEED RF24_1MBPS
//--------------------- ДЛЯ РАЗРАБОТЧИКОВ -----------------------
//--------------------- БИБЛИОТЕКИ ----------------------
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <Servo.h>
#include "TinyGPS++.h"
#include "SoftwareSerial.h"
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 для НАНО/УНО
//RF24 radio(9, 53); // для МЕГИ
static const int RXPin = 2, TXPin = 4;
static const uint32_t GPSBaud = 9600;
SoftwareSerial ss(RXPin, TXPin);
TinyGPSPlus gps;
//--------------------- БИБЛИОТЕКИ ----------------------
//--------------------- ПЕРЕМЕННЫЕ ----------------------
byte pipeNo;
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; // возможные номера труб
byte recieved_data[5]; // массив принятых данных
byte gaz = 3; // GAZ на 3 цифровом
byte roll = 5; // ROLL на 5 цифровом
byte pitch = 6; // PITCH на 6 цифровом (ТУТ ЕСТЬ ШИМ!!!)
byte LED = 7;
Servo servogaz;
Servo servoroll;
Servo servopitch;
byte telemetry[4]; // массив данных телеметрии (то что шлём на передатчик)
//--------------------- ПЕРЕМЕННЫЕ ----------------------
void setup() {
ss.begin(GPSBaud);
servogaz.attach(3);
servoroll.attach(5);
servopitch.attach(6);
//-------------Калибовка регулятора-----------
servogaz.writeMicroseconds(2300);
delay(2000);
servogaz.writeMicroseconds(800);
delay(6000);
//----------------------------------
Serial.begin(115200);
radioSetup();
}
void loop() {
while (radio.available(&pipeNo)) { // слушаем эфир
radio.read(&recieved_data, sizeof(recieved_data)); // чиатем входящий сигнал
digitalWrite(LED, recieved_data[0]); // подать на LED сигнал с 0 места массива
servogaz.write((recieved_data[1] | recieved_data[2] << 8));//два байта обороты двигателя
servopitch.write(recieved_data[3]); // руль высоты
servoroll.write(recieved_data[4]); // элероны
Serial.println (" ///+++///*****");
Serial.println((recieved_data[1] | recieved_data[2] << 8));
Serial.println((recieved_data[3]));
Serial.println((recieved_data[4]));
Serial.println(" ---+++---");
// формируем пакет данных телеметрии (скорость, высота...)
while (ss.available() > 0)
gps.encode(ss.read());
telemetry[0] = gps.time.hour() + 3;// время
telemetry[1] = gps.time.minute();
telemetry[2] = gps.altitude.meters() / 10; // высота / на 10
telemetry[3] = gps.speed.mps();// скорость м/с
telemetry[4] = gps.satellites.value();// спутники
Serial.println(telemetry[0]);
Serial.println(telemetry[1]);
Serial.println(telemetry[2]);
Serial.println(telemetry[3]);
Serial.println(telemetry[4]);
Serial.println(" --/////////--");
// отправляем пакет телеметрии
radio.writeAckPayload(pipeNo, &telemetry, sizeof(telemetry));
}
}
void radioSetup() { // настройка радио
radio.begin(); // активировать модуль
radio.setAutoAck(1); // режим подтверждения приёма, 1 вкл 0 выкл
radio.setRetries(0, 15); // (время между попыткой достучаться, число попыток)
radio.enableAckPayload(); // разрешить отсылку данных в ответ на входящий сигнал
radio.setPayloadSize(5); // размер пакета, байт
radio.openReadingPipe(1, address[0]); // хотим слушать трубу 0
radio.setChannel(CH_NUM); // выбираем канал (в котором нет шумов!)
radio.setPALevel(SIG_POWER); // уровень мощности передатчика
radio.setDataRate(SIG_SPEED); // скорость обмена
// должна быть одинакова на приёмнике и передатчике!
// при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); // начать работу
radio.startListening(); // начинаем слушать эфир, мы приёмный модуль
}