nrf24l01 принимает данные только один раз при включении

AntonHT
Offline
Зарегистрирован: 29.12.2017

Здравствуйте, не судите строго, в ардуино новичек. Есть такая проблема. Имеются две ардуино с модулями nrf24l01, одна передает другой показания температуры с датчика DHT22, проблема заключается в следующем, данные температуры передаются только один раз, при включении приемника, что бы обновить данные приходится нажимать кнопку рестарт на ардуино. Вообще не могу понять в чем проблема. код приемника ниже. Заранее спасибо, не пинайте сильно)))))))))

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);



#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
byte tT;

RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно

byte recieved_data[2]; // массив принятых данных

byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

void setup() {
  Serial.begin(9600); //открываем порт для связи с ПК
  lcd.init();
  lcd.backlight(); 

  radio.begin(); //активировать модуль
  radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)
  radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);     //размер пакета, в байтах

  radio.openReadingPipe(1, address[0]);     //хотим слушать трубу 0
  radio.setChannel(0x60);  //выбираем канал (в котором нет шумов!)

  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS

  radio.powerUp(); //начать работу
  radio.startListening();  //начинаем слушать эфир, мы приёмный модуль
}

void loop() {

  while (radio.available()){ 
    radio.read( &recieved_data, sizeof(recieved_data) );         // читаем входящий сигнал
    tT = recieved_data[0];
    tT = map(tT, 0, 200, -98, 101); // конвертируем данные
    lcd.setCursor(0, 0);
    lcd.print(tT);
    Serial.println(recieved_data[0]);
    lcd.setCursor(0, 1);
    int i;
    i++;
    lcd.print(i); // добавил для проверки работает ли в принципе цикл

  } 
 
}

 

AntonHT
Offline
Зарегистрирован: 29.12.2017

проверял на передатчике значение массива с температурой через серийный монитор, значения меняются при изменении температуры на датчике

AntonHT
Offline
Зарегистрирован: 29.12.2017

Сам разобрался.

Удалил из скетча на приемнике и передатчике строку

  radio.enableAckPayload();

и все за работало

AntonHT
Offline
Зарегистрирован: 29.12.2017

Тему можно закрыть

staseshe
Offline
Зарегистрирован: 28.02.2018

Добрый день! Нужна помощь. У меня похожая проблема, данные принимаются и отображаются на экране, но  когда выключаю передатчик, приемник продолжает отображать последнее значение температуры. Скетчи брал за основу с https://github.com/liamjack/Arduino-NRF24L01-Thermometer, но переделал для led индикатора. Буду использовать в качестве термостата, поэтому и необходимо в случае ошибки с приемом данных "бить тревогу". Подскажите как исправить

Вот мои старания:

#include <EEPROM.h>
//#include <MsTimer2.h>
//#include <Led4Digits.h>
// Radio
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

#include <avr/sleep.h>
#include <avr/wdt.h>

// -- Global variables --
//#define OUT 5 // выход для Buzzer

//byte pos;
float tempOUT = 15;
float errorT = -55;
int buttonPlus=A0;
int buzerPin = 5;

// int analog=0;


RF24 radio(9,10);

void setupRadio()
{
 // Initiate the radio
 radio.begin();
 radio.setAutoAck(1);
 // Define the number of retries sending a packet
 radio.setRetries(15,15);
 
 // Define the radio's broadcast channel (0 - 127)
 // Must be the same on the sensor and the master node
 radio.setChannel(17);
 
 // Define the radio's bitrate (using cards lowest bitrate)
 radio.setDataRate(RF24_250KBPS);
 
 // Define the radio's power amplifier level (RF24_PA_MIN for debugging, RF24_PA_HIGH for longest range)
 radio.setPALevel(RF24_PA_HIGH);
 
 // Enable dynamic payloads for packets
 radio.enableDynamicPayloads();
 
 // Open reading pipe
 radio.openReadingPipe(1, 0xE8E8F0F0E1LL);
 
 // Start listening for packets
 radio.startListening();
}
int packetCounter = 0;
int anodPins[] = {2, 3, 4}; // Задаем пины для кажого разряда
int segmentsPins[] = {7, 6, 8, 15, 16, 17, 18, 19}; //Задаем пины для каждого сегмента (из 7 + 1(точка))

int pinIn = A0;

void setup() {
  for (int i = 0; i < 3; i++) pinMode(anodPins[i], OUTPUT);
  for (int i = 0; i < 8; i++) pinMode(segmentsPins[i], OUTPUT);
  pinMode(pinIn, INPUT);
  pinMode(buzerPin, OUTPUT);
  wdt_disable();
  delay(8000);
  wdt_enable(WDTO_8S);   //пробуждение каждые 8 сек
  

 // MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс 
 // MsTimer2::start();              // разрешаем прерывание по таймеру
 
  // Initiate serial connection
  Serial.begin(57600);
  
  // RF Radio setup
  setupRadio();

}

//{A, B, C, D, E, F, G,DP}
int seg[12][8] = {
  {1, 1, 1, 1, 1, 1, 0, 0}, //Цифра 0
  {0, 1, 1, 0, 0, 0, 0, 0}, //Цифра 1
  {1, 1, 0, 1, 1, 0, 1, 0}, //Цифра 2
  {1, 1, 1, 1, 0, 0, 1, 0}, //Цифра 3
  {0, 1, 1, 0, 0, 1, 1, 0}, //Цифра 4
  {1, 0, 1, 1, 0, 1, 1, 0}, //Цифра 5
  {1, 0, 1, 1, 1, 1, 1, 0}, //Цифра 6
  {1, 1, 1, 0, 0, 0, 0, 0}, //Цифра 7
  {1, 1, 1, 1, 1, 1, 1, 0}, //Цифра 8
  {1, 1, 1, 1, 0, 1, 1, 0}, //Цифра 9
  {0, 0, 0, 0, 0, 0, 1, 0}, //Знак -
  {0, 0, 0, 0, 0, 0, 0, 0}  //Пустой разряд
};

int err[3][8] = {
  //{0, 0, 0, 0, 0, 0, 0, 0}, //Пусто
  {1, 0, 0, 1, 1, 1, 1, 0}, //E
  {0, 0, 0, 0, 1, 0, 1, 0}, //r
  {0, 0, 0, 0, 1, 0, 1, 0}  //r
};

static int arr[3][8]; // Переменная-массив для хранения данных, которые не нужно каждый раз пересчитывать

float value=0.0;
int counter = -1;
//int numindex = 0;
void loop() 

{
 counter += 1;
if ((counter % 100) == 0) { // Пауза между сменами 100 мс
    counter = 0;
    
   {
if(radio.available()) {
        float temperature = 0;
           // Read the packet received into the temperature variable
   
   if(!radio.available()) {
                  // Read the packet received into the temperature variable
   float errorT = 0;
   errorT = -55;
   getDigits(errorT);
  Serial.println("ACK not received by client.");  
      
     }
   
   
   
  if(!radio.read(&temperature, sizeof(float)))   {
      // The sensor did not receive the ACK packet
  // tone(5, 3000,1000);  
 errorT = -55;
   getDigits(errorT);
  Serial.println("ACK not received by client.");  
        
     }
  else  value = temperature;
   getDigits(value);
   Serial.println(temperature);  
      if(tempOUT>temperature) tone(5, 3000,1000);
            
      else digitalWrite(5, LOW);
    }
   
   
 //    if(analog>690&&analog<700)//здесь я сравниваю   

     //значение входящего сигнала не с конкретной цифрой
     //а с определенным диапазоном от 690 до 700   
     //это нужно для того чтобы исключить влияние погрешностей резисторов
 //    {
 //      digitalWrite(9,HIGH);
 //      digitalWrite(10,LOW);
 //    }
 //     if(analog>785&&analog<795)
 //    {
 //      digitalWrite(9,LOW);
 //      digitalWrite(10,HIGH);
 //    }
 //    if(analog>860&&analog<870)
 //    {
 //      digitalWrite(9,HIGH);
 //      digitalWrite(10,HIGH);
 //    }
 //    if(analog<100)
 //    {
 //      digitalWrite(9,LOW);
 //      digitalWrite(10,LOW);
 //    }
   
  
  if (digitalRead(buttonPlus) == LOW) 
  
{ 
    tempOUT-=0.05;
    if (-55 > tempOUT) tempOUT = 0;
    delay(27);
    Serial.println(tempOUT);
    getDigits(tempOUT);
   
  
   // getDigits(ceil(tempOUT));
      }   // Делаем проверку, если вход под номером 9 (buttonPlus) имеет состояние  5 В. Увеличиваем значение переменной яркости на 5 единиц.
else if (analogRead(buttonPlus) < 800) 
 { 
    tempOUT+=0.05;
    if (tempOUT > 125) tempOUT = 0;
    delay(27);
        Serial.println(tempOUT);
      getDigits(tempOUT);
    

//getDigits(ceil(tempOUT));    
    
  }   // Делаем проверк
  
 }
   
  
  displayMessage(arr);

}
}


void getDigits (float value) {
 // Serial.println(value);
//Serial.println(tempOUT);

  // Выдаем ошибку на те значения, которые не можем показать
  if ((value >= 10000) ||
      (value <= -1000)){
      
     // (value > -0.01 && value < 0.001)
    
    for (int i = 0; i < 3; i++) { // Каждый разряд по очереди
      for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
        arr[i][k] = err[i][k];
      }
    }
    return; // Выходим
  }

  int digits = 3; // У нас 4 разряда
  if (value < 0) digits = 2; // Из-за минуса один символ убирается*/

  // Делим число на 2 группы - отдельно целую часть и дробную.
  int intPart = (int)abs(value);
  int intLength = ((String)intPart).length(); // Смотрим, сколько разрядов занимает целая часть

  // На дробную часть у нас остается разрядов: digits-intLength
  int fracPart = (int)((abs(value) - abs(intPart)) * 10); //  *1000 Мы можем показать максимум 3 знака после запятой - 0,000
  int fracDigits = digits - intLength;

  fracPart = (((String)fracPart).substring(0, fracDigits)).toInt();

  // Собираем строку для отображения
  String output = (value < 0) ? "-" : "";
  output += (String)intPart;
   String outputFrac = (digits - intLength < 0) ? "" : ((String)"." + ((String)fracPart).substring(0, digits - intLength));
  //String outputFrac = ((digits - intLength <= 0) || (fracPart == 0)) ? "" : ((String)"." + ((String)fracPart).substring(0, digits - intLength));
  output += (String)outputFrac;

   // Дополняем символы спереди, если цифр слишком мало, например для "-1" делаем "  -1"
  String spaces = "     ";
  digits = 3;
  if (~output.indexOf(".")) digits += 1;
  if (output.length() < digits) output = spaces.substring(0, digits - output.length()) + output;

  // Формирум данные для показа:
  int dig = -1;
  for (int i = 0; i < output.length(); i++) {
    String _char = output.substring(i, i + 1);

    if (_char != ".") dig += 1; // Точка не занимает сегмент - увеличиваем на 1

    int actualdigit = 11; // По умолчанию пустой символ
    if ((_char == "-")) {
      actualdigit = 10;
    }
    else if (_char == " " || _char == ".") {
    }
    else {
      actualdigit = _char.toInt();
    }

    if (_char == ".") {
      arr[dig][7] = 1; // Если нужно - ставим точку
    }
    else  {
      for (int n = 0; n <= 7; n++) {
        arr[dig][n] = seg[actualdigit][n];
      }
    }
  }
}

void displayMessage(int dig[3][8]) {
  for (int i = 0; i < 3; i++) { // Каждый разряд по очереди
    for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
      digitalWrite(segmentsPins[k], ((dig[i][k] == 1) ? LOW : HIGH));
    }
    digitalWrite(anodPins[i], HIGH);
    delay(1);
    digitalWrite(anodPins[i], LOW);
      }
    }

 

vmf
Offline
Зарегистрирован: 30.11.2021

Я на приёмнике, при каждом приёме сбрасываю счётчик. Если счётчик не сбрасывается 10 - 30 мин. включаю ALARM. Но есть другая проблема, Если температура и напряжение ИП стабильны и не меняются длительное время, загорается ALARM. NRF24L01 не воспринимает второй пакет если он такой же как предыдущий. 

Flush_rx не помогает.