1

Тема: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Всем Добра!
Нужна ваша помощь начинающиму ардуинщику, есть готовая метеостанция, она работает отлично, но не хватает знаний проверки принял ли данные приемник nRF24L01, если нет, то сообщить об этом на экран.
То есть если передатчик выключен (сел аккумулятор) или иные факторы повлиявшие на потерю данных, то на экране хотелось бы видеть сообщение типа "NoSignal".
В данном скетче на экране застывают последние переданные данные.
Скетч прикрепляю только приемника.  Так как передатчика все бонально просто.


#include <SPI.h>                                                                      // Библиотека для работы с шиной SPI
#include "nRF24L01.h"                                                                 // Библиотека радиомодуля
#include "RF24.h"                                                                     // Ещё библиотека радиомодуля
#include <Wire.h>                                                                     // Подключаем библиотеку для работы с I2C-устройствами
#include <LiquidCrystal_I2C.h>                                                        // Подключаем библиотеку для работы с модулем LCD1602_I2C
#include <BMP085.h>

//************************************************************************************************************************************************
// Битовая маска символа
byte temp_cel[8] =
{
  0b00000,
  0b01000,
  0b10100,
  0b01000,
  0b00011,
  0b00010,
  0b00011,
};

byte mmHg[8] =
{
  B00000,
  B00100,
  B00110,
  B00100,
  B00100,
  B01110,
  B01110,
};
//***********************************************************************************************************************************************

BMP085 dps = BMP085();                                                                // Устанавливаем датчик давления
LiquidCrystal_I2C lcd(0x27, 16, 2);                                                   // Устанавливаем дисплей

long Temperature = 0, Pressure = 0;                                                   // Создаем переменные для хранения температуры и давления из BMP185

int inputPin = 2;                                                                     // Инициализируем пин для получения сигнала от пироэлектрического датчика движения
int pirState = HIGH;                                                                  // Начинаем работу программы, предполагая, что движение есть, чтобы небыло задержки включения дисплея.
int PIR = 0;                                                                          // Переменная для чтения состояния пина
unsigned long old_time = 0;                                                           // Предыдущее время
unsigned long current_time = 0;                                                       // Текущие время

float temp0, temp1;                                                                   // Создаем переменные для хранения температуры
float data[2];                                                                        // Создаем колическо ячеек хранения данных

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


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

void setup()
{
  Wire.begin();                                                                       // Включаем работу с I2C-устройствами
  dps.init();                                                                         // Инициализируем датчик давления
  lcd.init();                                                                         // Инициализируем дисплей
  lcd.clear();
  lcd.createChar(1, temp_cel);                                                        // Создаем символ под номером 1 температуры
  lcd.createChar(2, mmHg);                                                            // Создаем символ под номером 2 давление
  radio.begin();                                                                      // Активируем nRF24L01 модуль
  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();                                                                    // Включаем (начинаем) nRF24L01 работу
  radio.startListening();                                                             // Начинаем слушать эфир, мы приёмный модуль
}

void loop()
{
  byte pipeNo;
  while ( radio.available(&pipeNo))                                                     // Слушаем эфир со всех труб
  {
    radio.read( &data, sizeof(data) );                                                    // Чиатем входящий сигнал
  }
  {
    temp0 = data[0];
    temp1 = data[1];
  }
  //Блок работы опроса датчика
  //----------------------------------------------------------------
  current_time = millis();                                                              // Получаем текущие время
  if (old_time == 0 || current_time < old_time || current_time >= (old_time + 15000))   // Выполняется цикл 15000мс
  {
    dps.getPressure(&Pressure);
    dps.getTemperature(&Temperature);

    lcd.setCursor(0, 0);
    lcd.print(Temperature * 0.1, 1);
    lcd.print("\1");                   
    lcd.print(" ");

    lcd.setCursor(10, 0);
    lcd.print(Pressure / 133.3, 1);
    lcd.print("\2");

    lcd.setCursor(0, 1);

    lcd.setCursor(0, 1);
    lcd.print(temp0, 1);
    lcd.print("\1");                   
    lcd.print(" ");

    lcd.setCursor(11, 1);
    lcd.print(temp1, 1);
    lcd.print("\1");                   
    lcd.print(" ");

    old_time = current_time;
  }
  //----------------------------------------------------------------

  PIR = digitalRead(inputPin);                                                            // Считываем значение с датчика
  if (PIR == HIGH)                                                                        // Проверяем, соответствует ли считанное значение HIGH
  {
    lcd.backlight();                                                                        // Включаем подсветку на LCD1602
  } else
  {
    lcd.noBacklight();                                                                       // Выключаем подсветку на LCD1602
  }
  delay(300);
}

2

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

byte wachdog = 0;

// Выше
radio.read( &data, sizeof(data) );
// Добавить
wachdog = 0;

// Выше 
dps.getPressure(&Pressure);
// Добавить
wachdog++;

// Ну и в самом низу проверять.
if (wachdog >= 4)
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("NoSignal");
}

Суть проста, мы добавляем сторожевого пса.
Каждый раз, когда мы считываем данные, мы обнуляем переменную wachdog.
В цикле, который срабатывает раз в 15 секунды, мы увеличиваем переменную на один.
В конце мы проверяем, если переменная >= 4 т.е. если прошла 1 минута с последней передачи, то выводим сообщение.
Ну и когда данные опять начнут поступать, надпись исчезнет.

3

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

То же как то столкнулся с проблемой "замораживания данных", вкратце суть проста - после приёма данных:

  • нужно отобразить данные на дисплее

  • Сохранить последние данные в отдельной(!) переменной

  • Очистить(!) буфер приёма передачи

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

4

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Да, хорошо бы) хочу постараться вникнуть в оба варианта)

5

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

И да, мне бы затирать

 lcd.setCursor(0, 1);
    lcd.print(temp0, 1);
    lcd.print("\1");                   
    lcd.print(" ");

    lcd.setCursor(11, 1);
    lcd.print(temp1, 1);
    lcd.print("\1");                   
    lcd.print(" ");
dps.getPressure(&Pressure);

- это локальный датчик, а не удаленный

6

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Сопоставил вроде правильно, но не срабатывает.

void loop()
{
  byte wachdog = 0;
  byte pipeNo;
  while ( radio.available(&pipeNo))                                                     // Слушаем эфир со всех труб
  {
    wachdog = 0;
    radio.read( &data, sizeof(data) );                                                    // Чиатем входящий сигнал
  }
  {
    temp0 = data[0];
    temp1 = data[1];
  }
  //Блок работы опроса датчика
  //----------------------------------------------------------------
  current_time = millis();                                                              // Получаем текущие время
  if (old_time == 0 || current_time < old_time || current_time >= (old_time + 15000))   // Выполняется цикл 15000мс
  {
    wachdog++;
    dps.getPressure(&Pressure);
    dps.getTemperature(&Temperature);
    
    lcd.setCursor(0, 0);
    lcd.print(Temperature * 0.1, 1);
    lcd.print("\1");
    lcd.print(" ");

    lcd.setCursor(10, 0);
    lcd.print(Pressure / 133.3, 1);
    lcd.print("\2");

    lcd.setCursor(0, 1);
    lcd.print(temp0, 1);
    lcd.print("\1");
    lcd.print(" ");

    lcd.setCursor(11, 1);
    lcd.print(temp1, 1);
    lcd.print("\1");
    lcd.print(" ");

    if (wachdog >= 4)
    {
      lcd.clear();
      lcd.setCursor(5, 1);
      lcd.print("NoSignal");
    }
    old_time = current_time;
  }
  //----------------------------------------------------------------

7

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Все понял ошибку, поместил

byte wachdog = 0;

выше))))

8

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Жду этот скетч, даже интересно

jazon пишет:

То же как то столкнулся с проблемой "замораживания данных", вкратце суть проста - после приёма данных:

  • нужно отобразить данные на дисплее

  • Сохранить последние данные в отдельной(!) переменной

  • Очистить(!) буфер приёма передачи

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

9

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Спасибо!!! Как придут оставшиеся дисплеи закончу физически проект, выложу на ютуб, за помощь можно ссылаться на ваш форум?

genaonyx пишет:
byte wachdog = 0;

// Выше
radio.read( &data, sizeof(data) );
// Добавить
wachdog = 0;

// Выше 
dps.getPressure(&Pressure);
// Добавить
wachdog++;

// Ну и в самом низу проверять.
if (wachdog >= 4)
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("NoSignal");
}

Суть проста, мы добавляем сторожевого пса.
Каждый раз, когда мы считываем данные, мы обнуляем переменную wachdog.
В цикле, который срабатывает раз в 15 секунды, мы увеличиваем переменную на один.
В конце мы проверяем, если переменная >= 4 т.е. если прошла 1 минута с последней передачи, то выводим сообщение.
Ну и когда данные опять начнут поступать, надпись исчезнет.

10

Re: nRF24L01+ Вывод информации на LCD 1602 при ошибке получения данных.

Спасибо!!!

Не за что.

за помощь можно ссылаться на ваш форум?

На ваше усмотрение.