Ошибка записи NRF24L01

Мой Arduino Uno с комбинацией NRF24L01 выдает сообщения об ошибках при записи.

Используя базовый пример кода «Начало работы», буквально скопированный из: http://tmrh20.github.io/RF24/GettingStarted_8ino-example.html, мой последовательный монитор постоянно пишет "не удалось" (см. прикреплённый скриншот)

Настройка для моего Arduino uno описана в таблице на http://arduino-info.wikispaces.com/Nrf24L01-2.4GH-HowTo#PP (контакт Arduino для Библиотека ТМРх20 РФ24)

Код:

/*
* Пример эскиза для начала работы с радиостанциями nRF24L01+.
* Это очень простой пример того, как отправлять данные с одного узла на другой.
* Обновлено: декабрь 2014 г., автор TMRh20.
*/
#include <SPI.h>
#include "RF24.h"
#include <printf.h>

/****************** Конфигурация пользователя ****************************/
/*** Установить это радио как радио номер 0 или 1 ***/
bool radioNumber = 1;
/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7,8);
/**********************************************************/
byte addresses[][6] = {"1Node","2Node"};
// Используется для управления отправкой или получением этого узла
bool role = 0;
void setup() {
  Serial.begin(115200);
  printf_begin();
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  radio.begin();
  // Установите низкий уровень PA, чтобы предотвратить проблемы, связанные с питанием, поскольку это
 // эскиз get_started и вероятность непосредственной близости устройств. RF24_PA_MAX используется по умолчанию.
  radio.setPALevel(RF24_PA_LOW);

  // Открываем канал записи и чтения на каждом радио с противоположными адресами
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.printDetails();
  // Запускаем радиоприемник, прослушивающий данные
  radio.startListening();
}
void loop() {


/****************** Ping Out Role ***************************/  
if (role == 1)  {

    radio.stopListening();                                    // Во-первых, перестань слушать, чтобы мы могли поговорить.


    Serial.println(F("Now sending"));
    unsigned long start_time = micros();                             // Найдите время и отправьте его. Это будет заблокировано до завершения
     if (!radio.write( &start_time, sizeof(unsigned long) )){
       Serial.println(F("failed"));
     }

    radio.startListening();                                    // Теперь продолжаем слушать

    unsigned long started_waiting_at = micros();               // Устанавливаем период таймаута, получаем текущие микросекунды
    boolean timeout = false;                                   // Настраиваем переменную, чтобы указать, был ли получен ответ или нет

    while ( ! radio.available() ){                             // Пока ничего не получено
      if (micros() - started_waiting_at > 200000 ){            // Если ожидание превышает 200 мс, укажите таймаут и выйдите из цикла while
          timeout = true;
          break;
      }      
    }

    if ( timeout ){                                             // Описываем результаты
        Serial.println(F("Failed, response timed out."));
    }else{
        unsigned long got_time;                                 // Получаем ответ, сравниваем и отправляем на отладку
        radio.read( &got_time, sizeof(unsigned long) );
        unsigned long end_time = micros();

        // Выплеснуть это
        Serial.print(F("Sent "));
        Serial.print(start_time);
        Serial.print(F(", Got response "));
        Serial.print(got_time);
        Serial.print(F(", Round-trip delay "));
        Serial.print(end_time-start_time);
        Serial.println(F(" microseconds"));
    }
    // Повторите попытку через 1 секунду
    delay(1000);
  }
/****************** Pong Back Role ***************************/
  if ( role == 0 )
  {
    unsigned long got_time;

    if( radio.available()){
                                                                    // Переменная для полученной временной метки
      while (radio.available()) {                                   // Пока данные готовы
        radio.read( &got_time, sizeof(unsigned long) );             // Получаем полезную нагрузку
      }

      radio.stopListening();                                        // Во-первых, перестань слушать, чтобы мы могли поговорить
      radio.write( &got_time, sizeof(unsigned long) );              // Отправляем последний обратно.
      radio.startListening();                                       // Теперь возобновляем прослушивание, чтобы перехватить следующие пакеты.
      Serial.print(F("Sent response "));
      Serial.println(got_time);  
   }
 }
/****************** Change Roles via Serial Commands ***************************/
  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ){      
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Стать основным передатчиком (пинговать)

   }else
    if ( c == 'R' && role == 1 ){
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));      
       role = 0;                // Становимся основным получателем (ответ на понг)
       radio.startListening();

    }
  }
} // Петля

Хотя у другого моего Arduino такие же настройки, только у него radioNumber = 0.

Выход монитора: вывод монитора

Моя установка: Настройка Arduino

РЕДАКТИРОВАТЬ: Хорошо, мне удалось запустить printDetails() (спасибо за помощь) Получилось:

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x65646f4e31 0x65646f4e32
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0x65646f4e31
RX_PW_P0-6   = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x03
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW

на arduino one и на следующем на arduino 2 с радиономером = 1

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x65646f4e32 0x65646f4e31
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0x65646f4e32
RX_PW_P0-6   = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x03
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW

, 👍1

Обсуждение

У вас такая же настройка ресивера? На каком расстоянии приемник от вашего передатчика? У НРФ возникнут некоторые проблемы, если им придется сблизиться друг с другом., @Gerben

Та же установка, примерно на расстоянии 2/3 метра. Однако это скорее похоже на проблему передачи, а не приема, потому что это говорит о том, что передача даже не работает, верно?, @Mart

Извините, вы правы. Сообщение о тайм-ауте сбило меня с толку. Похоже, что Arduino не может связаться с NRF. Попробуйте пошевелить все соединения, чтобы убедиться, что они имеют хороший контакт. Попробуйте вызвать функцию [printDetails](https://tmrh20.github.io/RF24/cl assRF24.html#adc95213ed4c8569a90eb33122e16cea6)., @Gerben

хм, с соединением вроде все в порядке... особенно потому, что оба устройства выдают одну и ту же ошибку. (та же установка). У меня небольшая проблема с реализацией printDetails. когда я добавляю строку radio.printDetails(); где-нибудь, я не вижу никакого ответа на своем мониторе?, @Mart

@Mart Сначала вам нужно инициализировать printf, чтобы printDetails работал., @Avamander

Спасибо @Avamander. Я обновил свой первоначальный вопрос выводом printDetails. Я понятия не имею, что может быть не так, @Mart

Глядя на фотографии, я уверен, что эта проблема вызвана слишком слабым источником питания. Попробуйте припаять большой развязывающий конденсатор напрямую к контактам VCC и GND модуля. Если это не улучшит ситуацию, используйте внешний стабилизатор на 3,3 В., @Avamander

Кросс опубликован по адресу: https://github.com/nRF24/RF24/issues/445., @Avamander


1 ответ


1

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

Изменить: чип ожидает CPOL 0, поэтому я использовал понижающий резистор на линии тактовой частоты. Поэтому по умолчанию он будет работать на низком уровне холостого хода.

,

Перепишите свой ответ как реальное решение, если оно таковое. В настоящее время это выглядит скорее как комментарий., @MichaelT

Спасибо, попробую как можно скорее и отпишусь о результате. Вы поместили резистор между выводом sck и землей? (при условии, что этот макет: https://tmrh20.github.io/RF24/), @Mart

Мне не нужно было физически устанавливать резистор, поскольку он есть внутри моего микроконтроллера, но это должно работать нормально. Может быть, 10 тысяч?, @Brandon Braun