Вывод с DHT11 на LCD

makssmrr
Offline
Зарегистрирован: 13.03.2021

И снова здравствуйте. Вожусь с DHT11, хочу вывести данные на LCD дисплей. В конце концов с трудом что то да получилось, но есть два момента. 1)Не отображаются символы "T" "H" в начале, и градус целься в конце.( так же в конце "С" иногда проподает) 2) Не корректно отображаются данные с датчика, вместо условно 13% влажности пишет 1.00, вместо 26 градусов пишет 2.00 3) Иногда выдает на дисплее какую то чушь(при этом я ничего не трогал и не менял) 

 

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
 
// назначение PIN и выбор типа датчика DHT
#define DHTPIN 2 // 
// раскомментировать нужную строку
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
 
DHT dht(DHTPIN, DHTTYPE);   // инициализация сенсора DHT
LiquidCrystal_I2C lcd(0x27,16,2);  // инициализация дисплея
 
byte symb_grad[8] =      // кодирование символа градуса
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000,
};
 
void setup()
{
lcd.init();  // инициализация lcd
lcd.backlight(); //включение подсветки дисплея
lcd.createChar(1, symb_grad);  // регистрируем собственный символ с кодом 1
Serial.begin(9600);   // запуск передачи данных
dht.begin();  //  запуск датчика DHT
}
 
void loop()
{
// добавляем паузы в 2 секунды между измерениями
delay(2000);
 
float h = dht.readHumidity();   // считывание влажности
float t = dht.readTemperature();   // считывание температуры
 if (isnan (h)||isnan (t))
 {
  Serial.print("Ошибка считывания");
  return;
 }

 Serial.print ("Влажность: ");
 Serial.print (h);
 Serial.print (" %\t");
 Serial.print ("Температура: ");
 Serial.print (t);
 Serial.println (" c");
 
// Выводим показания влажности и температуры
//lcd.clear();  // очистка экрана
lcd.setCursor(0,0); //ставим курсор на 1 символ первой строки
lcd.print(dht.readHumidity()); // печатаем сообщение на первой строке
lcd.setCursor(5,0);//ставим курсор на 1 символ первой строки 
lcd.print(" %");//печатаем сообщение на первой строке
lcd.setCursor(0,1); //ставим курсор на 1 символ первой строки 
lcd.print(dht.readTemperature());
lcd.setCursor(5,1);
lcd.print(" \1C");

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

1. А что печатается в мониторе порта?

2. почему в строка №№58 и 62 не используются готовые переменные h и t, а проводятся повторные измерения?

makssmrr
Offline
Зарегистрирован: 13.03.2021

1.  В монитор порта просто данные выходят, для проверки работоспособности датчика, все отрабатывает корректно 

2. так было изначально записано откуда я брал данный код, но я заменял на переменные, результат не меняется 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

makssmrr пишет:

1.  В монитор порта просто данные выходят, для проверки работоспособности датчика, все отрабатывает корректно 

Так, второй раз спрашиваю, что печатается в мнитор порта? Мне нужна копия этой печати. Можете вставить? Или будете ваньку валять?

Давайте Вы сделаете так.

1. Поставите переменные, а не вызовы
2. Запустите скетч
3. Выложите актуальный код
4. выложите содержимое монитора порта
5. выложите фото экрана.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Пох#рьте какую-либо из дубль тем. 

makssmrr
Offline
Зарегистрирован: 13.03.2021

 

/*Вывод значений влажности и температуры 
на LCD 1602 I2C с датчика DHT11 или DHT22
*/
// подключение библиотек
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
 
// назначение PIN и выбор типа датчика DHT
#define DHTPIN 2 // 
// раскомментировать нужную строку
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
 
DHT dht(DHTPIN, DHTTYPE);   // инициализация сенсора DHT
LiquidCrystal_I2C lcd(0x27,16,2);  // инициализация дисплея
 
byte symb_grad[8] =      // кодирование символа градуса
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000,
};
 
void setup()
{
lcd.init();  // инициализация lcd
lcd.backlight(); //включение подсветки дисплея
lcd.createChar(1, symb_grad);  // регистрируем собственный символ с кодом 1
Serial.begin(9600);   // запуск передачи данных
dht.begin();  //  запуск датчика DHT
}
 
void loop()
{
// добавляем паузы в 2 секунды между измерениями
delay(2000);
 
float h = dht.readHumidity();   // считывание влажности
float t = dht.readTemperature();   // считывание температуры
 if (isnan (h)||isnan (t))
 {
  Serial.print("Ошибка считывания");
  return;
 }

 Serial.print ("Влажность: ");
 Serial.print (h);
 Serial.print (" %\t");
 Serial.print ("Температура: ");
 Serial.print (t);
 Serial.println (" c");
 
// Выводим показания влажности и температуры
//lcd.clear();  // очистка экрана
lcd.setCursor(0,0); //ставим курсор на 1 символ первой строки
lcd.print(h); // печатаем сообщение на первой строке
lcd.setCursor(5,0); //ставим курсор на 5 символ первой строки 
lcd.print(" %"); //печатаем сообщение на первой строке
lcd.setCursor(0,1); //ставим курсор на 1 символ второй строки 
lcd.print(t); ;//печатаем сообщение на второй строке
lcd.setCursor(5,1); //ставим курсор на 5 символ второй строки
lcd.print(" \1C"); ;//печатаем сообщение на второй строке

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Впредь, пожалуйста, вывод монитора порта тоже текстом вставляёте. Намного легче читать.

Попробуйте, вместо строки №62 вставить вот это и покажите, что получилось.

char hh[12];
dtostrf(h, 5, 2, hh);
Serial.print("hh='");
Serial.print(hh);
Serial.println("'");
lcd.print(hh); // печатаем сообщение на первой строке

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

ЕвгенийП пишет:

Дык по другому и не получится - LCD не умеет выводить действительные числа.

И, кстати, для знака градуса используйте

lcd.print((char)223);

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

mykaida пишет:

LCD не умеет выводить действительные числа.

Что весьма странно. Разбираться в лом, но мельком я глянул в библиотеку. Там этот класс наследуется от Print, а значит, должен делать всё, что тот умеет, а у Print есть метод: size_t print(double, int = 2);

makssmrr
Offline
Зарегистрирован: 13.03.2021

Добавил

Монитор порта: 

Влажность: 18.00 % Температура: 27.00 c
hh='18.00'
Влажность: 18.00 % Температура: 27.00 c
hh='18.00'
Влажность: 18.00 % Температура: 27.00 c
hh='18.00'
 
 
ИгорьЛабспирт
ИгорьЛабспирт аватар
Offline
Зарегистрирован: 08.03.2021
byte cels[8] ={8,20,8,3,4,4,3,0};

Для знака градуса цельсия использую такой символ. Cо вставкой фото не разобрался.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

makssmrr пишет:

Добавил

Что именно добавил? Код где?

makssmrr
Offline
Зарегистрирован: 13.03.2021
/*Вывод значений влажности и температуры 
на LCD 1602 I2C с датчика DHT11 или DHT22
*/
// подключение библиотек
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
 
// назначение PIN и выбор типа датчика DHT
#define DHTPIN 2 // 
// раскомментировать нужную строку
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
 
DHT dht(DHTPIN, DHTTYPE);   // инициализация сенсора DHT
LiquidCrystal_I2C lcd(0x27,16,2);  // инициализация дисплея
 
byte symb_grad[8] =      // кодирование символа градуса
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000,
};
 
void setup()
{
lcd.init();  // инициализация lcd
lcd.backlight(); //включение подсветки дисплея
lcd.createChar(1, symb_grad);  // регистрируем собственный символ с кодом 1
Serial.begin(9600);   // запуск передачи данных
dht.begin();  //  запуск датчика DHT
}
 
void loop()
{
// добавляем паузы в 2 секунды между измерениями
delay(2000);
 
float h = dht.readHumidity();   // считывание влажности
float t = dht.readTemperature();   // считывание температуры
 if (isnan (h)||isnan (t))
 {
  Serial.print("Ошибка считывания");
  return;
 }

 Serial.print ("Влажность: ");
 Serial.print (h);
 Serial.print (" %\t");
 Serial.print ("Температура: ");
 Serial.print (t);
 Serial.println (" c");
 
// Выводим показания влажности и температуры
lcd.clear();  // очистка экрана
lcd.setCursor(0,0); //ставим курсор на 1 символ первой строки
char hh[12];
dtostrf(h,5,2,hh);
Serial.print("hh='");
Serial.print(hh);
Serial.println("'");
lcd.print(hh);
lcd.setCursor(5,0);//ставим курсор на 5 символ первой строки 
lcd.print(" %");//печатаем сообщение на первой строке
lcd.setCursor(0,1); //ставим курсор на 1 символ второй строки 
lcd.print(t); //печатаем сообщение на второй строке
lcd.setCursor(5,1); //ставим курсор на 5 символ второй строки
lcd.print((char)223); //печатаем сообщение на второй строке

}

 

ИгорьЛабспирт
ИгорьЛабспирт аватар
Offline
Зарегистрирован: 08.03.2021
/*Вывод значений влажности и температуры 
на LCD 1602 I2C с датчика DHT11 или DHT22
*/
// подключение библиотек
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"
 
// назначение PIN и выбор типа датчика DHT
#define DHTPIN 2 // 
// раскомментировать нужную строку
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
 
DHT dht(DHTPIN, DHTTYPE);   // инициализация сенсора DHT
LiquidCrystal_I2C lcd(0x27,16,2);  // инициализация дисплея
byte k207[8] ={31,17,17,17,17,17,17,0};	// кодирование символа П
byte k211[8] ={17,17,17,10,4,8,16,0};	// кодирование символа У
byte k203[8] ={15,5,5,5,5,21,9,0};		// кодирование символа Л
byte k198[8] ={21,21,21,14,21,21,21,0};	// кодирование символа Ж
byte k220[8] ={8,8,8,14,9,9,14,0};		// кодирование символа Ь
byte k176[8] ={8,20,8,3,4,4,3,0};		// кодирование символа градуса
   
 void setup()
{
lcd.init();  // инициализация lcd
lcd.backlight(); //включение подсветки дисплея
// регистрируем символы
lcd.createChar(0, k207); // П
lcd.createChar(1, k211); // У
lcd.createChar(2, k203); // Л
lcd.createChar(3, k198); // Ж
lcd.createChar(4, k220); // Ь
lcd.createChar(5, k176); // °С

Serial.begin(9600);   // запуск передачи данных
//dht.begin();  //  запуск датчика DHT
//пишем на дисплее постоянную часть сообщения.
lcd.clear();  // очистка экрана
//lcd.setCursor(0,0); //Не ставим курсор на 1 символ первой строки, после CLEAR он уже там.
lcd.print("TEM\x8\x45PAT\x1PA");// TEMПEPATУPA     
lcd.setCursor(0,1) ;
lcd.print("B\x2\x41\x3HOCT\x4");// BЛAЖHOCTЬ       


void loop() { // добавляем паузы в 2 секунды между измерениями delay(2000); float h = dht.readHumidity(); // считывание влажности float t = dht.readTemperature(); // считывание температуры if (isnan (h))

 {
  Serial.println("Ошибка считывания влажности");
  lcd.setCursor(12,1) ;
  lcd.print("ERR") ;  
 }
 else
 {
 Serial.print ("Влажность: ");
 Serial.print (h);
 Serial.println (" %\t");
  lcd.setCursor(12,1) ;
  lcd.print(String(h,0)+"%") ; 
}

  if (isnan (t))
 {
  Serial.println("Ошибка считывания температуры");
  lcd.setCursor(12,0) ;
  lcd.print("ERR") ; 
 }
 else
 {
  lcd.setCursor(12,0) ;
  lcd.print(String(t,0)+"\x5") ;  
 Serial.print ("Температура: ");
 Serial.print (t);
 Serial.println (" c");
 }
}
    
Порт... 
05:23:53.126 -> Температура: 21.77 c
05:23:55.129 -> Влажность: 29.44 %
05:23:55.129 -> Температура: 21.77 c
05:23:57.313 -> Влажность: 29.44 %
05:23:57.313 -> Температура: 21.77 c
05:23:59.150 -> Влажность: 29.44 %
05:23:59.150 -> Температура: 21.77 c
... и так далее.

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Поскольку чудес не бывает (по крайней мере на этом форуме), то предполагаю проблему или в LCD или в контактах.

Создайте маленькую программу и выведите "HELLO", целые числа, действительные числа через dtostrf().

Надо локализовать проблему.

ИгорьЛабспирт
ИгорьЛабспирт аватар
Offline
Зарегистрирован: 08.03.2021

ИгорьЛабспирт
ИгорьЛабспирт аватар
Offline
Зарегистрирован: 08.03.2021

Чудес на наблюдаю. 

В первой (нулевой) строке  вывожу число 12,34567 напрямую в print. Округляется до двух знаков.

Во второй строке вывожу через dtostrf, задав буфер в 5 символов и 0 знаков после запятой. Справа и слева втыкаю палки чтобы видеть границы. Все как в букваре. 

В третей строке -  тоже через dtostrf, но меняю размер буфера, 14 на 7. Теперь слева добавляются пробелы, а справа добавляется безобразие. Ардуино хреново работает с плавающей запятой. 

И во второй, и в третьей строке пришлось палки ставить в отдельные принт, так как строка с массивом символов просто так не клеится.

В последней строке я использовал String. Без аргумента он округляет до двух знаков, в с аргументом - до заданного количества знаков. 

String клеится с палкой, поэтому весь ввод пошел в один принт.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,4);	
  
void setup(){
float a = 12.34567;
char b[15];
	lcd.init();lcd.backlight();lcd.noBlink();lcd.clear();    

	lcd.setCursor(0,0); 
	lcd.print(a);  

	dtostrf(a,5,0, b);

	lcd.setCursor(0,1); 
	lcd.print("|");
	lcd.print(b);
	lcd.print("|");

	dtostrf(a,14,7, b);
  
	lcd.setCursor(0,2); 
	lcd.print("|");
	lcd.print(b);
	lcd.print("|");
	
	lcd.setCursor(0,3);lcd.print("|"+String(a,0)+"|"+String(a,8)+"|");
}
void loop(){}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так, понятно, значит, скетч из последнего поста работает нормально, а тот, что выше - криво. Так?

При этом библиотеки те же, и сборка та же (не пересобираете для другого скетча). Всё так?

Тогда вопросы - 

1. Что за ардуино? Точнее какой именно контроллер?
2. что за версии библиотек (можно ссылку, где брали)?

И ещё раз чётко уточните, какой именно скетч как работает. Я хочу повторить у себя, так не заставляёте меня это сделать, а потом узнать, что Вы не то имели в виду.