Как автоматически сбросить модуль NRF24L01

Для моего проекта домашней автоматизации я использую несколько arduino nano с каждым модулем NRF24L01 +. Каждый модуль способен как принимать, так и передавать данные друг другу. В течение пары часов все казалось безупречным, но через пару часов он либо прекращает передачу (полностью замораживается), либо повторно получает последние данные. В моем проекте я использую библиотеки RF24 и RF24Network, мне было интересно, удалось ли кому-нибудь автоматически сбросить модуль NRF24L01 с помощью кода, когда произошла одна из этих ошибок, и мог бы поделиться своим кодом?

Я уже нашел эту форму, но здесь используется только стандартная библиотека RF24, в то время как я также использую библиотеку RF24Network. Кроме того, в этой форме он имеет отдельную сторону TX и RX, в то время как мне хотелось бы, чтобы каждый модуль мог как отправлять, так и получать.

Некоторая дополнительная дополнительная информация: я использую стабильный источник питания с конденсатором, подключенным к модулю, также провода припаяны к модулю.

Я надеюсь, что кто-нибудь сможет мне в этом помочь,

Гвидо

, 👍1

Обсуждение

Вы уверены, что проблема не в Nano? Возможно, было бы лучше сбросить Nano. Сброс Nano также приведет к повторной инициализации NRF24., @Gerben

@Gerben Это известная проблема, и она особенно распространена у китайских клонов. У одного make даже весь бит ACK перевернут ... такое качество..., @Majenko


3 ответа


4

Это известная проблема с этими чипами (особенно с китайскими клонами). Это происходит, когда чип застревает в режиме передачи данных в ожидании подтверждения, которое никогда не возвращается.

Микросхемы не имеют "сброса", но переключение их в режим низкого энергопотребления, а затем снова включение, что не влияет на какие-либо настройки регистра, прерывает текущую операцию передачи данных.

RF24Network - это просто уровень протокола поверх библиотеки RF24. Эта библиотека RF24 имеет методы PowerDown() и PowerUp(). Просто вызовите PowerDown с последующим включением питания для вашего объекта драйвера RF24.

,

Я попробовал ваше предложение. Однако у меня это не получилось. Я действительно использую эти так называемые китайские клоны. Я дал объяснение моего кода, используемого в следующем ответе. Я надеюсь, что вы могли бы дать мне несколько полезных советов по его улучшению., @Guido


0

@Majenko спасибо за ваше предложение, я немного поиграл с функциями PowerDown () и PowerUp(), но, к сожалению, у меня это еще не заработало. Опять же, казалось, что это сработало в течение пары часов, а затем снова, похоже, застряло. Поэтому я также включил свой код, чтобы посмотреть, не допустил ли я каких-нибудь серьезных ошибок. Более того, я предполагаю, что у меня есть такие китайские клоны NRF24L01 +, которые я купил на Aliexpress.

Я включил несколько частей своего кода, следующая часть сбрасывает модуль NRF24L01 + при обнаружении сбоя. Здесь я также включил предлагаемые функции PowerDown и PowerUp.

void NetworkReconnect()
{
  pinMode(CE_PIN, OUTPUT); digitalWrite(CE_PIN, HIGH);
  pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH);

  radio.powerDown();

  radio.begin();

  radio.powerDown();

  Network.begin(90, thisNode);

  delay(100);

  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_1MBPS);

  radio.powerUp();
}

Следующий код у меня есть в моем void.loop(), каждые 5 секунд я проверяю сетевое соединение, вызывая NetworkCheckConnection() (см. Последнюю часть включенного кода). Который пытается выяснить, произошел ли сбой модуля, я нашел это обнаружение сбоя в качестве предложения в форме обсуждения библиотеки RF24 в обсуждении на GitHub. Кроме того, цикл while ограничен только 500 мс, чтобы избежать бесконечного цикла, если это значение превышено, функция NetworkReconnect() вызывается снова.

void loop() 
{

  Network.update();

  if (millis() - Timer > 5000)
  {
    NetworkCheckConnection();
    Timer = millis();
  }

  if(radio.failureDetected){
    radio.failureDetected = false;
    delay(250);
    Serial.println("Обнаружен сбой радиосвязи, перезапуск радиосвязи");
    NetworkReconnect();        
  }

  if (Network.available())
  {
    uint32_t failTimer = millis();
    while (Network.available())
    {
      if(millis() - failTimer > 500)
      {
        radio.failureDetected = true;
        Serial.println("Обнаружен сбой радиосвязи");
        break;
      }

      ... Обычная сеть.почитай всякую всячину...

    }   
  }

  ... Оставшаяся часть кода ...

}

И, наконец, код NetworkCheckConnection(), этот код основан на примере обработки сбоев RF24 и принципах, используемых для проверки подключения сетевого канала RF24Mesh (см. Строку 140).

void NetworkCheckConnection()
{
  if (radio.getDataRate() != RF24_1MBPS)
  {
    radio.failureDetected = true;
    Serial.println("CheckConnection FailureDetected");
    return;
  }
  // см. строку 140 из: https://github.com/nRF24/RF24Mesh/blob/master/RF24Mesh.cpp
  bool ok = 0;
  if(radio.rxFifoFull() || (Network.networkFlags & 1))
  {
    return;
  }
  RF24NetworkHeader header(otherNode, NETWORK_PING);
  ok = Network.write(header,0,0);
  if(ok) { Serial.println("Network Connected");       return;}
  if(!ok){ radio.stopListening(); NetworkReconnect(); return;}
}

Наконец, я также вызываю функцию NetworkReconnect(), если какая-либо из моих функций Network.write завершается с ошибкой.

Я надеюсь, что вы можете дать мне несколько советов о том, как заставить этот модуль работать более надежно, любое предложение приветствуется!

Заранее спасибо :)

,

Если вы столкнетесь с отказом радиосвязи, что вы получите в качестве выходных данных printDetails ()?, @Avamander


2

Та же проблема; Простой обходной путь сделал это за меня: (1) подайте питание + 3,3 В на nRF24L01 от цифрового вывода, используя диод прямого смещения / светодиод (с Vf в диапазоне 1,7-2,3 В), чтобы снизить напряжение до соответствующего диапазона (2,7-3,3 В), затем (2) скажем, в настройках переключите вывод на OUT / HIGH

pinMode(NRFPIN, ВЫХОД); digitalWrite (NRFPIN, ВЫСОКИЙ);

Примечания:

А) Если у вас есть устройство 3,3 В, то вы можете пропустить снижение напряжения в (2)

B) потребляемая мощность nRF24L01 достигает максимума при 13 мА (время покоя незначительно), что вполне соответствует спецификации выходного контакта

C) Конечно, вы можете сделать (1) с помощью делителя напряжения или микросхемы преобразователя уровня и т. Д., Но привлекательность светодиода (я проверил Vf на 100 Ом при 5 В, чтобы найти достойное соответствие) заключается в том, что он простой, пассивный и встроенный, а также имеет приятные дополнительные преимущество слабой вспышки при передаче или приеме!

Посмотрите здесь также сброс nRF24L01

,