Вопросы по NRF24L01

PiratFox

★★★★★✩✩
13 Фев 2020
1,692
471
@Денис Сергеевич, либо Вы что-то упустили, либо у Вас какие-то левые модули. Других причин нет. К сожалению, ясновидящих тут тоже нет. Разве что остаётся ещё вопрос: откуда Вы берёте 3,3в для питания радиомодулей?
 
Изменено:

Grover

✩✩✩✩✩✩✩
21 Фев 2023
1
0
Здравствуйте, я начинающий ардуинщик. Занимаюсь реализацией проекта, который заключается в передаче дискретного сигнала с четырех герконовых датчиков на одно устройство-приемник (с помощью Wi-fi модуля nRF24l01). Каждый передатчик сообщает приемнику о том, что он среагировал на магнит, а устройство приемник подсчитывает, сколько раз среагировал каждый передатчик. Проблема заключается в том, что период опроса всех четырех передатчиков в среднем составляет 2 секунды, вследствие чего, когда какой либо из передатчиков проходит мимо магнита, он может просто не успеть передать эту информацию приемнику и срабатывание не будет засчитано. Программно задал максимальную скорость передачи пакетов данных. Подключены передатчики к питанию через понижающие модули, конденсаторы припаяны, как и все контакты. Возможно ли, что дело в скорости взаимодействия между nRF модулем и самой платой ардуино? Или это никак не влияет на скорость опроса? Возможно ли сделать так, чтобы передатчик (если за период опроса прошел магнит, но не успел отправить об этом информацию, пока значение на нем было High), каким либо образом отправил информацию о пройденной метке в следующий опрос?

TX:
#include <SPI.h>                            // Подключаем библиотеку для работы с шиной SPI.
#include <nRF24L01.h>                       // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>                           // библиотека для работы с nRF24L01+ https://yadi.sk/d/nX_akvzEusyGz
RF24 radio(9, 10);                          // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN).
                                            // Создаём переменную для передачи данных
int buttonPin = 2;                          // Номер пина, к которому подключен геркон
int buttonState = 0;                        // Переменная для записи состояния геркона
                

void setup() {
  pinMode(buttonPin, INPUT);                // Включаем второй пин на ввод
                                            // LED. процесс приёма / передачи, подтверждаем миганием светодиода
  radio.begin();                            // Инициируем работу nRF24L01+.
  radio.setChannel(100);                    // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц.(на одном канале можно, одновременно иметь "1 передатчик-рот-труба" или "6 приёмников-ушей-трубы"
  radio.setDataRate     (RF24_2MBPS);         // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS). При скорости 2 Мб/с, задействуются сразу два канала (выбранный и следующий за ним). (самая дальнобойная 250KBPS, но скорость меньше)
  radio.setPALevel      (RF24_PA_MIN);      // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm).
  radio.openWritingPipe (0xAABBCCDD33LL);   // Открываем трубу с идентификатором 0xAABBCCDD11 (для передачи данных). на одном канале может быть только 1 труба, для передачи). (последний байт "идентификатора-передатчика (11)" нужен для распознавания трубами приёмника, которых может быть до 6-на одном канале).
}
void loop () {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {               
    radio.write(&buttonState, sizeof(buttonState));  // отправляем данные на другую Arduino. sizeof(TEST)))-указываем, сколько байт мы хотим отправить)(Приемник отправляет передатчику сигнал подтверждения приёма данных (без смены режима работы).
  }
  else{
    radio.write(&buttonPin, sizeof(buttonPin));
    }
  delay(50);                                         // "delay" устанавливаем задержку на 50 мс, за это время приемник успеет принять и обработать данные этого и другого передатчика.
}

RX:
#include <SPI.h>                             // Подключаем библиотеку  для работы с шиной SPI
#include <nRF24L01.h>                        // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>                            // библиотека для работы с nRF24L01+ https://yadi.sk/d/nX_akvzEusyGz
#include <SoftwareSerial.h>                  // библиотека для создания дополнительного UART порта из двух пинов


RF24           radio(9, 10);                 // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)
byte pipe;                                    // Создаём переменную  для хранения номера трубы, по которой пришли данные                                    // Создаём переменную для приема данных
int TEST;
int pipe_i = 1;

int sum[] = {0, 0, 0, 0};
int TEST_1[] = {1, 1, 1, 1};
int res1 = 0;
int res2 = 0;

int result = 0;
int A = 0;
int B = 33;
int C = 66;
int D = 100;

void setup() {
 
  Serial.begin(9600);
  
  delay(1000);                               // перед первой командой инициализацией nRF24L01+, лучше сделать паузу. припаять конденсатор между выводами плюс и минус nRF24L01+
  radio.begin();                             // Инициируем работу nRF24L01+
  radio.setChannel(100);                       // Указываем канал приёма данных (от 0 до 127), 5 - значит приём данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
  radio.setDataRate     (RF24_2MBPS);      // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS). При скорости 2 Мб/с, задействуются сразу два канала (выбранный и следующий за ним). (самая дальнобойная 250KBPS, но скорость меньше)
  radio.setPALevel      (RF24_PA_MIN);      // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
  radio.openReadingPipe (1, 0xAABBCCDD11LL); // Открываем 1 трубу с идентификатором 0xAABBCCDD11 для приема данных ("приёмник"-на одном канале может быть открыто до 6 разных труб), (которые должны отличаться только последним байтом идентификатора)
  radio.openReadingPipe (2, 0xAABBCCDD22LL); // Открываем 2 трубу с идентификатором 0xAABBCCDD22 для приема данных (То есть может одновременно ловить сигнал от шести таких же модулей, передающих на одном частотном канале)
  radio.openReadingPipe (3, 0xAABBCCDD33LL);
  radio.openReadingPipe (4, 0xAABBCCDD44LL);
  radio.startListening  ();                  // Включаем приемник, начинаем прослушивать открытую трубу
  //  radio.stopListening   ();              // Выключаем приёмник, если потребуется передать данные

}

void loop() {
    
  if (radio.available(&pipe)) {              // Если в буфере имеются принятые данные, то получаем номер трубы, по которой они пришли, по ссылке на переменную pipe
    radio.read(& TEST, sizeof(TEST));         // Читаем данные в переменную TEST и указываем сколько байт читать
    
    if (pipe == pipe_i){                                //конструкция для поочередного опроса передатчиков с 1 по 4
      if (TEST != TEST_1[pipe_i-1] && TEST == 2){        //С помощью этого условия фиксируется переход состояния геркона передатчика с High на Low и наоборот
        sum[pipe_i-1] += 1;
        }
        TEST_1[pipe_i-1] = TEST;
        pipe_i++;
        if (pipe_i == 5)
        pipe_i = 1;
        }
  }
}
 

k5sha..

✩✩✩✩✩✩✩
15 Мар 2023
1
0
Здраствуйте все пользователи. У меня появился вопрос возможно ли как-то на камушек Attiny26 закинуть библиотеку nRF24L01.h и использовать nRF24L01.
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,692
471
@k5sha.., а самому просто взять и попробовать, не? Впрочем, с 2к флеши пустая затея. Да и непонятно зачем...
 
Изменено:

te238s

★★✩✩✩✩✩
14 Ноя 2021
376
95
Подключить-то не проблема. SPI есть на борту. Ну а размер памяти...Вам решать,хватит ли.
 

MeL_0MaN

✩✩✩✩✩✩✩
23 Май 2023
1
0
Написал 2 скетча, первый передает данные с гироскопа-аксеерометра(ГА) GY-521 при помощи nrf модуля, второй их принимает.
В обоих скетчах в порт выводятся значения с ГА (до отправки и после соответственно).
Проблема в том, что в скетче приемника в порт приходят совсем не правильные значения, хотя в передатчике они верные. (скрины приложил).
В порту приемника значения меняются сами по себе и в больших диапазонах, на втором скрине видно (датчик неподвижен).
Я тут новичек, с ардуино плохо знаком, прошу помощи.
ПЕРЕДАТЧИК:
#include <SPI.h>          // библиотека для работы с шиной SPI
#include "nRF24L01.h"     // библиотека радиомодуля
#include "RF24.h"
#include<Wire.h>

RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно

byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

void setup(){
   Serial.begin(9600);         // открываем порт для связи с ПК

  radio.begin();              // активировать модуль
  radio.setAutoAck(1);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    // (время между попыткой достучаться, число попыток)
  radio.enableAckPayload();   // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах

  radio.openWritingPipe(address[0]);  // мы - труба 0, открываем канал для передачи данных
  radio.setChannel(0x0a);             // выбираем канал (в котором нет шумов!)

  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.powerUp();        // начать работу
  radio.stopListening();  // не слушаем радиоэфир, мы передатчик

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}

void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

radio.write(&AcX, sizeof(AcX)); // передаем данные по радиоканалу
radio.write(&AcY, sizeof(AcY));
radio.write(&AcZ, sizeof(AcZ));
radio.write(&Tmp, sizeof(Tmp));
radio.write(&GyX, sizeof(GyX));
radio.write(&GyY, sizeof(GyY));
radio.write(&GyZ, sizeof(GyZ));

   Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);

delay(100);
}
ПРИЕМНИК:
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(9, 10);  // "создать" модуль на пинах 9 и 10 Для Уно
//RF24 radio(9,53); // для Меги

byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

void setup() {
  Serial.begin(9600);         // открываем порт для связи с ПК
  radio.begin();              // активировать модуль
  radio.setAutoAck(1);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    // (время между попыткой достучаться, число попыток)
  radio.enableAckPayload();   // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах

  radio.openReadingPipe(1, address[0]);   // хотим слушать трубу 0
  radio.setChannel(0x0a);     // выбираем канал (в котором нет шумов!)

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

void loop() {
byte pipeNo;
  while (radio.available(&pipeNo)) {        // слушаем эфир со всех труб
radio.read(&AcX, sizeof(AcX)); // читаем данные с радиоканала
radio.read(&AcY, sizeof(AcY));
radio.read(&AcZ, sizeof(AcZ));
radio.read(&Tmp, sizeof(Tmp));
radio.read(&GyX, sizeof(GyX));
radio.read(&GyY, sizeof(GyY));
radio.read(&GyZ, sizeof(GyZ));
}
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
 
}
Передатчик порт:
передатчик порт.jpg

Приемник порт:
прием порт.jpg
 

Sasauge

✩✩✩✩✩✩✩
3 Июн 2023
8
0
Есть 2 nrf24l01+ и ардуино уно и нано. Проблема: Передатчик вроде что то передает , но приемник принимает только последние цифры при выключении передатчика


Код:
TX на уно
#include <SPI.h>          // библиотека для работы с шиной SPI
#include <nRF24L01.h>     // библиотека радиомодуля
#include <RF24.h>         // ещё библиотека радиомодуля

RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
//RF24 radio(9,53); // для Меги

byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

byte counter;

void setup() {
  Serial.begin(9600);         // открываем порт для связи с ПК

  radio.begin();              // активировать модуль
  radio.setAutoAck(0);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(10, 15);    // (время между попыткой достучаться, число попыток)
  // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах

  radio.openWritingPipe(address[0]);  // мы - труба 0, открываем канал для передачи данных
  radio.setChannel(0x60);             // выбираем канал (в котором нет шумов!)

  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.powerUp();        // начать работу
  radio.stopListening();  // не слушаем радиоэфир, мы передатчик
}

void loop() {
  Serial.print("Sent: ");
  Serial.println(counter);
  radio.write(&counter, sizeof(counter));
  counter++;
  delay(10);
}
Код:
/*   Данный скетч делает следующее: передатчик (TX) отправляет массив
     данных, который генерируется согласно показаниям с кнопки и с
     двух потенциомтеров. Приёмник (RX) получает массив, и записывает
     данные на реле, сервомашинку и генерирует ШИМ сигнал на транзистор.
    by AlexGyver 2016
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(5, 6);  // "создать" модуль на пинах 9 и 10 Для Уно
//RF24 radio(9,53); // для Меги

byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

void setup() {
  Serial.begin(9600);         // открываем порт для связи с ПК
  radio.begin();              // активировать модуль
  radio.setAutoAck(0);        // режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(10, 15);    // (время между попыткой достучаться, число попыток)
  // разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);   // размер пакета, в байтах

  radio.openReadingPipe(1, address[0]);   // хотим слушать трубу 0
  radio.setChannel(0x60);     // выбираем канал (в котором нет шумов!)

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

void loop() {
  byte pipeNo, gotByte;
  while(radio.available(&pipeNo)) {        // слушаем эфир со всех труб
    radio.read(&gotByte, sizeof(gotByte));  // чиатем входящий сигнал
    Serial.print("Recieved: ");
    Serial.println(gotByte);
  }
}
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,784
575
44
Какие модули: с нарисованной или с внешней антенной?
Какое расстояние передачи?
Как подключаете по питанию?
 

Sasauge

✩✩✩✩✩✩✩
3 Июн 2023
8
0
@PiratFox, через какойто модуль который с 5в в 3 превращает к нему нрф полностью подключена
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,784
575
44
@Sasauge, NRF24L01 очень капризные модули.
Возьмите примеры (где то в ардуине) передатчика и приемника, чтобы убедиться что это не программная ошибка.
По питанию модуля (3.3В) подключить дополнительный электролитический конденсатор 100-200мкФ обычно достаточно.
Мощность обязательно должна быть минимальная, можно еще скорость передачи поставить минимальную. Попробовать накрутить на передатчике пару витков провода, либо зажать антенну пальцами.
 
  • Лойс +1
Реакции: PiratFox

Sasauge

✩✩✩✩✩✩✩
3 Июн 2023
8
0
@PiratFox, с питанием все норм и модули менял

приемник пишет в монитор порта когда я нажимаю кнопку ресет на плате передатчика или открываю монитор передатчика
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,692
471
@Sasauge, ну, ещё может быть хреновый или нестабильный контакт проводов, соединяющих ардуину и модуль. Если это собрано на разъёмах "дюпонт", то почти наверняка дело в них, это редкое говнище. Да, попробуйте загрузить примеры из библиотек, как советовал @Геннадий П, чтобы исключить программные косяки.
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,692
471
@Sasauge, должны быть в папке "examples" библиотеки. У меня сейчас нет рабочего компьютера под рукой, поэтому точнее не скажу, просто не помню.
 

te238s

★★✩✩✩✩✩
14 Ноя 2021
376
95
Для начала размер пакета уменьшить до 1 байта. Зачем остальные 31 ? Вероятность ошибок в эфире сокращается раз в...несколько,не помню скок там заголовок занимает.
Может дело в приёме 32 байт и чтении лишь 1 первого?
И вообще в radio.read и radio.write укажите явно размер переменной,дабы избежать неопределённостей.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,784
575
44
И вообще в radio.read и radio.write укажите явно размер переменной,дабы избежать неопределённостей.
Но ведь указано: sizeof(counter) и sizeof(gotByte). Переменные обе byte, так что передается и принимается одинаковое кол-во данных.

Вообще, это нормально что они с первого раза не заработали, не стОит унывать. У меня у самого когда первый раз их подключил, то около недели с ними возился, в итоге кое-как их победил. :)
 
  • Лойс +1
Реакции: te238s

te238s

★★✩✩✩✩✩
14 Ноя 2021
376
95
@Геннадий П,это указывает: записать в буфер нрф 1 байт. Но! В эфир отправляет 32 байта,ибо radio.setPayloadSize(32)
Я не знаю,в библиотеке по умолчанию какой режим, фиксированный размер или динамический. Возможно нужно явно указать динамический,либо фиксировать его,но тогда нужно radio.setPayloadSize(1)
 
  • Лойс +1
Реакции: Геннадий П