Самолет, радиоуправление на nrf24l01

Самолет, радиоуправление на 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();  // начинаем слушать эфир, мы приёмный модуль
}

Схемотехнику приведи в порядок.

сделать на этой пионерии что либо прилично летающее невозможно, закажи контроллер APM2.6 или 2.8, зальёшь туда Мишинплэнер для самолёта и, наслаждайся полётами

ФСБ уже едет за вами …
Пока soft serial принимает пакет - всё остальное на паузе ?

а может в его регионе нет запрета на летающие модельки…другим остаётся запускать кораблики или автомобильчики )))

В этом Ваша главная ошибка!

Лучшего, чем у AlexGyver не бывает и быть не может. Если бы было возможно сделать лучше, он бы сделал!

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

1 лайк

„Оптимисты считают, что мы живём в лучшем из возможных миров; пессимисты боятся, что это правда.“ — Джеймс Кейбелл

Источник: Джеймс Кейбелл цитата: Оптимисты считают, что мы живём в лучшем из возможных миров; … | Цитаты известных личностей

„Свой вклад в общество делают как оптимисты, так и пессимисты. Оптимист придумал самолёт, пессимист — парашют.“ — Джордж Бернард Шоу

Источник: Джеймс Кейбелл цитата: Оптимисты считают, что мы живём в лучшем из возможных миров; … | Цитаты известных личностей

2 лайка

Это прерывание? А подробнее можно?

если проблема в soft serial
Развел порты как в стандартном примере TwoPortReceive
Добавил порт, обозвал его RF
SoftwareSerial RF(9, 10); куда продключена nrf24l01 на 9 и 10 пины.
Теперь так

static const int RXPin = 2, TXPin = 4;
SoftwareSerial ss(RXPin, TXPin);
SoftwareSerial RF(9, 10);
void setup() {
  ss.begin(GPSBaud);
 RF.begin(9600);

Остальное оставил как есть. Теперь , дерганья прекратились, управление работает, но в телеметрии нет данных GPS.

два софтовых сериала точно работать не будут

Почему? listen использовать и всё будет.

потому, что
RE На основе проекта nRF24L01/Projects at master · AlexGyver/nRF24L01 · GitHub

Конечно, только решаете Вы её не с того конца.

Выбросьте всё (совсем ВСЁ, оставьте только сериалы) и убедитесь, что сериалы (софтовый и хардовый) нормально работают вместе. Только потом возвращайте функционал обратно.

Например, в стартовом коде у Вас у софтового сериала скорость 9600, а у хардового - 115200. И Вы и впрямь ожидаете, что они будут вместе работать? Сделайте хотя бы скорость одинаковыми.

а что не так, у хардового буфер в 1 байт, с ним разбираемся быстрее оставляя машинное время для софтового ?
PS чуток подумал…мне понятен ход ваших мыслей, логично )))

Какой пакет GPS вы пытаетесь принимать ??? Сколько байт пытаетесь принять и сколько этот процесс длится по времени ?
В SoftwareSerial прием\передача одного байта, это БЛОКИРУЮЩИЙ код !!!

Всё выбросил, скорости сравнял на 9600, забил номера своих пинов в пример TwoPortReceive из библиотеки SoftwareSerial и получил:
Снимок экрана от 2023-04-17 12-55-48
GPS на втором порту живой, что-то там успевает проскакивать, а первый порт не отзывается…

Мне пока хотя бы время со спутников получить, чтобы увидеть что оно работает. А потом уже скорость и удаление вычислить. Самолёт без скорости не бывает. В приведенном выше скетче GPS телеметрия приходит, но органы управления дёргаются как бешеные.
Как победить БЛОКИРУЮЩИЙ код?

Использовать МК с соответствующим задаче числом аппаратных UART !
Как вариант - переключить GPS модуль на протокол UBX и получать данные по нему. Там есть пакет Ubx-Nav-Pvt, где в ~100 байтах есть вся нужная вам информация !
Тот протокол, что вы сейчас принимаете - это многие сотни байт текстовой информации. Не мудрено что на обработку остального просто не хватает ресурсов МК !

1 лайк