NRF24L01 прием/передача
- Войдите на сайт для отправки комментариев
Всем доброго дня! В среде программирования ардуино не долго, поэтому не серчайте, если буду тупить)
Хотел спросить у Вас вот чего, есть сеть состоящая из NRF24L01 по топологии звезда, как в даташите. Задача стоит показать прием/передачу каждого модуля. Написал прогу, но работает все не так, как бы хотелось. Суть работы в двух словах: каждый TX находится в состоянии приема, с нажатием кнопки начинает слать данные с номером модуля куда их передать, RX в свою очередь принимая определенный номер должен отослать данные на этот самый модуль. Так вот момент передачи данных работает, приема центром и отсылки тоже, а прием на конечном узле - нет. В чем косяк подскажите, если не трудно.
Код TX:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);
byte massiv[1];
byte massiv2[1];
uint8_t pipe;
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(18, OUTPUT);
pinMode(19, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(4, INPUT);
radio.begin();
radio.setChannel(5);
radio.setDataRate (RF24_1MBPS);
radio.setPALevel (RF24_PA_HIGH);
radio.openReadingPipe (0, 0xAABBCCDD66LL);
radio.openReadingPipe (1, 0xAABBCCDD11LL);
radio.openReadingPipe (2, 0xAABBCCDD22LL);
radio.openReadingPipe (3, 0xAABBCCDD33LL);
radio.openReadingPipe (4, 0xAABBCCDD44LL);
radio.openReadingPipe (5, 0xAABBCCDD55LL);
radio.startListening ();
}
void loop() {
if (radio.available(&pipe))
{
radio.read(massiv, 1);
if (massiv[0] == 1)
{
radio.stopListening();
massiv2[0] = 11;
radio.write(massiv2, 1);
digitalWrite(2, HIGH);
delay(1000);
}
if (massiv[0] == 2)
{
radio.stopListening();
massiv2[0] = 22;
radio.write(massiv2, 1);
digitalWrite(7, HIGH);
delay(1000);
}
if (massiv[0] == 3)
{
radio.stopListening();
massiv2[0] = 33;
radio.write(massiv2, 1);
digitalWrite(8, HIGH);
delay(1000);
}
if (massiv[0] == 4)
{
radio.stopListening();
massiv2[0] = 44;
radio.write(massiv2, 1);
digitalWrite(3, HIGH);
delay(1000);
}
if (massiv[0] == 5)
{
radio.stopListening();
massiv2[0] = 55;
radio.write(massiv2, 1);
digitalWrite(18, HIGH);
delay(1000);
}
if (massiv[0] == 6)
{
radio.stopListening();
massiv2[0] = 66;
radio.write(massiv2, 1);
digitalWrite(19, HIGH);
delay(1000);
}
}
}Код RX:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);
byte massiv[1];
byte massiv2[1];
int switchPin = 4;
int val;
int state;
int c;
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, INPUT);
radio.begin();
radio.setChannel(5);
radio.setDataRate (RF24_1MBPS);
radio.setPALevel (RF24_PA_HIGH);
radio.openWritingPipe (0xAABBCCDD11LL);
}
void loop() {
state = digitalRead(switchPin);
if (state == HIGH && c == 0)
{
c = 1;
}
if (state == LOW && c == 1)
{
val = ++val;
if (val == 7)
{
val = 0;
}
c = 0;
}
if (val == 0)
{
digitalWrite(6, HIGH);
digitalWrite(3, LOW);
radio.startListening();
delay(50);
if (radio.available())
{
radio.read(massiv2, 1);
if (massiv2[0] == 11)
{
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
}
}
}
if (val == 1)
{
digitalWrite(6, LOW);
radio.stopListening();
massiv[0] = 1;
radio.write(massiv, 1);
digitalWrite(3, HIGH);
}
if (val == 2)
{
digitalWrite(6, LOW);
radio.stopListening();
massiv[0] = 2;
radio.write(massiv, 1);
digitalWrite(3, HIGH);
}
if (val == 3)
{
digitalWrite(6, LOW);
radio.stopListening();
massiv[0] = 3;
radio.write(massiv, 1);
digitalWrite(3, HIGH);
}
if (val == 4)
{
digitalWrite(6, LOW);
radio.stopListening();
massiv[0] = 4;
radio.write(massiv, 1);
digitalWrite(3, HIGH);
}
if (val == 5)
{
digitalWrite(6, LOW);
radio.stopListening();
massiv[0] = 5;
radio.write(massiv, 1);
digitalWrite(3, HIGH);
}
if (val == 6)
{
digitalWrite(6, LOW);
radio.stopListening();
massiv[0] = 6;
radio.write(massiv, 1);
digitalWrite(3, HIGH);
}
delay(10);
}
модули работают или на прием или на передачу, поэтому надо после передачи переключать на прием
radio.startListening();модули работают или на прием или на передачу, поэтому надо после передачи переключать на прием
radio.startListening();Так, они же по умолчанию стоят на прием. В не нажатом состоянии, они слушают эфир, при нажатии уходят в передачу.
вы же останавливаете прием, и не возобновляете :)
вы же останавливаете прием, и не возобновляете :)
Вы имеете ввиду в коде TX? Или я что-то не догоняю)
Просто получается, что к примеру с 4 модуля ушла единичка на центр, центр ее обработал и полслал 11, в свою очередь 1 модуль услышал и отреагировал. Так вот с последним проблема.
у вас везде
radio.stopListening();а старта нигде нет, кроме сетапа, который срабатывает один разу вас везде
radio.stopListening();а старта нигде нет, кроме сетапа, который срабатывает один разТеперь понял, попробую, спасибо)
Поправил, проблема не ушла, видимо где-то в приеме RX косяк.
if (val == 0) { digitalWrite(6, HIGH); digitalWrite(3, LOW); radio.startListening(); delay(50); if (radio.available()) { radio.read(massiv2, 1); if (massiv2[0] == 11) { digitalWrite(5, HIGH); digitalWrite(6, HIGH); } } }не забывайте, на переключение с приема на передачу и обратно время уходит, надо ставить задержки около 20 мс
на передатчике тоже , т. е. попасть передачей тогда, когда приемник начал уже слушать
не забывайте, на переключение с приема на передачу и обратно время уходит, надо ставить задержки около 20 мс
на передатчике тоже , т. е. попасть передачей тогда, когда приемник начал уже слушать
То есть здесь на RX:
if (val == 1) { digitalWrite(6, LOW); radio.stopListening(); delay(20); massiv[0] = 1; radio.write(massiv, 1); digitalWrite(3, HIGH); }И здесь на TX:
if (massiv[0] == 1) { radio.stopListening(); delay(20); massiv2[0] = 11; radio.write(massiv2, 1); digitalWrite(2, HIGH); delay(1000); digitalWrite(2, LOW); }у вас опять нет строки переключающей на прием
у вас опять нет строки переключающей на прием
Я ее в loop сразу поставил, неверно?
void loop() { radio.startListening(); if (radio.available(&pipe)) { radio.read(massiv, 1); } }так нельзя
надо так
radio.stopListening(); radio.write(&data_out, sizeof(data_out) ); radio.startListening();Вот так:
if (massiv[0] == 1) { radio.stopListening(); delay(20); massiv2[0] = 11; radio.write(&massiv2, sizeof(massiv2)); digitalWrite(2, HIGH); delay(1000); digitalWrite(2, LOW); radio.startListening(); }дааааа, delay 1000?
у вас на 1 секунду все умирает, используйте millis();
Походу че-то не верно я сделал, так как прием на центральном модуле тоже ушел:
unsigned long time; void loop() { if (massiv[0] == 1) //если пришла 1, то нужно отправить данные на TX1 { radio.stopListening(); delay(20); massiv2[0] = 11; radio.write(&massiv2, sizeof(massiv2)); digitalWrite(2, HIGH); time = millis(); digitalWrite(2, LOW); radio.startListening(); } }Все-таки на RX косяк может??
c millis сначала разберитесь
c millis сначала разберитесь
Так?
if (massiv[0] == 1) //если пришла 1, то нужно отправить данные на TX1 { radio.stopListening(); delay(20); massiv2[0] = 11; radio.write(&massiv2, sizeof(massiv2)); if (currentMillis - previousMillis > interval) { previousMillis = currentMillis; digitalWrite(2, HIGH); } radio.startListening(); }Думаю проблема может еще быть в том, что модули настроены на передачу, и поэтому не могут принимать данные:
Или я не прав, и модули могут и принимать при таких настройках? Если так, то тогда как их перенастроить для приема от центра, командой:
но как это сделать правильно?
да, надо
const uint64_t pipe[2] = {0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL};и в сетапе
это получается 1 центр и еще 5 дочерних? и как задать адрес центра?
То есть 0xAABBCCDD11LL - центр, 0xAABBCCDD22LL,.. дочерние:
const uint64_t pipe[2] = {0xAABBCCDD11LL, 0xAABBCCDD22LL};И так для других?
да, одна для передачи, другая для приема
если ипользовать то что я дал первым, то это пусть будет центр, а для дочерних тогда так
А количесвто дочерних только 5 да?
хоть 100, если опрашивать по очереди по одному
Спасибо Valera19701, прием - передача теперь работает, но вот каксделать, чтобы они друг другу не мешали?
void loop() { radio.openReadingPipe (1, pipe[1]); if (radio.available()) { radio.read(&data2, sizeof(data2)); digitalWrite(2, HIGH); lcd.setCursor(0, 0); lcd.print(data2[0]); radio.startListening(); } radio.openReadingPipe (1, pipe[4]); if (radio.available()) { radio.stopListening (); radio.write(&data2, sizeof(data2)); digitalWrite(3, HIGH); radio.startListening(); } radio.openReadingPipe (1, pipe[2]); if (radio.available()) { radio.read(&data, sizeof(data)); digitalWrite(7, HIGH); lcd.setCursor(7, 0); lcd.print(data[0]); radio.startListening(); } radio.openReadingPipe (1, pipe[5]); if (radio.available()) { radio.stopListening (); radio.write(&data, sizeof(data)); digitalWrite(18, HIGH); radio.startListening(); } }я же написал, опрашивать по одному, оставить 2 pipe, и например первым байтом передавать число,
, а на приемниках принимать это число, если оно совпадает с передаваемым то отвечать на запрос, както так
Просто свзяь работает хорошо, но по одному, да и важно чтобы были отдельные каналы. Может просто на время глушить как-то? И странно что информация передается в разных массивах, и все равно перемешивается, то есть массив data, для одного приемника вмешивается в массив data2 для другого.
Реализовать к примеру опрос 3 модулей записать данные в массив, а затем эти данные разослать другим 3.
я не знаю вашу задачу, но у себя с двумя каналами (pipe) за 1 сек я опрашиваю 30 датчиков
Сеть, центральная точка, 6 дочерних, с 3 данные принимаем, другим 3 передаем, прием работает, а отсылка данных сбивает все.
ну так присвойте каждой точке чтото типа номера (device id), например 1, 2, 3 в первый байт массива и таким образом распознавайте что и кому
Так в том то и дело, что информация доходит и распознается, вопрос только как сделать чтобы, не мешали друг другу и не перебивали информацию соседа.
я же писал, по очереди, например отправил запрос на 1 устройство- переключился на прием, дождался ответа, переключился на передачу отправил на 2 и т. д. на дочерних также, все время слушают, получил свой id, переключился на передачу, отправил, и опять на прием
То есть как то так:
дочерняя:
void loop() { radio.startListening (); if (radio.available()) { radio.read(&zapros, sizeof(zapros)); if (zapros[1] == 1) { radio.stopListening (); digitalWrite(Trig, HIGH); delayMicroseconds(10); // равный 10 микросекундам digitalWrite(Trig, LOW); // Отключаем impulseTime = pulseIn(Echo, HIGH); // Замеряем длину импульса distance_sm = impulseTime / 58; // Пересчитываем в сантиметры Serial.println(distance_sm); // Выводим на порт data2[0] = distance_sm; radio.write(&data2, sizeof(data2)); digitalWrite(3, HIGH); delay(100); radio.startListening (); } } }центр:
void loop() { radio.openReadingPipe (1, pipe[1]); radio.stopListening (); zapros[1] = 1; radio.write(&zapros, sizeof(zapros)); delay(100); digitalWrite(2, HIGH); radio.startListening (); if (radio.available()) { radio.read(&data2, sizeof(data2)); digitalWrite(2, HIGH); lcd.setCursor(0, 0); lcd.print(data2[0]); lcd.print(" cm "); delay(500); } }Блин. Вам руки надо за delay() поотбивать
Блин. Вам руки надо за delay() поотбивать
Если будет работать, то ок)
А ваша проблема заставить работать вашу голову, а я так просто указываю на ваши ошибки(имхо разумеется)
void loop() { radio.startListening (); if (radio.available()>=sizeof(zapros) { // <- когда пакет полностью в буфере, а не только 1 первый байт radio.read(&zapros, sizeof(zapros)); } }Не слышит дочерняя. Еще ошибки?
Лиди подскажите пожалуйста кусочек кода, где реализовано переключение каналов.
Вы уже сюда перешли! Я понял так, Вам нужно переключать каналы на НРФ24, с помощью кнопки - включил ардуино это 1 канал, нажал на кнопку 2 канал , еще раэ нажал 3, еще раз 1 канал, можно сделать на сколько хотите. Вот есть урок про кнопку ,
http://ampexpert.ru/arduino-urok-3-knopka/
в конце посмотрите код, как раз для Вас. Только в коде в режимах 1, 2, 3, 4 впишите строку radio.setChannel(0x70); В кавычках вставте канал какой Вам нужен.
этот код соедените со своим.
int regim=1; int flag=0; void setup(){ pinMode(2,INPUT); // кнопка } void loop(){ if(digitalRead(2)==HIGH&&flag==0)//если кнопка нажата // и перемення flag равна 0 , то ... { regim++; flag=1; //это нужно для того что бы с каждым нажатием кнопки //происходило только одно действие // плюс защита от "дребезга" 100% if(regim>4)//ограничим количество режимов { regim=1;//так как мы используем только одну кнопку, // то переключать режимы будем циклично } } if(digitalRead(2)==LOW&&flag==1)//если кнопка НЕ нажата //и переменная flag равна - 1 ,то ... { flag=0;//обнуляем переменную "knopka" } if(regim==1)//первый режим { radio.setChannel(0x70); } if(regim==2)//второй режим { radio.setChannel(0x71); } if(regim==3)//третий режим { radio.setChannel(0x72); } if(regim==4)//четвертый режим { radio.setChannel(0x73); } }Поделитесь пожалуйста примером своей реализации. Очень интересно. Бьюсь уже которую неделю, не выходит каменный цветок..