Криво работает вывод на дисплей

Собрал прибор, измеряющий параметры окружающей среды, выводящий их на экран и при необходимости включающий тревогу с пояснением причины тревоги на экране. Ситуация следующая - если закомментировать блок тревоги то вывод работает нормально, если блок тревоги работает, то символ градусника вообще не выводится (каким раком не знаю, он в коде стоит РАНЬШЕ тревоги), а показания не выводятся в принципе, даже если тревоги нет. Быстрая отладка через сериал принт показала что даже при запуске значения просто не считываются…
Прошу помочь, код прикрепил ниже.

#include "DHT.h"
#include <BH1750.h>                      //подключаем все необходимые библиотеки
#include <Wire.h>
#include <math.h>


#define DHTPIN 3 //задаем пин для датчика DHT22 (датчик влажности и температуры воздуха)
#define DHTTYPE 22 //тип датчика (DHT22), для универсальной библиотеки DHT
#define SoilPin A1 // задаем пин для снятия показаний с  датчика влажности почвы 
#define SoilPowerPin 9//задаем пин питания датчика влажности почвы
int piezoPin = 6; //задаем пин для управления зуммером (для сигнала тревоги)

LiquidCrystal_I2C lcd(0x27,16,2); //установка дисплея
BH1750 lightMeter; //создаем объект lightMeter для управления датчиком света


DHT dht(DHTPIN, DHTTYPE); //задаем тип и пин датчика DHT для библиотеки

//объявляем глобальные переменные (предельные показатели датчиков)
int const maxlight = 36000;  //максимально допустимый уровень света
int const minlight = 9; //минимально допустимый уровень света
int const mintemp = 16; //минимально допустимый уровень температуры воздуха
int const maxtemp = 30;  //максимально допустимый уровень температуры воздуха
int const maxhum = 70; //максимально допустимая влажность воздуха
int const minhum = 40; //минимально допустимая влажность воздуха
int const maxsoil = 300;  //максимально допустимая влажность почвы. 
int const minsoil = 908; //минимально допустимая влажность почвы



void alertSignal(){//функция для  сигнала тревоги. 
 lcd.home();
 tone(piezoPin, 1000, 500);
 delay(800);
 noTone(piezoPin);                   //мелодия для зуммера 
 delay(100);
 tone(piezoPin,1000,500);
 delay(800);
}


void setup() {
//подготовка к работе (инициализация, задание режима работы пинов)
pinMode(SoilPin, INPUT);
pinMode(SoilPowerPin, OUTPUT);//переводим пин питания датчика влажности почвы в режим output
lcd.backlight();
Wire.begin();
lightMeter.begin();
lcd.init();
dht.begin();
Serial.begin(9600);

byte Humidity_symbol[] = {//символ капли для влажности воздуха
 B00100,
 B00100,
 B01110,
 B11111,
 B11111,
 B11111,
 B11111,
 B01110
};

byte Temp_symbol[] = {//символ градусника для показа температуры воздуха
 B01011,
 B01011,
 B01000,
 B11111,
 B01000,
 B01000,
 B01010,
 B01110
};

byte LightLevelSymbol[] = {//символ солнца для отображения уровня освещенности
 B00100,
 B10101,
 B01110,
 B11111,
 B11111,
 B01110,
 B10101,
 B00100
};



byte SoilSymbol[] = {//символ уровня влажности почвы (толком нихрена не придумал еще)
 B00100,
 B01110,
 B11111,
 B11111,
 B01110,
 B00000,
 B11111,
 B11111
};

lcd.createChar(3, Temp_symbol);
lcd.createChar(0, Humidity_symbol);
lcd.createChar(4, LightLevelSymbol);
lcd.createChar(5, SoilSymbol);

}

void loop() {
//блок вывода интерфейса на экран
lcd.backlight();
lcd.write(3);//выводит на экран градусник
lcd.print(":");
lcd.setCursor(11,0);
lcd.write(0);// выводит на экран каплю
lcd.print(":");
lcd.setCursor(0,1);
lcd.write(4);//выводит на экран символ освещенности
lcd.print(":");
lcd.setCursor(11,1);//выводит на экран символ влажности почвы
lcd.write(5);
lcd.print(":");
//блок сбора данных
float lux = lightMeter.readLightLevel();
float AirHumid = dht.readHumidity();                //считываем показания датчиков
float AirTemp = dht.readTemperature();
int TempLED = ceil(AirTemp);
int HumLed = ceil(AirHumid);    //тут мы округляем значения с датчиков в большую сторону, дабы влезли показания на экран.
int luxLED = ceil(lux);          //и тут тоже округляем...


//отдельно блок управления почвой
digitalWrite(SoilPowerPin, HIGH);//подаем питание на датчик влажности почвы
int Soil = analogRead(SoilPin); //снимаем показания с датчика влажности почвы. Содержит аналоговое значение в диапазоне от 0 до 1023. Используется для анализа состояния почвы.
delay(250);//тут воткнул делей чисто ради безопасности мб убрать его?
digitalWrite(SoilPowerPin,LOW);//отключаем питание у датчика влажности почвы
int percentSoil = map(Soil, 0, 1023, 100, 0); //перевод значений влажности почвы в проценты из аналоговых единиц. Используется для вывода
//блок вывода показаний
lcd.setCursor(2,0);
lcd.print(TempLED);//вывод показаний на экран.
lcd.print("C");
lcd.setCursor(13,0);
lcd.print(HumLed);
lcd.print("%");
lcd.setCursor(2,1);
lcd.print(luxLED);
lcd.print("Lx");
lcd.setCursor(13,1);
lcd.print(percentSoil);
lcd.print("%");
delay(1000);
lcd.clear();
Serial.println(lux);
Serial.println(Soil);
Serial.println(AirTemp);

//блок тревоги 
if (luxLED > maxlight) {
 lcd.print("TOO MUCH LIGHT!");
 alertSignal();
}

if (Soil<=minsoil) {
 alertSignal();
 lcd.print("SOIL IS DRY!");

}


if (HumLed < maxhum){
 alertSignal();
 lcd.print("AIR IS DRY!");

}


if (TempLED < maxtemp) {
 alertSignal();
 lcd.print("AIR IS COLD!");
}


if  (luxLED < minlight) {
 alertSignal();
 lcd.print("TOO DARK!");
}


if  (HumLed > maxhum) {;
 alertSignal();
 lcd.print("AIR IS TOO HUMID!");

}

if  (TempLED > maxtemp) {
 alertSignal();
 lcd.print("TOO HOT!");
}

if  (Soil >= maxsoil) {
 alertSignal();
 lcd.print("SOIL IS WATERLOGGED!");
 
}
delay(2000);

}```

Есть такая поговорка: “косо-криво, лишь бы живо”. Хочется нормального - расставляйте отладочный вывод. Всего то.)

А если у вас будет сразу две тревоги, то как вы об этом узнаете?

Конечно никак. Будет паника и конец света.)

1 лайк

не подумал об этом. Скорее всего, сработает первая.

Будет такая “трель” - “мама ой” :laughing:
А на экране отразится последнее сообщение и остатки от предыдущего (если таковое будет).
Код же блокирующий, да еще с такими большими задержками…

1 лайк

последнее сообщение и остатки пофиксил добавлением “lcd.clear()” в начале цикла, так чтобы перед каждым измерением производилась очистка экрана. Теперь у меня проблема с тем что ардуино выдает тревогу по “слишком большому уровню света”. Если что предел по максимуму 36к люкс а вывод показывает 273 люкса.

Горе с этими любителями. Впору операционку какую нибудь представлять , что бы задержки можно было использовать. И delay не бояться.)

Но не между “сработками”. Об этом я и написал. Или до тебя не дошло еще о чем я?

сработка через функцию в которой зуммер выпикивает два раза и останавливается, прямо сейчас у меня орала тревога на готовом образце и все нормально было)
но вопрос с тревогой не раскрыт, раскомментировал один иф - работало нормально
раскоменнтировал все ИФы - тревога не орет но ничего кроме “интерфейса” не выводится

Бгггг, он еще спорит…

Вот кусок твоего кода:

if  (HumLed > maxhum) {;
 alertSignal();
 lcd.print("AIR IS TOO HUMID!");
}

if  (TempLED > maxtemp) {
 alertSignal();
 lcd.print("TOO HOT!");
}

Что будет на экране если оба условия выполнятся?

Сначала вызовется функция внутри alertSignal()

lcd.home();

Курсор встанет на первый символ первой строки и напечатается:

AIR IS TOO HUMID!

А потом точно так же курсор вернется на первый символ первой строки и не очищаясь сверху напчатает:

TOO HOT!

А общий результат на экране будет такой:

TOO HOT!OO HUMID!

если внутрь alertSignal добавить lcd.clear(), то эта проблема должна решиться. Но все равно дело не в ней, а в том что у меня не выводятся сами показания датчиков (просто на экране пиктограммы и все)

Выбросите всё из скетча кроме вывода данных на экранчик через 5 сек.

У Вас вместо кода - лапша.
Разделите код на отдельные блоки по назначению:

  1. Измерения параметров.
  2. Анализ ситуации.
  3. Индикация результатов на экране.
  4. Включение тревоги.

И при этом избавьтесь от всех delay().

Информация к размышлению: процесс отладки намного более трудоемкий, чем процесс написания кода. Поэтому ВСЕГДА целесообразно переписать код с нуля так, чтобы облегчить процесс отладки.

1 лайк

Попробуйте else if

https://forum.arduino.ru/t/shtaskmanager-legkij-dispetcher-zadach-dlya-arduino/

Да. Осталось только ещё людЯм внедрить. Что бы не боялись).

Утож )))

2 лайка