Как автоматически сбросить nrf24l01+ с кодом?

У меня есть два отдельных nrf24l01+, подключенных к двум разным Arduino UNOS, один как TX, а другой как RX. Проблема в том, что через некоторое время связь между ними прекращается.

На экране Arduino COM я заметил следующие вещи:

Сторона TX: полностью заморожена (передача прекращается).
Сторона RX: непрерывно получает последние данные повторно.

Проблема временно решается при перезапуске TX MCU (следовательно, nrf).Иногда даже после перезапуска TX MCU RX перестает отвечать, и мне приходится перезапускать RX. Поэтому я пытаюсь найти способ автоматического сброса моих nrfs с помощью программного обеспечения, когда возникает такая ситуация.

, 👍1

Обсуждение

Что подключено на pin9 и pin10 ?, @Jensen


3 ответа


Лучший ответ:

2

Я обнаружил, что проблема возникает из-за того, что передатчик ожидает подтверждения от приемника, который каким-то образом теряется, в то время как передача и передатчик все еще ждут ack для последних переданных данных (которые он никогда не получает), поэтому он продолжает передавать последний пакет снова и снова. Я видел на форумах, что это из-за того, что буфер TX заполняется после 3 попыток или что-то в этом роде. Я точно не знаю, почему это происходит.

Сначала я попытался сбросить только передатчик с помощью кода, но этого было недостаточно (как уже упоминалось в вопросе). Поэтому теперь я сбрасываю как TX, так и RX, используя приведенный ниже код. У меня есть отдельный счетчик сброса 1 байта в первом байте массива (вы можете использовать однобайтовую переменную), который действует как идентификатор пакета (вы также можете использовать внутренний PID).

Приведенный ниже код сбрасывает TX при сбое передачи, проверяя возвращаемое значение функции записи, и сбрасывает RX, когда он получает один и тот же ack или пакет (с одним и тем же значением счетчика сброса) более 2 раз (я использую условие, чтобы проверить, отличается ли последнее значение счетчика от текущего или нет). Чтобы сбросить его с помощью кода, я использую следующий алгоритм :

  1. Выключите питание NRF с помощью функции PowerDown ().
  2. Повторно инициализируйте nrf для MCU.
  3. Включите питание NRF с помощью функции PowerUp ().

Примечание: я использую библиотеку TMRH20 RF24.

TX Код

void radio1_init()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  myRadio1.begin();
  delay(100);
  myRadio1.setChannel(96);
  myRadio1.setPALevel(POWERLEVEL);
  myRadio1.setDataRate(DATARATE);
  myRadio1.setAutoAck(1);
  myRadio1.enableAckPayload();
  myRadio1.enableDynamicPayloads();
  myRadio1.setRetries(2, 10);
  myRadio1.setCRCLength(RF24_CRC_8);
  myRadio1.openWritingPipe( addresses1[0]);
}

void loop()
{
  dataTransmitted[0]++;
  if ( myRadio1.write( &dataTransmitted, sizeof(dataTransmitted)))
  {

    if (myRadio1.isAckPayloadAvailable())
    {
      myRadio1.read(&ack, sizeof(ack));
    }
  }
  else
  {
    myRadio1.powerDown();
    \\Serial.println(" 1 Tx1 problem end");
    radio1_init();
    myRadio1.powerUp();
  }
}

RX Код

void radio2_init()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  myRadio2.begin();
  delay(100);
  myRadio2.setChannel(96);
  myRadio2.setPALevel(POWERLEVEL);
  myRadio2.setDataRate(DATARATE);
  myRadio2.setAutoAck(1);
  myRadio2.enableAckPayload();
  myRadio2.enableDynamicPayloads();
  myRadio2.setRetries(10, 10);
  myRadio2.setCRCLength(RF24_CRC_8);
  myRadio2.openReadingPipe(1, addresses2[0]);
  myRadio2.startListening();
}

void loop()
{
      if (myRadio2.available())
      {
        myRadio2.read( &dataReceived, sizeof(dataReceived));
        myRadio2.writeAckPayload(1, &ack2, sizeof(ack2));
        if (prevack2 == dataReceived[0])
        {
          \\Serial.println("RX 2 problem");
          c2++;
        }
        prevack2 = dataReceived[0];
        if (c2 > 2)
        {
          myRadio2.powerDown();
          radio2_init();
          myRadio2.powerUp();
          c2 = 0;
        }
      }
}
,

1

Если вы используете стандартные контактные кабели arduino, то они не обеспечивают стабильного подключения для NRF24L01+. Попробуйте вместо этого припаять штифты (не шучу).

Другая причина может заключаться в том, что один из ваших модулей имеет плохой источник питания. Включите его с помощью идеального 3,3 вольта (от другого источника питания, а не от Arduino) или используйте "базовый модуль" для NRF24L01+ (подключите этот "базовый модуль" к контакту 5V на Arduino). http://www.yourduino.com/sunshop/index.php?l=product_detail&p=467

,

1

Если NRF24L01 действительно блокируется, как это может произойти при недостаточном источнике питания, то метод PowerDown(), init(), PowerUp() не будет работать, так как NRF не будет получать команды SPI. В этой ситуации, которая, по-видимому, является наиболее распространенной формой блокировки, физический цикл питания является единственным вариантом.

,