Arduino Nano+2 Сервы+Мотор+NRF_PA_LNA - никак что то...
- Войдите на сайт для отправки комментариев
Сб, 17/09/2022 - 02:35
Всем доброго друзья!
Делаю тут одну штуку...Самолёт в общем из потолочки :-)
И никак не могу побороть эту застарелую беду (насколько я понял, порыскав по сети). А именно:
Мне нужно чтобы работали 2 сервы, двигатель и радиомодуль NRF_PA_LNA. Всё настроил, всё работает (и передатчик тоже). Но! По отдельности :-))
Или сервы - или мотор. Хоть ты тресни. Да, почитал про особенности библиотеки Servo.h. И про таймеры: https://arduino.ru/Tutorial/Arduino_Interrupts_part2
Однако, всё равно не могу пока побороть....Любому совету буду рад. На 11-12 пине у меня висит NRF (т.к. там у нас MOSI-MISO). Остаются для экспериментов остальные пины...
Скетч приёмной части пока такой:
// 4 Channel Receiver // PWM output on pins D2, D3, D4, D5 #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> #define PIN_CE 7 // Номер пина Arduino, к которому подключен вывод CE радиомодуля #define PIN_CSN 8 // Номер пина Arduino, к которому подключен вывод CSN радиомодуля RF24 radio(PIN_CE, PIN_CSN); // Создаём объект radio с указанием выводов CE и CSN //------Настройки двигателя------ int DirPin = 10; int SpeedPin = 3; //------------------------------- int ch_width_1 = 0; int ch_width_2 = 0; int ch_width_3 = 0; int ch_width_4 = 0; //Servo ch1; //Servo ch2; Servo ch3; Servo ch4; struct Signal { byte throttle; byte pitch; byte roll; byte yaw; }; Signal data; const uint64_t pipeIn = 0xE9E8F0F0E1LL; void ResetData() { // Определение начальных значений // Среднее положение потенциометров (254/2=127) data.throttle = 0; // Motor Stop data.pitch = 127; // Center data.roll = 127; // Center data.yaw = 127; // Center } void setup() { // Serial.begin (9600); //-----Настраиваем двигатель----------- pinMode(DirPin, OUTPUT); pinMode(SpeedPin, OUTPUT); digitalWrite(DirPin, LOW); analogWrite(SpeedPin, 0); //------------------------------------- //Set the pins for each PWM signal // ch1.attach(2); // ch2.attach(3); ch3.attach(6); ch4.attach(5); radio.begin(); // Инициализация модуля NRF24L01 radio.setChannel(5); // Обмен данными будет вестись на пятом канале (2,405 ГГц) radio.setDataRate (RF24_1MBPS); // Скорость обмена данными 1 Мбит/сек radio.setPALevel(RF24_PA_HIGH); // Выбираем высокую мощность передатчика (-6dBm) radio.openReadingPipe (1, pipeIn); // Открываем трубу ID передатчика radio.startListening(); // Начинаем прослушивать открываемую трубу } void(* resetFunc) (void) = 0; // объявляем функцию reset unsigned long lastRecvTime = 0; void recvData() { while ( radio.available() ) { radio.read(&data, sizeof(Signal)); lastRecvTime = millis(); // receive the data analogWrite(SpeedPin, data.throttle); } } void loop() { recvData(); unsigned long now = millis(); if ( now - lastRecvTime > 1000 ) { ResetData(); // Сигнал потерян..Сброс данных resetFunc(); //вызываем reset } // ch_width_1 = map(data.throttle, 0, 255, 0, 255); // pin D2 (PWM signal) ch_width_2 = map(data.pitch, 0, 255, 1000, 2000); // pin D3 (PWM signal) ch_width_3 = map(data.roll, 0, 255, 1000, 2000); // pin D4 (PWM signal) ch_width_4 = map(data.yaw, 0, 255, 1000, 2000); // pin D5 (PWM signal) // //// Write the PWM signal //ch1.writeMicroseconds(ch_width_1); // ch2.writeMicroseconds(ch_width_2); ch3.writeMicroseconds(ch_width_3); ch4.writeMicroseconds(ch_width_4); }
Какую застарелую беду? У каждого она своя - у кого нога не ходит, у кого в голове туман.
да ладно, как там в песенке...если в голове опилки не беда...да...да...да...
Короче, всё, как всегда:-) Токсичные старики (да я и сам не молод). Про это даже мем есть: " спросишь на зарубежном форуме - получишь ответ. Спросишь на нашем - тебе объяснят, что ты мудак" :-)))
P.S. прежде чем спрашивать - я вычитал теорию, и перепробовал массу вариантов. В том числе разделять: вешать даижок на один таймер, сервы- на другой. Ни хрена не работат..
Короче все как всегда - телепаты требуются. В отпуске они все, приходите через полгода.
у тебя там всё неправильно, как это можно комментировать, данные зачем нулишь?
вот так всегда, задаст вопрос и исчезнет...
Если ты о ResetData() - то это насколько я понимаю, при потере связи - для отключения двигателя и переключения руля и эакрылков - в среднее положение.
Буду рад, если скажешь что неправильно.
P.S. Самолёт управляется пультом - на котором 2 аналоговых джойстика. По отдельности (или сервы или движок - всё работает. Вместе - уже нет. уже чего только не пробовал...).
Система соединений примерно такая, как на картинке (только у меня проще -я взял эту за основу, но у меня только 2 сервы- для простоты управления. Плюс - у меня перед двигателем стоит драйвер L9110, а не как тут.
В коде выше 3 серва не везде вырублена -но это не суть. И отключаешь её и не отключаешь - сути не меняет. Пробовал...
попробуй убрать разрешение мотора с 10 пина на любой другой (кроме 9), может там косяк, так как он к первому таймеру (это servo.h) привязан
Хорошо, попробую завтра и отпишусь. Спасибо!
В общем, пока бесполезно...
Попробовал такое:
5,3 – двигатель; 9,10 – две сервы
5,6-двигатель; 3-одна серва
9,10 – две сервы; 5,6-двигатель
Сервы дергаются вместе с двигателем...Или какой то косяк в коде, - хотя пока что в упор не вижу. С питанием системы -всё отлично - 2 элемента 18650 последовательно. Или просто что то другое...Читал в сети, что многие сталкиваются с такой проблемой. И кто то даже рекомендовал искать асинхронную библиотеку для серв - вместо Servo.h.
Пока не знаю, что ещё сказать. Всю голову сломал над этим вопросом...По отдельности (если отключить сервы или движок ) - всё отлично. Вместе - ну никак...
Не надо искать библиотеки. Надо зарядить таймеры 1 и 2 на выдачу необходимых сигналов. Они аппаратно, без участия программы, будут держать сервы в нужных положениях. Первый канал третьего таймера можно пустить на управление мотором. Программе останется только обмен данными и редкая запись в регистры таймеров значений угла серв и скорости мотора. Таймеры зарядить на 20 мс цикл, а в регистры сравнения писать данные. Соответственно будут задействованы ноги D10 D9 - выход первого таймера и D3 - выход второго канала второго таймера. Первый канал второго таймера конфликтует по выходу со SPI, поэтому управление мотором через прерывание первого канала второго таймера можно отправить на любую ногу.
Первый канал третьего таймера можно пустить на управление мотором.
Их всего 3. Имена конечно нулевой, первый и второй, но если считать как звучит - всего три - то так и хочется говорить. Прости такую оплошность. В голове почему-то упорно гуляет первый, второй, третий.
Откуда у наны третий таймер?
В современном варианте (PB) - 4.
Первый канал третьего таймера можно пустить на управление мотором.
это истинно китайская нано, там есть )))
В общем, пока бесполезно...
Попробовал такое:
5,3 – двигатель; 9,10 – две сервы
5,6-двигатель; 3-одна серва
9,10 – две сервы; 5,6-двигатель
Сервы дергаются вместе с двигателем...Или какой то косяк в коде, - хотя пока что в упор не вижу. С питанием системы -всё отлично - 2 элемента 18650 последовательно. Или просто что то другое...Читал в сети, что многие сталкиваются с такой проблемой. И кто то даже рекомендовал искать асинхронную библиотеку для серв - вместо Servo.h.
Пока не знаю, что ещё сказать. Всю голову сломал над этим вопросом...По отдельности (если отключить сервы или движок ) - всё отлично. Вместе - ну никак...
поменяй движок на нормальный с регулем и забудь
У меня есть конечно дурацкий способ (вернее, нормальный) -но используя решение, которое в своё время у меня заработало на ESP32. В своё время я решил такую проблему. Там суть была в том, что вместо библиотеки Servo.h - я пользовал решение, позаимствованное от буржуинов. Сейчас выложу.
Вот это решение у меня заработало на esp. Там было 2 двигателя и серва (машинка детская с клешнёй спереди). И движки с ШИМом так же конфликтовали с сервой. Библиотека была та же (Servo.h) Это - вкратце решение (как запустить серву без библиотеки вообще):
ПЫ-СЫ: Дурацкость решения заключается в том, что я выкидываю на.. нану :-). Ставлю вместо неё esp32. В итоге - все счастливы, танцуют и смеются :-)
Ну это я пока так. На скорую руку. Надо попробовать предложенное выше с таймерами. Если вытяну...
вообще-то NRF24 занимает 5 пинов, 4 из них ты поменять не можешь, это 10,11,12,13 волен только пин CS определять самостоятельно
CS - это какой пин?
обычно используют CE -D9, CSN -D10, MO -D11, MI - D12, SCK-D13 servo.h на первом таймере и конфликтует с SPI так что проблемы неизбежны, а он еще шимит напрямую, можно попробовать на 0 таймер на D5 D6 и, это пожалуй единственный вариант, не?
Так можно CS поменять или нет? В посте два утверждения, противоречащих друг другу.
по идее можно, но для начала по фэншую, как прописаны, а потом уж экспериментировать, не?
Я тут вот с SPI RP2040 экспериментирую, не хочешь подключиться?
Уф, победил полностью. Но не нану :-) Сделал "мозги" на самолёт - на базе esp32. Работает отлично.
Уф, победил полностью. Но не нану :-) Сделал "мозги" на самолёт - на базе esp32. Работает отлично.
чего бы ей на таком монстре не работать, ESP тут явно лишний, я бы взял Rasberry Pi Pico, 175 рублей всех делов
Скидывай скетчи приёмника и передатчика, откомпилирую, посмотрим...пины разведу сам )))
Начало универсального скетча аппаратуры радиоуправления на ESP32 или RP2040 будет выглядеть так:
Ну ок.. Выложу коды ;-)
Вкратце система:
-пульт управления - на Arduino Nano (переставить на esp32 элементарно - просто CE перекинуть на 4 пин, а CSN-на 5-й. В общем, всё как у приёмника);
- мозги самолёта - esp32
Почему такой разнобой: потому что хотел изначально всё собрать на Arduino Nano - но нет времени с ней возиться. Поэтому: пульт заработал - ну и нормально. Самолёт заработал? Да и хрен бы с ним...:-)
В коде много мусора из закомментированных участков. Но некоторые нужны - ибо пояснения. Код протестирован и отлично работает.
Выявилась проблема только в том (но это уже не с кодом), что двигатель потребляет дюже много ампер (гораздо больше того, что может дать драйвер). В пике, пишут что аж до 20А и более может быть. Так как питаю от парочки 18650 высокотоковых (на 35А макс) - без разницы. Но - когда в первый раз запустил и "выжал газ" - натурально пошёл дым и выгорел драйвер двигателя. Сейчас буду ставить мосфет с логическим уровнем (чтобы мог открыться полностью от вольтажа пинов esp32). Так как это винт самолёта - реверс вращения мне не нужен, достаточно только вращения в одну сторону.
P.S. в настройках ШИМа забыл обновить комменты- ну да неважно. Кому надо - разберётесь;-)
В мозгах самолёта - какие либо библиотеки для управления сервами - не используются. Применяется решение, которое я выложил выше.
Пульт (Arduino Nano):
Мозги самолёта(esp32):