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();//разрешить отсылку данных в ответ на входящий сигналПример моего кода для настройки
void radioSetup() { // настройка радио модуля radio.begin(); // активировать модуль radio.setAutoAck(1); // режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); // (время между попыткой достучаться, число попыток) radio.setPayloadSize(32); // размер пакета, байт radio.openReadingPipe(1, address[0]); // хотим слушать трубу 0 radio.openWritingPipe(address[1]); // хотим писать на трубу по первому адресу radio.setChannel(CH_NUM); // выбираем канал radio.setPALevel(SIG_POWER); // задаем уровень мощности передатчика RF24_PA_MAX radio.setDataRate(SIG_SPEED); // задаем скорость обмена RF24_1MBPS // должна быть одинакова на приёмнике и передатчике! // при самой низкой скорости имеем самую высокую чувствительность и дальность!! (логично) radio.powerUp(); // начать работу radio.startListening(); // начинаем слушать эфир, мы приёмный модуль }Вы с благородным доном 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 на разных версиях модуля.
не нравится Аск - можно ведь работать и без него. Просто передали что надо, выключили передатчик, включили приемник, слушаем эфир...
не знаю, не испытывал проблем заставить НРФ-ки работать с переключением между приемом и передачей.
Да, все так, это базовая практика. АвтоАск первым отключается при поиске проблем. Но только проблемы на этом не заканчиваются))
На мой взгляд, проблема именно с китайскими модулями. Но от этого не легче. Из за этого, подбирая рабочий вариант, приходится действовать методом тыка. Потому как, бывало, у себя на тестовых образцах работает, а у заказчика ни в какую.(
Передатчик
#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]; float ackData[1]; int valMotor; int valServo1; int valServo2; int valServo3; const int potPinMotor = 0; const int potPinRole = 1; const int potContainerServo1 = 3; const int potContainerServo2 = 4; void setup() { Serial.begin(115200); pinMode(potPinMotor, INPUT); pinMode(potPinRole, INPUT); pinMode(potContainerServo1, INPUT); pinMode(potContainerServo2, INPUT); radio.begin(); //radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(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 //должна быть одинакова на приёмнике и передатчике! 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; radio.write(&transmit_data, sizeof(transmit_data)); if( radio.isAckPayloadAvailable()){ // Если в буфере имеются принятые данные из пакета подтверждения приёма, то ... radio.read(&ackData, sizeof(ackData)); // Читаем данные из буфера в массив ackData указывая сколько всего байт может поместиться в массив. Serial.println(ackData[0]); }else{Serial.println("not ask");} // Serial.print("valMotor: "); // Serial.println(transmit_data[0]); }Приемник
#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 = 900; // интервал разрыва связи int lastTime = 0; float vout = 0.0; // переменные для вольтметра float vin = 1.0; float R1 = 61000.0; // resistance of R1 (60K) -see text! float R2 = 10000.0; // resistance of R2 (10K) – see text! int value = 0; byte recieved_data[4]; float ackData[1]; void setup(){ motor.attach(2); servo1.attach(3); servo2.attach(4); servo3.attach(5); Serial.begin(115200); //открываем порт для связи с ПК radio.begin(); //активировать модуль printf_begin(); // radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах 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.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() { if(radio.available()){ // слушаем эфир со всех труб 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.println(recieved_data[0]); value = analogRead(A0); vout = (value * 5.0) / 1024.0; // see text vin = vout / (R2/(R1+R2)); Serial.println(vin); ackData[0] = vin; radio.writeAckPayload (1, &ackData, sizeof(ackData) ); // запишем в radio.enableAckPayload(); } int dt = millis() - lastTime; if (dt >= timeout) { Serial.println(dt); motor.write(29); servo1.write(92); } }Хмм.. Сделал, но 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 такой проблемы нет.
пульт
#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include "nRF24L01.h" // Подключаем файл конфигурации из библиотеки RF24 #include "RF24.h" // Подключаем библиотеку для работа для работы с модулем NRF24L01 #include "printf.h" // Инфо NRF24L01 #include <iarduino_OLED_txt.h> // OLED SSD1306 #include <Servo.h> RF24 radio(9, 10); // CE, CSN модуль nrf24l01 + pa + lna на пинах RF24 radio(9,10); Для Уно/нано. RF24 radio(9,53); для Меги. iarduino_OLED_txt myOLED_1(0x3D); // Объявляем объект myOLED_1_1, указывая адрес первого дисплея на шине I2C: 0x3C. byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб extern uint8_t SmallFontRus[]; //Шрифт OLED uint32_t myTimer1; //таймер byte transmit_data[4]; float ackData[5]; int error = -1; float input_volt = 0.0; // переменные для вольтметра float temp = 0.0; float r1 = 101000.0; //сопротивление резистора r1 float r2 = 10000.0; // сопротивление резистора r2 int value = 0; byte speedGPS; byte GPSsatelite; int compass; float VoltageShip; int valMotor; int valServo1; int valServo2; int valServo3; const int potPinMotor = 0; const int potPinRole = 1; const int potContainerServo1 = 3; const int potContainerServo2 = 6; void setup() { //Serial.begin(115200); myOLED_1.begin(); radio.begin(); pinMode(potPinMotor, INPUT); pinMode(potPinRole, INPUT); pinMode(potContainerServo1, INPUT); pinMode(potContainerServo2, INPUT); myOLED_1.setFont(SmallFontRus); //radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(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_1MBPS);//скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! printf_begin(); radio.printDetails(); myOLED_1.print ("Скорость:", 0, 0); myOLED_1.print ("%>", 70, 0); myOLED_1.print ("КМ/ч", 103, 0); myOLED_1.print ("Джойстик:", 0, 1); myOLED_1.print ("АКБ пульта:", 0, 2); myOLED_1.print ("v", 92, 2); myOLED_1.print ("АКБ катера:", 0, 3); myOLED_1.print ("v", 97, 3); myOLED_1.print ("GPS спутников:", 0, 4); myOLED_1.print ("GPS компас:", 0, 5); myOLED_1.print ("Ошибок связи:", 0, 7); } void loop() { valMotor = analogRead(potPinMotor); valMotor = map(valMotor, 0, 1023, 28, 255); transmit_data[0] = valMotor; valMotor = map(valMotor, 28, 255, 0, 99); 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; radio.write(&transmit_data, sizeof(transmit_data)); if ( radio.isAckPayloadAvailable()) { // Если в буфере имеются принятые данные из пакета подтверждения приёма, то ... radio.read(&ackData, sizeof(ackData)); // Читаем данные из буфера в массив ackData указывая сколько всего байт может поместиться в массив. VoltageShip = ackData[0]; GPSsatelite = ackData[1]; speedGPS = ackData[2]; compass = ackData[3]; } else { error++; myOLED_1.setCursor(80, 7); myOLED_1.print (error); myOLED_1.print (" "); } int analogvalue = analogRead(A7); temp = (analogvalue * 5.0) / 1024.0; // формула для конвертирования значения напряжения input_volt = temp / (r2 / (r1 + r2)); if (input_volt < 0.1) { input_volt = 0.0; } valServo1 = map(valServo1, 80, 103, 15, -15); myOLED_1.setCursor(53, 0); myOLED_1.print(valMotor); myOLED_1.print (" "); myOLED_1.setCursor(87, 0); myOLED_1.print (speedGPS); myOLED_1.print (" "); myOLED_1.setCursor(53, 1); myOLED_1.print (valServo1); myOLED_1.print (" Град. "); myOLED_1.setCursor(66, 2); myOLED_1.print (input_volt); myOLED_1.setCursor(66, 3); myOLED_1.print (VoltageShip); myOLED_1.setCursor(87, 4); myOLED_1.print (GPSsatelite); myOLED_1.print (" "); myOLED_1.setCursor(66, 5); myOLED_1.print (compass); myOLED_1.print (" Град. "); if (millis() - myTimer1 >= 1000) { // ищем разницу (количество мс) myTimer1 = millis(); // сброс таймера } // Serial.print("valMotor: "); // Serial.println(transmit_data[0]); }катер
#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include "nRF24L01.h" // Подключаем файл конфигурации из библиотеки RF24 #include "RF24.h" // Подключаем библиотеку для работа для работы с модулем NRF24L01 #include "printf.h" // Инфо NRF24L01 #include <Servo.h> #include <TinyGPS++.h> //Работа с GPS #include <SoftwareSerial.h> //Для GPS Servo motor; Servo servo1; Servo servo2; Servo servo3; TinyGPSPlus gps; RF24 radio(9, 10); // CE, CSN модуль nrf24l01 + pa + lna на пинах RF24 radio(9,10); Для Уно/нано. RF24 radio(9,53); для Меги. SoftwareSerial SerialGPS(7, OUTPUT); byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб int timeout = 500; // интервал разрыва связи int lastTime = 0; float input_volt = 0.0; // переменные для вольтметра float temp = 0.0; float r1 = 93150.0; //сопротивление резистора r1 float r2 = 10000.0; // сопротивление резистора r2 int value = 0; byte recieved_data[4]; float ackData[5]; void setup() { motor.attach(2); servo1.attach(3); servo2.attach(4); servo3.attach(5); Serial.begin(115200); //открываем порт для связи с ПК SerialGPS.begin(9600); //открываем порт для связи с GPS (только 9600 - читать мануал) radio.begin(); //активировать модуль printf_begin(); // radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах 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_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.printDetails(); 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() { if (radio.available() > 0) { // слушаем эфир со всех труб 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.write(recieved_data[1]); int analogvalue = analogRead(A0); temp = (analogvalue * 5.0) / 1024.0; // формула для конвертирования значения напряжения input_volt = temp / (r2 / (r1 + r2)); ackData[0] = input_volt; while (SerialGPS.available() > 0) { //Работа с TinyGPS++ if (gps.encode(SerialGPS.read())) { ackData[1] = gps.satellites.value(); ackData[2] = gps.speed.kmph(); ackData[3] = gps.course.deg(); } } radio.writeAckPayload (1, &ackData, sizeof(ackData) ); // запишем в radio.enableAckPayload(); } int dt = millis() - lastTime; if (dt >= timeout) { Serial.println(dt); motor.write(29); servo1.write(91); } }Я чего-то не догоняю, в 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
#include <SPI.h> // Подключаем библиотеку для работы с SPI-интерфейсом #include "nRF24L01.h" // Подключаем файл конфигурации из библиотеки RF24 #include "RF24.h" // Подключаем библиотеку для работа для работы с модулем NRF24L01 #include "printf.h" // Инфо NRF24L01 #include <TinyGPS++.h> //Работа с GPS #include <ServoTimer2.h> #include <AltSoftSerial.h> //Для GPS ServoTimer2 motor; ServoTimer2 servo1; ServoTimer2 servo2; ServoTimer2 servo3; TinyGPSPlus gps; RF24 radio(9, 10); // CE, CSN модуль nrf24l01 + pa + lna на пинах RF24 radio(9,10); Для Уно/нано. RF24 radio(9,53); для Меги. AltSoftSerial SerialGPS(7, OUTPUT); byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб int timeout = 500; // интервал разрыва связи int lastTime = 0; float input_volt = 0.0; // переменные для вольтметра float temp = 0.0; float r1 = 93150.0; //сопротивление резистора r1 float r2 = 10000.0; // сопротивление резистора r2 int value = 0; byte recieved_data[4]; float ackData[5]; void setup() { motor.attach(2); servo1.attach(3); servo2.attach(4); servo3.attach(5); Serial.begin(9600); //открываем порт для связи с ПК SerialGPS.begin(9600); //открываем порт для связи с GPS (только 9600 - читать мануал) radio.begin(); //активировать модуль printf_begin(); // radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах 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_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.printDetails(); 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() { if (radio.available() > 0) { // слушаем эфир со всех труб lastTime = millis(); radio.read( &recieved_data, sizeof(recieved_data) ); // чиатем входящий сигнал motor.write(map(recieved_data[0], 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH)); servo1.write(map(recieved_data[1], 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH)); servo2.write(map(recieved_data[2], 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH)); servo3.write(map(recieved_data[3], 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH)); Serial.println(recieved_data[1]); int analogvalue = analogRead(A0); temp = (analogvalue * 5.0) / 1024.0; // формула для конвертирования значения напряжения input_volt = temp / (r2 / (r1 + r2)); ackData[0] = input_volt; while (SerialGPS.available() > 0) { //Работа с TinyGPS++ if (gps.encode(SerialGPS.read())) { ackData[1] = gps.satellites.value(); ackData[2] = gps.speed.kmph(); ackData[3] = gps.course.deg(); } } radio.writeAckPayload (1, &ackData, sizeof(ackData) ); // запишем в radio.enableAckPayload(); } int dt = millis() - lastTime; if (dt >= timeout) { Serial.println(dt); motor.write(map(28, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH)); servo1.write(map(91, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH)); } }продолжали есть кактус )))
Нуу такое.. Ардуино СИЛА!) Разнообразие, свобода..
продолжали есть кактус )))
Нуу такое.. Ардуино СИЛА!) Разнообразие, свобода..
ааа, поиграться...тогда я сам такой )))
Если брать лору SX1278 будет норм ?