Вопросы по NRF24L01

Геннадий П

★★★★★★✩
14 Апр 2021
1,950
621
44
@te238s, Кстати да, упустил это.

На сколько понял, это максимальный размер передаваемого блока и в данном случае не влияет на передачу.
 
  • Лойс +1
Реакции: te238s

te238s

★★✩✩✩✩✩
14 Ноя 2021
374
95
@Геннадий П,я в своё время ВЕСЬ даташит распечатал и на работе в свободное время каждый регистр и команду чуть ли не побитно сравнивал с библиотечными файлами,вникал в логику работы и головы разработчиков этой железки. Спустя неделю психанул,распаял всё,спаял обратно...и заработало🤣
Так что тут способ стандартный: брать классический скетч сканера. А далее уже вникать и под себя настраивать. В общем,Вы и сами знаете.
Там ведь логика такова:
Читается весь пакет из буфера и сбрасываются флаги приёма пакета. Возможно они и не сбрасываются,раз чтение неполное,соответственно последующие пакеты просто не принимаются,т.к буфер заполнен.

это максимальный размер передаваемого блока
В режиме динамического размера эта команда игнорируется,т.е. сколько в буфер запишет мк,столько нрф и отправит.
В режиме фиксированного размера эта команда ПайлоадСайз указывает размер который будет передаваться,независимо от количества записаных байт в буфер.
А вот со стороны приёмника хз,не проверял. Но мне кажется там "не засчитывается" не полное чтение буфера,соответственно буфер не сбрасывается.
Максимальный размер аппаратного буфера 32 байта. Буфера 3 шт.
 

Sasauge

✩✩✩✩✩✩✩
3 Июн 2023
8
0
что-то получилось ! я поменял передатчик с уно на нано, припаял конденсатор 10мкф на нрф только на передатчике , запитал передатчик 5в и самое главное продублировал строку отправки. оно заработало , но не разобрался как еще
 

Sasauge

✩✩✩✩✩✩✩
3 Июн 2023
8
0
вопрос решён , теперь у меня 2 ардуино нано , каждая с питанием от 2 банок 18650, на каждой по конденсатору 10мкф, дублировать строку отправки оказалось не надо
 

Дмитрий Ш

✩✩✩✩✩✩✩
20 Июн 2023
1
1
Тоже два дня мучаюсь с проблемой странного приёма. Вроде как все сообщения уходят благополучно, но приёмник принимает только если на большой частоте отправка идёт. И то как-то с грехом пополам, как-то случайно выхватывая данные. Решил проблему, отсылая сдвоенным импульсом одну и ту же переменную, без задержки, тупо в цикле for. Приёмник почему-то вторую (как и остальные из цепочки отправки, хотя принимает на одну отправку меньше чем указано в for, просто каждый раз принимает одно и то же первое число, даже если отправлять разные) отправку игнорирует, но первую принимает хорошо, с любой задержкой между отправками..

TX:
void loop() {
  for(int i = 0; i < 2; i ++) {
    radio.write(&counter, sizeof(counter));
    Serial.println(counter + i);
  }
  counter++;
  delay(2000);
}
RX:
void loop() {
  byte gotByte;
  if (radio.available()) {
    radio.read(&gotByte, sizeof(gotByte));  // чиатем входящий сигнал
    Serial.print("Recieved: "); //Serial.print(count); Serial.print(" ");
    Serial.println(gotByte);
  }
}
Далее хочу попробовать воспользоваться советом выше, с удалением библиотеки Гайвера и заменой на ту, которая есть в теме.
 
  • Лойс +1
Реакции: voso;

voso;

✩✩✩✩✩✩✩
16 Апр 2023
1
0
Подскажите на какую рабочую библиотек в этой теме ссылаетесь?
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
586
141
насколько я знаю, библиотека Servo не поддерживает другие пины для серво кроме D9 и D10 на плате Nano
Вы немного заблуждаетесь. Библиотека servo.h поддерживает до 12 сервоприводов. А вот при использовании вышеуказанной библиотеки пропадает возможность формирования ШИМ сигнала на пинах D9, D10.
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,707
474
radio.read(received_data, sizeof(received_data));
Для функции radio.read() первым аргументом должен быть адрес массива received_data, а не сам массив.
Т.е. правильно будет так: radio.read(&received_data, sizeof(received_data));

P.S. На форуме любой код нужно вставлять соответствующим тегом. Иначе мало кому вообще захочется такое смотреть.
 
Изменено:

Forgetweb

★✩✩✩✩✩✩
8 Май 2022
61
20
Массив и указатель на него почти одно и то же. Разница только в том, что к массиву применима функция sizeof и она вернет размер массива. Ну а sizeof указателя вернет размер указателя. В остальном разницы нет.
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,707
474
Массив и указатель на него почти одно и то же.
Ключевое слово "почти". Я не собираюсь спорить и обсуждать здесь все нюансы. Если интересно - откройте любой учебник по языку Си или С++.
 
Изменено:
  • Лойс +1
Реакции: Геннадий П

poty

★★★★★★✩
19 Фев 2020
3,167
926
В последней версии библиотеки RF24.h описано следующее:
void openReadingPipe(uint8_t number, const uint8_t* address);
Это явно не то, что применяете Вы:
radio.openReadingPipe(1,address[0]);
Аналогично по записи:
void openWritingPipe(const uint8_t* address);
radio.openWritingPipe(address[0]);
Строку:
radio.write(&transmit_data, sizeof(transmit_data));
нужно записать как
radio.write(transmit_data, sizeof(transmit_data));
Поскольку transmit_data уже является указателем.
 
Изменено:

Forgetweb

★✩✩✩✩✩✩
8 Май 2022
61
20
@PiratFox, мне это ни к чему. Я на Си 20 лет пишу. Хочется проверить - вперед, смотрите листинг с просто именем массива и взятием от него указателя. Попробуйте найти разницу.
 
  • Лойс +1
Реакции: bort707

Bogdan.L

✩✩✩✩✩✩✩
20 Июн 2023
6
1
Здравствуйте, сделал управление на 4-ех кнопках, использовал нрф24 и ардуино. Производил тесты подключив к выходам 4 светодиода на другой ардуине, думая что если загорается значит там есть около 5 вольт, но как оказалось там очень странные значения напряжений от 1.6В до 2.6В и его не хватает для управления нагрузкой.
Вопрос, как это решить и из-за чего происходит? (так же хотел спросить что нужно добавить в код, чтобы когда передатчик с приемником теряет связь, приемник не "застревал" в последнем положении какой-нибудь из управляющих кнопок, а просто выдавал 0 на выходах)
Передатчик:
//передатчик
#include <SPI.h>
#include <RF24.h>
RF24 radio(9, 10); // порты D9, D10: CSN CE
const uint32_t pipe = 111156789; // адрес рабочей трубы;

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

byte butt1=3;
byte butt2=4;
byte butt3=5;
byte butt4=6;
byte transmit_data[4];

void setup() {
  Serial.begin(115200);
  Serial.println("TransmitterTester ON");

  radio.begin();                // инициализация
  delay(2000);
  radio.setDataRate(RF24_1MBPS); // скорость обмена данными RF24_1MBPS или RF24_2MBPS
  radio.setCRCLength(RF24_CRC_8); // размер контрольной суммы 8 bit или 16 bit
  radio.setPALevel(RF24_PA_MAX); // уровень питания усилителя RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
  radio.setChannel(0x6f);         // установка канала
  radio.setAutoAck(false);       // автоответ
  radio.powerUp();               // включение или пониженное потребление powerDown - powerUp
  radio.stopListening();  //радиоэфир не слушаем, только передача
  radio.openWritingPipe(pipe);   // открыть трубу на отправку

  pinMode(butt1, INPUT_PULLUP);
  pinMode(butt2, INPUT_PULLUP);
  pinMode(butt3, INPUT_PULLUP);
  pinMode(butt4, INPUT_PULLUP);

}

void loop() {
 
transmit_data[0]= !digitalRead(butt1);
transmit_data[1]= !digitalRead(butt2);
transmit_data[2]= !digitalRead(butt3);
transmit_data[3]= !digitalRead(butt4); 
   radio.write(&transmit_data, sizeof(transmit_data));

  }
Приемник:
// приемник
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(9, 10); // порты D9, D10: CSN CE

const uint32_t pipe = 111156789; // адрес рабочей трубы;



byte received_data[4];
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"};
byte led1 = 3;
byte led2 = 4;
byte led3 = 5;
byte led4 = 6;

void setup() {
  Serial.begin(9600);
  Serial.println("ReceiverTester ON");

  radio.begin();  // инициализация
  delay(2000);
  radio.setDataRate(RF24_1MBPS); // скорость обмена данными RF24_1MBPS или RF24_2MBPS
  radio.setCRCLength(RF24_CRC_8); // размер контрольной суммы 8 bit или 16 bit
  radio.setChannel(0x6f);         // установка канала
  radio.setAutoAck(false);       // автоответ
  radio.openReadingPipe(1, pipe); // открыть трубу на приём
  radio.startListening();        // приём
  digitalWrite(led1, OUTPUT);
  digitalWrite(led2, OUTPUT);
  digitalWrite(led3, OUTPUT);
  digitalWrite(led4, OUTPUT);
}

void loop() {
  byte pipeNo;
  while ( radio.available(&pipeNo)) {
  radio.read(&received_data, sizeof(received_data));
  }
 digitalWrite(led1, received_data[0]);
  digitalWrite(led2, received_data[1]);
   digitalWrite(led3, received_data[2]);
    digitalWrite(led4, received_data[3]);
}
 

poty

★★★★★★✩
19 Фев 2020
3,167
926
подключив к выходам 4 светодиода
светодиоды в таком случае подключаются к выводам Ардуино через сопротивления.
не хватает для управления нагрузкой.
выводы Ардуино имеют ограничения на ток, который они могут обеспечить и это, в целом 20-40мА, при этом суммарный ток, потребляемый всей микросхемой не должен превышать 100мА. Для управления более мощными нагрузками необходимо использовать драйверы или делать управление на транзисторах.
 

Bogdan.L

✩✩✩✩✩✩✩
20 Июн 2023
6
1
@poty,Так это понятно что я через резисторы светодиоды подключил, я когда подключаю вместо светодиодов модуль мосфетов, он не работает. один мосфет потребляет в открытом состоянии 12-14 мА
 

poty

★★★★★★✩
19 Фев 2020
3,167
926
@Bogdan.L,
я через резисторы светодиоды подключил
схему - в студию. Где мерили напряжение:
?
один мосфет потребляет в открытом состоянии 12-14 мА
MOSFET не может ничего потреблять со стороны управляющего электрода. Даже если Вы его включили вместо светодиодов (оставив сопротивление), то на него должно идти максимальное напряжение на выводе Ардуино (с оговоркой, что не используется высокая частота переключения, что вряд ли имеет место быть). То, что MOSFET не открывается - означает только то, что он выбран неверно. Опять же имеет смысл говорить только при наличии схемы.
 

VictorArx

★★✩✩✩✩✩
22 Мар 2021
513
83
@Bogdan.L, сам измерительный прибор не врёт? Такое тоже случается. Проверь тестом саму arduino в иде, сколько на выходе вольт. Какие номиналы резисторов для светодиодов? Как сказали выше схему в студию. В передатчике делей не большой?
 

Максим_Л

✩✩✩✩✩✩✩
12 Июл 2023
1
0
@viktor1703, Ага, понял, спасибо за уточнение

@PiratFox, @PiratFox, По-поводу radio.read - спасибо, исправил. Но проблема, к сожалению, осталась. По-поводу того, как нормально нужно вставлять код - также спасибо. Первый раз сижу на таких форумах, буду знать.

@poty, Спасибо, исправил. Но, если это должно было решить проблему, - оно её не решило. На всякий случай, коды исправил в самом вопросе (в начале обсуждения), в соответствии с Вашими замечаниями.
 

poty

★★★★★★✩
19 Фев 2020
3,167
926

@Максим_Л, а что исправлено? Поставлен пробел? В прототипе функций в первых двух случаях используется указатель на строку идентификатора, а Вы запихиваете туда значение из массива.
Вот например, описание метода создания соединения со стороны приёмника:
C++:
    /**
     * Создание соединения для чтения данных
     *
     * Одновременно может быт ьоткрыто до 6 соединений для чтения.  После открытия всех необходимых соединений
     * для чтения вызовите startListening().
     *
     * @see
     * - openWritingPipe()
     * - setAddressWidth()
     *
     * @note Соединения 0 и 1 будут использовать полный адрес длиной 5 байт. Соединения 2-5 будут использовать
     * только первый байт адреса, применяя для остальных 4 байт значения соединения 1
     * Адреса соединений 1-5 могут отличаться только первым байтом.
     * Только первый байт в массиве адресов может быть уникальным, например
     * @code
     * uint8_t addresses[][6] = {"Prime", "2Node", "3xxxx", "4xxxx"};
     * openReadingPipe(0, addresses[0]); // используется "Prime"
     * openReadingPipe(1, addresses[1]); // используется "2Node"
     * openReadingPipe(2, addresses[2]); // используется "3Node"
     * openReadingPipe(3, addresses[3]); // используется "4Node"
     * @endcode
     *
     * @warning
     * @parblock
     * If the reading pipe 0 is opened by this function, the address
     * passed to this function (for pipe 0) will be restored at every call to
     * startListening().
     *
     * Read
     * http://maniacalbits.blogspot.com/2013/04/rf24-addressing-nrf24l01-radios-require.html
     * to understand how to avoid using malformed addresses. This address
     * restoration is implemented because of the underlying necessary
     * functionality of openWritingPipe().
     * @endparblock
     *
     * @param number Какое соединение открыть. Можно открыть только соединения с номерами 0-5,
     * все адреса, присвоенные соединениям за пределами этих номеров будут проигнорированы.
     * @param address 24, 32 или 40 бит адрес открываемого соединения.
     *
     * Параметр длины адреса опущен, поскольку будет использоваться только то количество байт
     * (для соединений 0 и 1) которое установлено методом setAddressWidth().
     */
    void openReadingPipe(uint8_t number, const uint8_t* address);
Вот метод, позволяющий изменить размер адреса:
C++:
    /**
     * Устанавливает размер адреса от 3 до 5 байт (24, 32 или 40 бит)
     *
     * @param a_width Размер адреса в байтах; может принимать значение 3, 4 или
     * 5.
     */
    void setAddressWidth(uint8_t a_width);
Сравним с Вашим размером адреса:

uint64_t address[]

64 бит!

Т.о., нужно:
1. Привести длину адреса к 5 байтам (длине по умолчанию).
2. Передавать в качестве параметра не значение адреса, а адрес его первого байта.
 
Изменено:
  • Лойс +1
Реакции: te238s и PiratFox

te238s

★★✩✩✩✩✩
14 Ноя 2021
374
95
Автоподтверждение приёма не работает на 250 kbps. Либо 1 или 2 mbps, либо без автоподтверждения.
Зачем radio.setRetries(0, 15); ? Так уверены в качестве связи? Поставьте хотя бы 5 попыток.
И почему radio.setPayloadSize(32) ? У Вас 1 байт только передать.
Ещё раз напомню: вдумывайтесь в то,что кодите. Не надо слепо копировать.
 
  • Лойс +1
Реакции: poty и PiratFox

te238s

★★✩✩✩✩✩
14 Ноя 2021
374
95
Наверно,запамятовал)
Я уже где-то писал о своём опыте. Когда так же не завелась связь по чужому коду. Начал с малого и далее:
1. Проверил связь МК и нрф приемника и передатчика
2. На гайверовском скетче "сканер" проверил приём
3. Проверил сканером передатчик в режиме несущей.
4. И ещё 33 пункта)))
 

Bogdan.L

✩✩✩✩✩✩✩
20 Июн 2023
6
1
@VictorArx, в передатчике делей в сетапе и по сути не должен влиять на что либо. измерительный прибор мультиметр rm101. номиналы резисторов 200 Ом. Измерения проводил относительно пина Д3 и земли.
Подключил выходы к такому модулю и меряю относительно контактов SIG подключенных к нему д3 и GND когда нажимаю на кнопку на мультиметре показывает 1 вольт


1689422214199.png
 

poty

★★★★★★✩
19 Фев 2020
3,167
926
На модуле сопротивления на входе оптронов стоят?
 

Bogdan.L

✩✩✩✩✩✩✩
20 Июн 2023
6
1
@poty, естественно! я когда заливаю другой скетч, мигалку например то оно работает прекрасно! Светодиод на плате мосфета светит, нагрузку коммутирует.