Подтверждение получения сообщения от nRF24L01

Jek
Offline
Зарегистрирован: 05.01.2014

Господа, помогите, пожалуйста в решении следующего вопроса.

Есть четыре ардуинки с модулями nRF24L01+ настроенные на одни каналы, кому отправлено сообщение указывается в первом байте отсылаемого пакета и программно ардуинка понимает кому пакет. Периодически ардуинки общаются между собой. Например, первая говорит второй «включи насос», вторая должна принять сообщение и подтвердить получение. Если получение не подтверждено, то первая должна повторно отправить сообщение и так раз пять.

Сейчас это реализовано путем остановки программы и ожидания ответа определенное время, т. е. в это время остальной скетч не выполняется. Хотелось бы, чтобы скетч выполнялся во время ожидания ответа. Как это можно реализовать?

  byte k = 0; 
  while (status_otveta == false && k < 5)
    {
      currentTime = millis();
      if(currentTime >= (time_oprosa + 10000)) // Передачу запроса проводим не чаще раз в 10 секунд
        {
          msg_out[0] = dom;
          msg_out[1] = schitok;
          msg_out[2] = opros;
          radio.stopListening(); 
          radio.write(msg_out, 32);
          //Serial.println("Radio zapros opros doma otpravlen");
          radio.startListening();
          //delay(10);
          time_oprosa = currentTime;
          k++;
        }
      if (radio.available())
        {
          bool done = false;    
          while (!done)
            {
              done = radio.read(msg_in, 32);
              if (msg_in[0] == schitok && msg_in[1] == dom && msg_in[2] == otvet) // Ждем пакет для schitok от dom
                {
                  temp_in_1 = msg_in[3];
                  vlazhnost_in_1 = msg_in[4];
                  auto_temp = msg_in[5];
                  //Serial.println("Polucheno radio ot dom");
                  //Serial.print("Temp v dome ");
                  //Serial.println(temp_in_1);
                  //Serial.print("Vlazhnost v dome-");
                  //Serial.println(vlazhnost_in_1);
                  //Serial.print("Auto_temp-");
                  //Serial.println(auto_temp);
                  status_otveta = true;
                }
              //delay(10);
           }
        }
    }

 

sirik
Offline
Зарегистрирован: 10.11.2012

23 строка лучше писать так:

done = radio.read(&msg_in, sizeof(msg_in));

24 так:

if ((msg_in[0] == schitok) && (msg_in[1] == dom) && (msg_in[2] == otvet))

это как минимум

Jek
Offline
Зарегистрирован: 05.01.2014

По 23-ей понятно, а в чем смысл изменений в 24-ой?

sirik
Offline
Зарегистрирован: 10.11.2012

Нужно отделять отдельные условия и визуально более понятнее.

На счет же самой задачи, сегодня-завтра буду писать свою реализацию подобного процесса, будем думать вместе ;)

зы/ а что должен делать клиент в случае ошибки передачи после 5 попытки?

Jek
Offline
Зарегистрирован: 05.01.2014

sirik пишет:

зы/ а что должен делать клиент в случае ошибки передачи после 5 попытки?

Если ответ не получен, то посылаю пять раз команду на отмену операции(вдруг просто сигнал ответа не проходит), включаю аварийную сигнализацию (светодиод и зуммер) и отправляю смс об ошибке.

Если контроллер на ответственном месте (например отопление или насос в скважине) и я не на даче, то тупо отрубаю линию питания.

Radjah
Offline
Зарегистрирован: 06.08.2014

> вдруг просто сигнал ответа не проходит

Это как вдруг?

nRF24 умеет сам подтверждать получение сообщения. Если write возвращает не true, то посыл никто не услышал за указанное число попытаок отправки.

void setRetries(uint8_t delay, uint8_t count);

void setAutoAck(bool enable);

void setAutoAck( uint8_t pipe, bool enable ) ;

sirik
Offline
Зарегистрирован: 10.11.2012

А через какое время после write мы сможем узнать посылка доставленна или нет? Врядли сразу после команды, сегодня буду тестить.

Radjah
Offline
Зарегистрирован: 06.08.2014
  /**
   * Write to the open writing pipe
   *
   * Be sure to call openWritingPipe() first to set the destination
   * of where to write to.
   *
   * This blocks until the message is successfully acknowledged by
   * the receiver or the timeout/retransmit maxima are reached.  In
   * the current configuration, the max delay here is 60ms.
   *
   * The maximum size of data written is the fixed payload size, see
   * getPayloadSize().  However, you can write less, and the remainder
   * will just be filled with zeroes.
   *
   * @param buf Pointer to the data to be sent
   * @param len Number of bytes to be sent
   * @return True if the payload was delivered successfully false if not
   */
  bool write( const void* buf, uint8_t len );

 

sirik
Offline
Зарегистрирован: 10.11.2012

Просто прекрасно!

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

sirik пишет:

А через какое время после write мы сможем узнать посылка доставленна или нет? Врядли сразу после команды, сегодня буду тестить.

10 ms, проверено на практике

toc
Offline
Зарегистрирован: 09.02.2013

> Если write возвращает не true, то посыл никто не услышал за указанное число попытаок отправки.

или ни одна подтверждающая приём квитанция не получена отправителем основного сообщения!!!

Jek
Offline
Зарегистрирован: 05.01.2014

toc пишет:
> Если write возвращает не true, то посыл никто не услышал за указанное число попытаок отправки. или ни одна подтверждающая приём квитанция не получена отправителем основного сообщения!!!

Именно. Стандартная функция дает один и тот же ответ приема и исчерпания попыток. :( Поэтому она не годится.

Radjah
Offline
Зарегистрирован: 06.08.2014

toc пишет:
> Если write возвращает не true, то посыл никто не услышал за указанное число попытаок отправки. или ни одна подтверждающая приём квитанция не получена отправителем основного сообщения!!!
В любом случае на другом конце хрень, и надо включать тревогу.

Maverik
Offline
Зарегистрирован: 12.09.2012

Если ответ не получен, то посылаю пять раз команду на отмену операции(вдруг просто сигнал ответа не проходит), включаю аварийную сигнализацию (светодиод и зуммер) и отправляю смс об ошибке.

можно просто добавить на ответственный участок еще один GSM-модуль, и , если не проходит передача по через nRF, то отсылать смс-кой на другой модуль. 

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

предлагаю обменяться скальпами скайпами )))

Jek
Offline
Зарегистрирован: 05.01.2014

Maverik пишет:
можно просто добавить на ответственный участок еще один GSM-модуль, и , если не проходит передача по через nRF, то отсылать смс-кой на другой модуль. 

Мне проще с ардуинки в щитке отключить линию питания дома и включить заново. Этим перезагрузятся остальные ардуинки  и можно заново попробывать отправить радио.

За первый год эксплуатации, основная ардуинка пару раз зависала и не реагировала на команды, но потом я нашел способ её перезагрузки с GSM модуля и вопрос снялся. Осталась теоретическая проблема зависания GSM модуля, но за два года он не зависал.

Maverik пишет:

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

предлагаю обменяться скальпами скайпами )))

Т. к. у меня всё в процессе строительства, то многое сделано по временной схеме. Труба от скважины идет по воздуху под наклоном до емкости в доме(правда и потом не больно изменится, просто труба будет под землей). После отключения насоса вся вода из трубы сливается обратно в скважину и замерзать нечему. Насос можно просто включить тумблером на контроллере в доме или включить автоматический режим. Тумблером ни разу за год не воспользовались, всегда в авто режиме. Уровень контроллируется ультразвуковым датчиком и обычным китайским поплавком на всякий случай. Естественно есть труба перелива в канализацию.

Пока не решена одна проблема, это переключение потока воды с емкости в доме на емкость на улице, т. к. нужно два электровентиль на 32-ую трубу(или на три направления), а он даже китайский от 60 баксов...

Скайп.... сто лет не пользовался... почта моя еvрl@рамблер,ру

 

Maverik
Offline
Зарегистрирован: 12.09.2012

За первый год эксплуатации, основная ардуинка пару раз зависала и не реагировала на команды, но потом я нашел способ её перезагрузки с GSM модуля и вопрос снялся.

а watchdag-таймерами не ползьзуетесь ?

. После отключения насоса вся вода из трубы сливается обратно в скважину и замерзать нечему. 

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

Скайп.... сто лет не пользовался... 

мессенджер есть какой-нибуд ь? 

Jek
Offline
Зарегистрирован: 05.01.2014

Maverik пишет:

а watchdag-таймерами не ползьзуетесь ?

Пробовал в самом начале. Не получилось. Надо перепрошивать загрузчики. Хотя... наверно надо заняться...

Maverik пишет:

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

Не, не замерзает. У меня ПНД 32 мм.

Maverik пишет:

мессенджер есть какой-нибуд ь? 

На почту отправь тестовое письмо, скину номер вайбера.