nrf24l01 прием и передача
- Войдите на сайт для отправки комментариев
Сб, 24/04/2021 - 17:37
Делаю катер. С пульта отправляю данные на катер, но с катера на пульт с перебоями это на скорости RF24_1MBPS, а на скорости RF24_250KBPS вовсе данные не отправляются. Подскажите лучше из катера отправлять другой ардуинкой или можно оптимизировать код ?
Код пульта
#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include "nRF24L01.h" // Подключаем файл конфигурации из библиотеки RF24 #include "RF24.h" // Подключаем библиотеку для работа для работы с модулем NRF24L01 #include "printf.h" // Инфо NRF24L01 #include <Servo.h> RF24 radio(9, 10); // CE, CSN модуль nrf24l01 + pa + lna на пинах RF24 radio(9,10); Для Уно/нано. RF24 radio(9,53); для Меги. byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб byte transmit_data[4]; byte recieved_data[4]; float vin = 0.0; int valMotor; int valServo1; int valServo2; int valServo3; const int potPinMotor = 0; const int potPinRole = 1; const int potContainerServo1 = 3; const int potContainerServo2 = 4; int timeout = 500; // переменные для разрыва связи int lastTime = 0; void setup() { Serial.begin(115200); pinMode(potPinMotor, INPUT); pinMode(potPinRole, INPUT); pinMode(potContainerServo1, INPUT); pinMode(potContainerServo2, INPUT); radio.begin(); radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[0]); //мы - труба 0, открываем канал для передачи данных radio.openReadingPipe(0, address[1]); //хотим слушать трубу 0 radio.setChannel(0x71); //( Автовыбор канала в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS);//скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! radio.powerUp(); radio.stopListening(); //перестайом слушать эфир, мы передаваемый модуль printf_begin(); radio.printDetails(); } void loop() { valMotor = analogRead(potPinMotor); valMotor = map(valMotor, 0, 1023, 25, 255); transmit_data[0] = valMotor; valServo1 = analogRead(potPinRole); valServo1 = map(valServo1, 0, 1023, 80, 103); transmit_data[1] = valServo1; valServo2 = analogRead(potContainerServo1); valServo2 = map(valServo2, 0, 1023, 0, 179); transmit_data[2] = valServo2; valServo3 = analogRead(potContainerServo2); valServo3 = map(valServo3, 0, 1023, 0, 179); transmit_data[3] = valServo3; // Serial.print("valMotor: "); //Serial.println(transmit_data[0]); radio.write(&transmit_data, sizeof(transmit_data)); radio.startListening(); //начинаем слушать эфир, мы приёмный модуль byte pipeNo; while (radio.available(&pipeNo)) { // слушаем эфир со всех труб lastTime = millis(); radio.read( &recieved_data, sizeof(recieved_data) ); // чиатем входящий сигнал Serial.println(recieved_data[0]); } int dt = millis() - lastTime; if (dt >= timeout) { Serial.println(dt); } radio.stopListening(); //перестайом слушать эфир, мы передаваемый модуль }
Код катера
#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include "nRF24L01.h" // Подключаем файл конфигурации из библиотеки RF24 #include "RF24.h" // Подключаем библиотеку для работа для работы с модулем NRF24L01 #include "printf.h" // Инфо NRF24L01 #include <Servo.h> Servo motor; Servo servo1; Servo servo2; Servo servo3; RF24 radio(9, 10); // CE, CSN модуль nrf24l01 + pa + lna на пинах RF24 radio(9,10); Для Уно/нано. RF24 radio(9,53); для Меги. byte address[][6] = {"1Node","2Node","3Node","4Node","5Node","6Node"}; //возможные номера труб int timeout = 500; // переменные для разрыва связи int lastTime = 0; float vout = 0.0; // переменные для вольтметра float vin = 0.0; float R1 = 61000.0; // резистор в R1 (60K) float R2 = 10000.0; // резистор в R2 (10K) int value = 0; byte recieved_data[4]; byte transmit_data[4]; void setup(){ motor.attach(2); servo1.attach(3); servo2.attach(4); servo3.attach(5); Serial.begin(115200); //открываем порт для связи с ПК radio.begin(); //активировать модуль printf_begin(); // radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[1]); //мы - труба 0, открываем канал для передачи данных radio.openReadingPipe(1, address[0]); //хотим слушать трубу 0 radio.setChannel(0x71); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS при самой низкой скорости имеем самую высокую чувствительность и дальность!! //должна быть одинакова на приёмнике и передатчике! radio.printDetails(); radio.powerUp(); //начать работу radio.startListening(); //начинаем слушать эфир, мы приёмный модуль for (int i=0; i <= 255; i++){ motor.write(i); delay(10); Serial.print(i); } delay(2000); for (int i=255; i >= 30; i--){ motor.write(i); delay(10); Serial.print(i); } delay(2000); } void loop() { byte pipeNo; while (radio.available(&pipeNo)) { // слушаем эфир со всех труб lastTime = millis(); radio.read( &recieved_data, sizeof(recieved_data) ); // чиатем входящий сигнал motor.write(recieved_data[0]); servo1.write(recieved_data[1]); servo2.write(recieved_data[2]); servo3.write(recieved_data[3]); Serial.print("valMotor: "); Serial.println(recieved_data[0]); } int dt = millis() - lastTime; if (dt >= timeout) { Serial.println(dt); motor.write(29); servo1.write(92); } radio.stopListening(); //перестайом слушать эфир, мы передаваемый модуль value = analogRead(A0); vout = (value * 5.0) / 1024.0; vin = vout / (R2/(R1+R2)); transmit_data[0] = vin; //Отправляем данные АКБ Serial.println(transmit_data[0]); radio.write(&transmit_data, sizeof(transmit_data)); radio.startListening(); //начинаем слушать эфир, мы приёмный модуль }
Сам с таким боролся - надеюсь поможет - короче - если nrf без антенн - накрути на нее тонкую проволоку колец 20 и сделай усы. Так - сигнал точно будет хорошо доходить. Скидываю фото - как на нем. (надеюсь будет видно). Если не помогло - отпишись, может глубже в код залезу - помогу
Также ,на сколько я понял ты взял пример AG. Попробуй просканить территорию, возможно тот канал, который ты используешь - захламлен
P.s если поступаете как здоровый человек (переводите датчики из прослушивание в отправителя и обратно) - зачем тогда использовать
radio.enableAckPayload();
//разрешить отсылку данных в ответ на входящий сигнал
Пример моего кода для настройки
Вы с благородным доном rumata поговорите. У него железные нервы и он с этой хернёй работал. У меня не получилось - нервный я, похоже...
Вы с благородным доном rumata поговорите. У него железные нервы и он с этой хернёй работал. У меня не получилось - нервный я, похоже...
Зачастую из-за китайских ручек сигнал просто-напросто не пробивает. Думаю человек решит вопрос как только намотает 20 виточков медного провода вокруг nrf
Вы с благородным доном rumata поговорите. У него железные нервы и он с этой хернёй работал. У меня не получилось - нервный я, похоже...
А я ведь предупреждал))
Вы с благородным доном rumata поговорите. У него железные нервы и он с этой хернёй работал. У меня не получилось - нервный я, похоже...
А я ведь предупреждал))
В итоге купил ESP32. Дон Румата - Вы были на 100% правы. херня.
Конденсаторы стоят, эфир чист, питание от специального стабилизатора для NRF24L01. Но когда модули используют 1 роль: 1-й модуль передатчик, 2-й приемник тогда работает без нареканий плавал в 740 метров от передатчика. У меня модуль nrf24l01 + pa + lna
radio.enableAckPayload();
//разрешить отсылку данных в ответ на входящий сигнал он еще означает что в пакете подтверждения приёма есть блок с пользовательскими данными.
Так вот экспериментировал.. так как в ответе приёмника могут присутствовать и те данные которые мы хотим отправить передатчику.
radio.writeAckPayload (1, &ackData, sizeof(ackData) );
// Помещаем данные всего массива ackData в буфер FIFO. Как только будут получены любые данные от передатчика на 1 трубе, то данные из буфера FIFO будут отправлены этому передатчику вместе с пакетом подтверждения приёма его данных.
Но при этих условия модули используют только 1 роль приемник и передатчик. но что-то у меня не работает.(пока что)
zDimaBY, спацифика проблем NRF24 как раз связана с отработкой ack на разных версиях модуля. Проблема на системном уровне не решаемая в принципе, поскольку относится к степени кривизны конкретного клона модуля. В идеале (не для идеальной работы, а для снятия части проблем), автоответ желательно отключать. Роли - это вообще немного о другом. Я бы прислушался к совету ЕвгенияП по поводу ЛорЫ. Катер целее будет, да и ебли с кодом в разы меньше
zDimaBY, спацифика проблем NRF24 как раз связана с отработкой ack на разных версиях модуля.
не нравится Аск - можно ведь работать и без него. Просто передали что надо, выключили передатчик, включили приемник, слушаем эфир...
не знаю, не испытывал проблем заставить НРФ-ки работать с переключением между приемом и передачей.
zDimaBY, спацифика проблем NRF24 как раз связана с отработкой ack на разных версиях модуля.
не нравится Аск - можно ведь работать и без него. Просто передали что надо, выключили передатчик, включили приемник, слушаем эфир...
не знаю, не испытывал проблем заставить НРФ-ки работать с переключением между приемом и передачей.
Да, все так, это базовая практика. АвтоАск первым отключается при поиске проблем. Но только проблемы на этом не заканчиваются))
На мой взгляд, проблема именно с китайскими модулями. Но от этого не легче. Из за этого, подбирая рабочий вариант, приходится действовать методом тыка. Потому как, бывало, у себя на тестовых образцах работает, а у заказчика ни в какую.(
Передатчик
Приемник
Хмм.. Сделал, но radio.writeAckPayload (1, &ackData, sizeof(ackData) ); почему-то не работает с radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) на передатчике как будто не принимает пакеты закомментировал radio.setRetries работает. А radio.setRetries(0, 15); как-бы нужная опция ? Еще заметил перебой когда подключен сервопривод и на джойстике с опцией radio.setRetries(0, 15); не было перебоев.. перебои делаются из-за питания когда серво двигается наверно.
zDimaBY
а почему у вас интервал в setretries 0? Косяк
Самая стабильная работа на RF24_1MBPS
Нужно иметь ввиду, что на многих клонах инвертирован NoAck. Определяется методом научного тыка и использованием эталонного модуля.
Если вам так сильно не хватает секаса в организме, либо другие типы радиомодулей не можете использовать по религиозным соображениям, я бы настоятельно рекомендовал прочитать тему ИгоряК на форуме Амперки. Там проведена огромная научно-изыскательская работа по понуждению этих модулей к вступлению в связь. У нас, кмк, не так много энтузиастов этого дела.
Аа.. setretries 0 15 потому-что предположим 15 это и есть интервал (время чтобы это сделать), а setretries 1 15 делать это через 1мс. или не так я понимаю ?
Таа.. это не се*с это как-бы хоби в свободное время кто-то телевизор смотрит кто-то ютуб, а я делаю такое.. Я бы и использовал другие модули (как посоветовали лору) но есть только эти.. На RF24_250KBPS тоже работает стабильно но без серво (очень восприимчив в питании) хотя с конденсаторами. Пойже попробую разделить цепь питания.. Я то на Ардуино форумах не сидел.. найду ИгоряКа почитаю.
Есть такая аппаратура, она работает и с передатчиком на NRF24L01, прошивка OpenTX
Аа.. setretries 0 15 потому-что предположим 15 это и есть интервал (время чтобы это сделать), а setretries 1 15 делать это через 1мс. или не так я понимаю ?
Обычно интервал (первый параметр) ставят в районе 15-20 миллис, чтобы приемник успевал Аск прислать. По русски setretries(15, 5) - в случае неудачи повторять попытку 5 раз с интервалом 15 мс.
Курите маны библиотеки: https://nrf24.github.io/RF24/classRF24.html
Есть такая аппаратура, она работает и с передатчиком на NRF24L01, прошивка OpenTX
К такой аппаратуре можно и соответствующий приемник сразу взять, благо, по сравнению с пультом он вообще даром получается. Я так понял, задача на творчество, ради развлечения
Есть такая аппаратура, она работает и с передатчиком на NRF24L01, прошивка OpenTX
К такой аппаратуре можно и соответствующий приемник сразу взять, благо, по сравнению с пультом он вообще даром получается. Я так понял, задача на творчество, ради развлечения
я к тому, что в некоторых китайских игрушках используется NRF24L01, сей пульт с ними умеет общаться, и не только с ними )))
(только для информации)
найду ИгоряКа почитаю.
А чего его искать, 80% всех поисковых запросов на тему нрф24 ведут в ту тему
Я бы и использовал другие модули (как посоветовали лору) но есть только эти.
Если сейчас закажете у кЕтайцев нормальную пару дальнобойных радиомодулей, то к моменту, когда вы окончательно натрахаетесь до полного катерсиса с нрф24, глядишь, они уже и приедут. За пару часов спокойно все соберете и в заплыв
я вот не пойму, при весьма скромной цене на комплект от флайская с гарантированной дальнобойность в 1 км, зачем?
я вот не пойму, при весьма скромной цене на комплект от флайская с гарантированной дальнобойность в 1 км, зачем?
Дороговато 2нрф 2нано пару кнопок и пару потенциометров дешевле выходит. + мне нужны хотя бы ещё 2 серво потенциометра на пульт. А ковырять этого пульта за 75$ не. не. не.
найду ИгоряКа почитаю.
А чего его искать, 80% всех поисковых запросов на тему нрф24 ведут в ту тему
Я бы и использовал другие модули (как посоветовали лору) но есть только эти.
Если сейчас закажете у кЕтайцев нормальную пару дальнобойных радиомодулей, то к моменту, когда вы окончательно натрахаетесь до полного катерсиса с нрф24, глядишь, они уже и приедут. За пару часов спокойно все соберете и в заплыв
пусть уже этот проект будет на нрф24 на следующий будет лора.
Вот и сейчас не могу понять как работать с SoftwareSerial и Servo вместе. (NEO-6M в роли GPS приемника + серво) так как После подключение GPS все сервы с интервалом в 1 секунду (когда GPS отправляет пакет на ардуино нано) уходят в крайнее левое положение и возвращаются в центр циклически. При отключенном GPS такой проблемы нет.
пульт
катер
Я чего-то не догоняю, в 16 строке OUTPUT (tx?) где объявлен?
Стоковый Серво.х и СофтСериал несовместимы до степени отсутствия видимых проблем. Я уж года два как такую связку в руки не брал, но в то время просто так проблема не обходилась.
с ардуино.сс:
Hello!
I've solved this problem with AltSoftSerial and ServoTimer2. https://github.com/vrxfile/track_robot
In ServoTimer2.h it is necessary to comment the line typedef uint8_t boolean;
https://github.com/nabontra/ServoTimer2 https://github.com/PaulStoffregen/AltSoftSerial
Занятие первого таймера - это одна из проблем. Вторая заключается в том, что софтсериал блочит прерывания и Серво.х вызывает процедуру дерганья ногами по таймера неравномерно. Вследствие чего заполнение pwm начинает плавать, и серва дергается в момент работы SoftSerial.
продолжали есть кактус )))
Я чего-то не догоняю, в 16 строке OUTPUT (tx?) где объявлен?
tx для GPS в этом случае не нужен так как он только отправляет пакеты. Или как написать ардуинке что можно без tx ?
Так и есть. Поэтому в ATmega328p есть 3 таймера. Мне покачто как-то сложно с ними работать.. Не до конца воображается как это.
с ардуино.сс:
Hello!
I've solved this problem with AltSoftSerial and ServoTimer2. https://github.com/vrxfile/track_robot
In ServoTimer2.h it is necessary to comment the line typedef uint8_t boolean;
https://github.com/nabontra/ServoTimer2 https://github.com/PaulStoffregen/AltSoftSerial
Серво работает, a GPS нет. Хмм. #include <AltSoftSerial.h> что-то не видит пакеты из GPS
продолжали есть кактус )))
Нуу такое.. Ардуино СИЛА!) Разнообразие, свобода..
продолжали есть кактус )))
Нуу такое.. Ардуино СИЛА!) Разнообразие, свобода..
ааа, поиграться...тогда я сам такой )))
Если брать лору SX1278 будет норм ?