NRF не передает редкие пакеты

Condensator
Offline
Зарегистрирован: 02.06.2017

Как только ставлю delay(1000) , NRF перестает работать -  статус виден по светодиодам. Это же подтверждается со  стороны RX.  

IDE версии 1.0.5 r2

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

const uint64_t pipe = 'ABCDEFG';
uint8_t  B_32bytes[32];

// для Mega2560:
RF24 ModuleToTest(49,53); // CE_PIN,SS_PIN

//для Uno другие CE_PIN,SS_PIN:
// RF24 ModuleToTest(8,10); 


// для Mega2560:
#define GR_LED 14     // Tx Ok 
#define RED_LED 16    // Tx fail 


// для UNO другие номера выводов LED:
//#define GR_LED  2
//#define RED_LED 4

void setup(void)
{  
  ModuleToTest.begin();
                          //ModuleToTest.setAutoAck(true);
  ModuleToTest.setAutoAck(false);
  ModuleToTest.setDataRate(RF24_1MBPS);
  ModuleToTest.setCRCLength(RF24_CRC_16);
  ModuleToTest.setChannel(66);
  ModuleToTest.openWritingPipe(pipe);
  //ModuleToTest.printDetails();
  pinMode(RED_LED, OUTPUT);  
  pinMode(GR_LED, OUTPUT);   
} 

void loop(void)
{
  switch(ModuleToTest.write(B_32bytes,32))
     { case false: digitalWrite(GR_LED,HIGH); digitalWrite(RED_LED,LOW); break;
       case true:  digitalWrite(RED_LED,HIGH); digitalWrite(GR_LED,LOW); break;
     }
delay(1000); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

 

Condensator
Offline
Зарегистрирован: 02.06.2017

Может быть delay() задействует те же прерывания и таймеры, что и библиотека для этого устройства?  При delay() < 5 мсек проблема не проявляется.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

??  делей - программавообще останавливается в микрконтроллере, а  нрф шлет инфу.. и куда он шлет, на деревню дедушке?

Condensator
Offline
Зарегистрирован: 02.06.2017

Short Circuit пишет:
??  делей - программа вообще останавливается в микроконтроллере
  Не похоже. По-вашему, в какой точке программы она останавливается?

Short Circuit пишет:
а  нрф шлет инфу.. и куда он шлет, на деревню дедушке?
нрф шлет информацию без пордтверждения получения , специально поставил в примере код

//         ModuleToTest.setAutoAck(true);
     	   ModuleToTest.setAutoAck(false);

Поэтому для демонстрации ошибки не важно наличие-отсутствия приемника. В случае AutoAckn(false) считается, что  доставлено в любом случае (tx_ok). Но если внести задержку между посылками больше чем delay(15), передача прекращается и включается красный LED "tx_fail".

 

 

Tarantino
Offline
Зарегистрирован: 04.06.2017

Condensator пишет:
Как только ставлю delay(1000) , NRF перестает работать -  статус виден по светодиодам. Это же подтверждается со  стороны RX.  

IDE версии 1.0.5 r2

Может нечаянно сотворили импульный блок питания?  Прочтите это:  http://arduino.ru/forum/obshchii/lozhnoe-srabatyvanie-pir-datchika-pri-p...

ЕвгенийП пишет:
Монтажную схему Вы не привели, но думаю, что у Вас проблемы с общей землёй. При включении относительно мощной нагрузки происходит скачок. Почитайте вот эту статью, сравните рисунки 2 и 3 и посмотрите на свой монтаж. Думаю, всё решится.

Condensator
Offline
Зарегистрирован: 02.06.2017

Tarantino пишет:
Может нечаянно сотворили импульный блок питания?  Прочтите это:  http://arduino.ru/forum/obshchii/lozhnoe-srabatyvanie-pir-datchika-pri-podklyuchenii-sim900#comment-287278

Нет осциллографа, чтобы проверить напряжение питания

Condensator
Offline
Зарегистрирован: 02.06.2017

Помогите пожалуйста понять в каком направлении искать причину

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Short Circuit вам указал направлении.

У вашей программы получается "окно" для приёма всего несколько микросекунд, во время проверки в switch. После этого секунду нечего не принимает, пока работает delay.

Копайте в сторону "Мигаем светодиодом без delay()".

Condensator
Offline
Зарегистрирован: 02.06.2017

Nosferatu, я не понимаю, можете объяснить мою ошибку попроще?

Приема (подтверждения ?) в программе не должно быть, так как отключено подтверждение передачи:

 //ModuleToTest.setAutoAck(true);
  ModuleToTest.setAutoAck(false); //  отключил прием  подтверждения 

А если не отключено, то прием подтверждения происходит во время выполнения 

ModuleToTest.write(B_32bytes,32);

и время выполнения write при включенном приеме подтверждения  немного больше, чем без подтверждения.

 

 

Lims
Offline
Зарегистрирован: 07.06.2017

Мое сугубо дилетантсткое предположение, может быть дело в неправильной работе SPI и его сигналов  CE и SS ?

По аналогиии с этим сообщением http://arduino.ru/forum/programmirovanie/s-kakim-obemom-rabotaet-bibliot...

Для Mega2560 стандартный SS=53, CE=не знаю какой. Для UNO см в таблице

 

 

b707
Offline
Зарегистрирован: 26.05.2017

Condensator, вы во внутрь либы RF24 загляните - при каких условия функция RF24.write() возвращает False? может станет понятнее

Condensator
Offline
Зарегистрирован: 02.06.2017

b707 пишет:
Condensator, вы во внутрь либы RF24 загляните - при каких условия функция RF24.write() возвращает False? может станет понятнее

Заглянул, но ясности не прибавилось. https://github.com/maniacbug/RF24/issues . Проблема проявляется не только в том, что функция write возвращает false, но и приемник на второй ардуино перестает принимать пакеты.

RF24:write(const void *buf, uint8_t  len) , на что влияет модификатор const для  void *buf?

код функции RF24:write:

/*
 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

#include "nRF24L01.h"
#include "RF24_config.h"
#include "RF24.h"

/******************************************************************/

bool RF24::write( const void* buf, uint8_t len )
{
  bool result = false;

  // Begin the write
  startWrite(buf,len);

  // ------------
  // At this point we could return from a non-blocking write, and then call
  // the rest after an interrupt

  // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd)
  // or MAX_RT (maximum retries, transmission failed).  Also, we'll timeout in case the radio
  // is flaky and we get neither.

  // IN the end, the send should be blocking.  It comes back in 60ms worst case, or much faster
  // if I tighted up the retry logic.  (Default settings will be 1500us.
  // Monitor the send
  uint8_t observe_tx;
  uint8_t status;
  uint32_t sent_at = millis();
  const uint32_t timeout = 500; //ms to wait for timeout
  do
  {
    status = read_register(OBSERVE_TX,&observe_tx,1);
    IF_SERIAL_DEBUG(Serial.print(observe_tx,HEX));
  }
  while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) && ( millis() - sent_at < timeout ) );

  // The part above is what you could recreate with your own interrupt handler,
  // and then call this when you got an interrupt
  // ------------

  // Call this when you get an interrupt
  // The status tells us three things
  // * The send was successful (TX_DS)
  // * The send failed, too many retries (MAX_RT)
  // * There is an ack packet waiting (RX_DR)
  bool tx_ok, tx_fail;
  whatHappened(tx_ok,tx_fail,ack_payload_available);
  
  //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available);

  result = tx_ok;
  IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed"));

  // Handle the ack packet
  if ( ack_payload_available )
  {
    ack_payload_length = getDynamicPayloadSize();
    IF_SERIAL_DEBUG(Serial.print("[AckPacket]/"));
    IF_SERIAL_DEBUG(Serial.println(ack_payload_length,DEC));
  }

  // Yay, we are done.

  // Power down
  powerDown();

  // Flush buffers (Is this a relic of past experimentation, and not needed anymore??)
  flush_tx();

  return result;
}
/****************************************************************************/

 

b707
Offline
Зарегистрирован: 26.05.2017

Condensator пишет:

Заглянул, но ясности не прибавилось.

тоже заглянул. Во-первых, может IF_SERIAL_DEBUG включить, чтобы увидеть какую-то диагностику? И во-вторых, что-то мне кажется. что то что вы отключили ask-пакеты - либа не отслеживает и все равно ждет ответа. Хотя могу ошибаться, смотрел мельком.

 

sansei4
Offline
Зарегистрирован: 09.01.2015

Ради эксперимента можете добавить ModuleToTest.stopListening(); перед switch() (пишу с телефона, так что лучше могу ошибиться в написании), а если не поможет, то и startListening(...); после

Condensator
Offline
Зарегистрирован: 02.06.2017

sansei4 пишет:
Ради эксперимента можете добавить ModuleToTest.stopListening(); перед switch() (пишу с телефона, так что лучше могу ошибиться в написании), а если не поможет, то и startListening(...); после
 

Но цитата из описания классов библиотеки http://maniacbug.github.io/RF24/classRF24.html противоречит этому совету тк  в тексте программы внутри switch используется write():

Pipe 0 is also used by the writing pipe. So if you open pipe 0 for reading, and then
startListening(), it will overwrite the writing pipe. Ergo, do an openWritingPipe() again before
write().

Перевод: Pipe 0 также используется как pipe для записи. Таким образом, если открываете pipe 0 для чтения, и затем startListening(), это перепишет pipe трубу для write. Следовательно, сделайте openWritingPipe() опять до write().

void loop(void)
{
  switch(ModuleToTest.write(B_32bytes,32))
     { case false: digitalWrite(GR_LED,HIGH); digitalWrite(RED_LED,LOW); break;
       case true:  digitalWrite(RED_LED,HIGH); digitalWrite(GR_LED,LOW); break;
     }
delay(1000); //

 

Condensator
Offline
Зарегистрирован: 02.06.2017

b707 пишет:
тоже заглянул. Во-первых, может IF_SERIAL_DEBUG включить, чтобы увидеть какую-то диагностику? И во-вторых, что-то мне кажется. что то что вы отключили ask-пакеты - либа не отслеживает и все равно ждет ответа. Хотя могу ошибаться, смотрел мельком.

Я отключил подтверждение setAutoAck(false) (стр. 27,28 программы в сообщении 1) только в версии опубликованной на форуме, чтобы можно было тестировать программу одной картой NRF. 

Если включить подтверждение при помощи setAutoAck(true), то понадобится вторая NRF в качестве приемника, но при этом возникает такая же ошибка и ее синхронно видно как со стороны TX,  так и со стороны  RX.

SERIAL_DEBUG попробую включить.

sansei4
Offline
Зарегистрирован: 09.01.2015

Не было возможности еще раз просмотреть даташит. И все равно, я бы посоветовал включить прослушку со всеми необходимыми настройками. У меня работает так и с delay и с millis.

Вы пробовали уменьшать/увеличивать значение delay? 

Condensator
Offline
Зарегистрирован: 02.06.2017

sansei4 пишет:
И все равно, я бы посоветовал включить прослушку со всеми необходимыми настройками
те мониторить и выводить статус регистров устройства?

sansei4 пишет:
У меня работает так и с delay и с millis.
У Вас работает программа из поста 1 с задержками более 15-20 мсек?

sansei4 пишет:
Вы пробовали уменьшать/увеличивать значение delay?
Да, уменьшение до нуляили удаление вызова delay().

При увеличении задержки в delay() от 15 и выше наблюдаются проблемы из-за которых и создана тема. Вместо delay() ставил длинные циклы операций с float для задержки и появляется эта же проблема.  

sansei4
Offline
Зарегистрирован: 09.01.2015

Я не запаривался с чтением статусов вообще, только прием пакетов. Мой код отличается наличием listening и задержкой между пакетами в пару секунд. А еще ардуино спит 5 минут, в это время питание радио отключено. Соответсвенно после включения надо инициализировать заново. Может и Вам поможет.

Condensator
Offline
Зарегистрирован: 02.06.2017

sansei4 пишет:
Я не запаривался с чтением статусов вообще, только прием пакетов. Мой код отличается наличием listening и задержкой между пакетами в пару секунд. А еще ардуино спит 5 минут, в это время питание радио отключено. Соответсвенно после включения надо инициализировать заново. Может и Вам поможет.
Возможно проблема в сбросе инициализации NRF