N
N
Nihhilistum2019-08-27 19:32:39
Arduino
Nihhilistum, 2019-08-27 19:32:39

How to serialize information on lcd with millis( )?

I'm writing code for a weather station. I use lcd 1602 (16x2) with I2C and a button to activate the display. I decided to scatter each blocks of code responsible for the operation of any modules in functions. I registered all actions tied to time not through delay (), but with the help of millis (), so as not to slow down the microcontroller. When I wrote the sketch and ran it on Arduino, two problems emerged:
1) The screen displayed only a greeting, without removing the text after the time had elapsed and then not displaying other information.
2) If the screen faded, then pressing the button again did not turn it on (it was thought that when the display was turned off, pressing the button again would make it turn on and again display first a greeting, and then information, and so on ad infinitum).
Here is this horror of a beginner unfortunate arduinist:

#include <Arduino.h>
#include <DHT_U.h>
#include <DHT.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>

//РАСПИНОВКА
#define DHTTYPE DHT11 //указание модели датчика DHT
#define DHTPIN 7      //пин датчика
#define button 2      //пин кнопки

//ТАЙМЕРЫ
uint16_t meteoTimer;         //таймер периодичности замера показаний датчика
uint16_t screenWelcomeTimer; //таймер приветствия экрана
uint16_t screenDataTimer;    //таймер вывода инфы с экрана

//ПЕРЕМЕННЫЕ:
byte temp; //значение температуры
byte hum;  //значение влажности

//ФУНКЦИИ
void meteo_current(); //функция замера температуры и влажности
void my_clear();      //библиотечный clear() не работает, этот костыль делает то же самое
void screen_inform(); //функция экрана

//ИНИЦИАЛИЗАЦИИ
DHT dht(DHTPIN, DHTTYPE);        //иициализвция датчика
LiquidCrystal_PCF8574 lcd(0x27); //инициализация экрана

void setup()
{
  dht.begin();      //начало работы датчика
  lcd.begin(16, 2); //начало работы экрана
  lcd.setBacklight(0);
  pinMode(button, INPUT_PULLUP); //подтяжка кнопки (сигнал будет инвертирован)
}

void loop()
{
  while (1) //в loop много проверок от дурака. Этот цикл немного ускорит МК
  {
    meteo_current();                //функция датчика
    if (digitalRead(button) == LOW) //сигнал инвертирован из-за подтяжки
    {
      screen_inform(); //функция экрана
    }
  }
}

void meteo_current() //функция датчика
{
  if (millis() - meteoTimer == 1000)
  {
    meteoTimer = millis();        //обновление таймера
    temp = dht.readTemperature(); //чтение температуры
    hum = dht.readHumidity();     //чтение влажности
  }
}

void my_clear() // библиотечный clear() не работает, этот костыль делает то же самое
{
  lcd.setCursor(0, 0);
  lcd.print("                "); //ввод 16 пробелов для очистки строки
  lcd.setCursor(0, 1);
  lcd.print("                "); //офигеть какой костыль, но работает как надо
}

void screen_inform()
{
  while (millis() - screenWelcomeTimer < 7000) //приветствие в течение 7с
  {
    screenWelcomeTimer = millis(); //обновление таймера
    lcd.setBacklight(100);
    lcd.setCursor(5, 0);
    lcd.print("Hello");
    lcd.setCursor(2, 1);
    lcd.print("Nihillist");
  }
  my_clear();                                 //функция очистки экрана
  while (millis() - screenDataTimer < 420000) //вывод инфы в течение 7 мин
  {
    screenDataTimer = millis(); //обновление таймера
    lcd.setCursor(0, 0);
    lcd.print("Temperature  ");
    lcd.print(temp); //вывод температуры
    lcd.print("  *C");
    lcd.setCursor(0, 4);
    lcd.print("Humilty  ");
    lcd.print(hum); //вывод влажности
    lcd.print("  *");
  }
  my_clear();          //функция очистки экрана
  lcd.setBacklight(0); //потушить подсветку экрана
}

Answer the question

In order to leave comments, you need to log in

3 answer(s)
K
kalapanga, 2019-08-27
@kalapanga

To begin with, remove while(1) - don't make people laugh, the comment contains complete nonsense.
Further, your comment about the inverted signal says absolutely nothing about when the button is pressed, and when it is not - only confuses. Make a ButtonPressed function. In it, check the pin for what you need. And the program will only have if ButtonPressed .... After all, it's more readable this way, right? And finally, it is necessary to formulate the desired algorithm more clearly:
- The initial state after switching on is that the button is pressed, nothing on the screen.
- The button is pressed and released (or pressed and held?) the following happens...
- If during this next.... then...
Then something more definite can be said. Or maybe you yourself will see during this time that your algorithm does not match.

V
vanyamba-electronics, 2019-08-27
@vanyamba-electronics

420000 is 19 bits, the variable must be of type unsigned long - uint32_t.

D
Dmitry, 2019-10-24
@Tomasina

#define LCD_UPDATE_TIME 40 // switching interval between screens, sec
#define LCD_SCREENS 4 // number of screens with information
...
loop()
{
static byte screenPage = 1; // current screen number counter
static unsigned long prevScreenUpdateTime;
...
if (millis() - prevScreenUpdateTime > LCD_UPDATE_TIME * 1000) // the button has not been pressed for more than N seconds
{
screenPage++;
if (screenPage > LCD_SCREENS) screenPage = 1;
my_clear(); //screen clearing function
switch (screenPage)
{
case 1:
{
.....
break;
}
case 2:
{
.....
break;
}
{
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question