lcd 1602

parrkof
Offline
Зарегистрирован: 18.04.2021

Доброго времени суток . Я новичок в программировании ардуино , занимаюсь этим делом около месяца . В данный момент времени пытаюсь разобраться с выводом НЕСКОЛЬКИ данных на дисплей (lcd1602). У меня стоит цель вывести данные с датчиков (YL-69, DNT11, DS1820) . Датчики я сумела подключить , и по отдельности я поняла как выводить на дисплей , но у меня вызывает недопонимание как заставить ардуино выводить данные сразу с нескольких .

Green
Offline
Зарегистрирован: 01.10.2015

Неужто нужно прям сразу? А если по очереди? По секунде каждому - 3 сек. на всё - про всё, не?

parrkof
Offline
Зарегистрирован: 18.04.2021

Да , мне нужно , желательно через кнопку , но вот у меня загвоздка в том что я не имею представления как это всё объединить в один код . Не могли бы подсказать как это объединить 

parrkof
Offline
Зарегистрирован: 18.04.2021

parrkof пишет:

Да , мне нужно , желательно через кнопку , но вот у меня загвоздка в том что я не имею представления как это всё объединить в один код . Не могли бы подсказать как это объединить 

Я знакома со всеми кодами к этим датчикам и знакома с работой кнопки , но опять же повторюсь , облазив весь гугл не нашла тутор по написанию общего 

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

Где ваш код?

parrkof
Offline
Зарегистрирован: 18.04.2021
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

#include <DHT.h>

#define DHTPIN 2
DHT dht(DHTPIN, DHT11);

void setup() {
 
  lcd.init();
  lcd.backlight();
 
  Serial.begin(9600);
  dht.begin();
}

void loop() {
  delay(1000); // 2 секунды задержки
  float h = dht.readHumidity(); //Измеряем влажность
  float t = dht.readTemperature(); //Измеряем температуру
  
  Serial.print("Влажность: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Температура: ");
  Serial.print(t);
  Serial.println(" *C "); //Вывод показателей на экран

  lcd.setCursor(0,0);
  lcd.print(dht.readHumidity());
  lcd.setCursor(5,0);
  lcd.print("%");
  lcd.setCursor(0,1);
  lcd.print(dht.readTemperature());
  lcd.setCursor(5,1);
  lcd.print("C");
}
#include <Wire.h>                          
#include <LiquidCrystal_I2C.h>              
#include <DallasTemperature.h>             
#define DS18B20 2  
byte simvol[8]   = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; 
 
LiquidCrystal_I2C lcd(0x27,16,2);          
OneWire oneWire(DS18B20);                   
DallasTemperature sensors(&oneWire);
 
void setup()
{
  sensors.begin();                           // Запуск библиотеки, по умолчанию 9 бит, то есть кратность 0.5 градуса 
  lcd.init();                                  
  lcd.backlight();                           
  lcd.setCursor(2,0);                       
  lcd.print("TEMP");                         
  lcd.setCursor(0,1);                        
  lcd.print("www.robotchip.ru");             
}
void loop()
{
  lcd.createChar(1, simvol);                 
  sensors.requestTemperatures();             
  lcd.setCursor(7,0);                        
  lcd.print(sensors.getTempCByIndex(0));      
  lcd.setCursor(12,0);                       
  lcd.print("\1");                            
  lcd.setCursor(13,0);                        
  lcd.print("C");                              
}

 

parrkof
Offline
Зарегистрирован: 18.04.2021

BOOM пишет:

Где ваш код?

#include <Wire.h>                           // Подключаем библиотеку Wire
#include <LiquidCrystal_I2C.h>              // Подключаем библиотеку LiquidCrystal_I2C 
#include <DallasTemperature.h>              // Подключаем библиотеку DallasTempature
#define DS18B20 2                           // Указываем, к какому выводу подключена DQ

byte simvol[8]   = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; // Символ градуса

LiquidCrystal_I2C lcd(0x27,16,2);           // Задаем адрес и размер дисплея
OneWire oneWire(DS18B20);                   
DallasTemperature sensors(&oneWire);
 
void setup()
{
  sensors.begin();                           
  lcd.init();                                   
  lcd.backlight();                          
  lcd.setCursor(2,0);                        
  lcd.print("TEMP");                        
  lcd.setCursor(0,1);                        
  lcd.print("www.robotchip.ru");            
}
void loop()
{
  lcd.createChar(1, simvol);                  
  sensors.requestTemperatures();              
  lcd.setCursor(7,0);                         
  lcd.print(sensors.getTempCByIndex(0));      
  lcd.setCursor(12,0);                        
  lcd.print("\1");                            
  lcd.setCursor(13,0);                        
  lcd.print("C");                             
}
parrkof
Offline
Зарегистрирован: 18.04.2021

У меня отдельные коды . А вот как их можно объединить и заставить переключатся дисплей между данными по кнопке . Возможно есть какая-то статья или урок ?

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

parrkof пишет:

Я знакома со всеми кодами к этим датчикам и знакома с работой кнопки , но опять же повторюсь , облазив весь гугл не нашла тутор по написанию общего 

Есть отличный гайд по объединению скетчей. Прочитав половину вы сможете даже (святотатство!) писать собственные:

parrkof
Offline
Зарегистрирован: 18.04.2021

Огромное спасибо)

parrkof
Offline
Зарегистрирован: 18.04.2021

А не могли бы вы сейчас подсказать как правильно собрать весь код в одно целое, а то книгу я заказала , а проект хотела доделать сейчас , ну точнее в ближайшее время. 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

parrkof пишет:

А не могли бы вы сейчас подсказать как правильно собрать весь код в одно целое, а то книгу я заказала , а проект хотела доделать сейчас , ну точнее в ближайшее время. 

Неа)) Боюсь, испорчу удовольствие. А как скоро требуется закончить проект?

parrkof
Offline
Зарегистрирован: 18.04.2021

Желательно до конца предстоящей недели , это проект на подобии умный аквариум со своем "садом" и метеостанцией , в субботу будет рыбка , хотелось уже запустить в это чудо инженерии)

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Завтра постараюсь глянуть, если работа позволит. 

parrkof
Offline
Зарегистрирован: 18.04.2021

Спасибо огромное )

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

parrkof пишет:

Спасибо огромное )

Не стоит благодарить раньше времени. Не забывайте аксиому трех "З". Я могу: забыть, запить, забить :)

Еще и в синдроме сейчас буду заклеймён))

 

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

parrkof пишет:

Желательно до конца предстоящей недели , это проект на подобии умный аквариум со своем "садом" и метеостанцией , в субботу будет рыбка , хотелось уже запустить в это чудо инженерии)

Рыбку пожалейте! В неотлаженную и непроверенную систему-то запускать! :-)

Вас, случайно, не Юлей зовут?

parrkof
Offline
Зарегистрирован: 18.04.2021

Уверяю вас с рыбкой будет всё хорошо ) Зовут не Юлей 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

parrkof пишет:

Зовут не Юлей 

Хреново...

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

parrkof пишет:

Зовут не Юлей 

Не повезло :-(

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

DetSimen пишет:

Хреново...

Насколько это хреново? Придется работать с тем, что есть

 

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

parrkof пишет:
Спасибо огромное )

В общем, картина такая. Не увидел в ваших программах YL-69 от слова совсем. Ну, да не суть..

Итак, если я правильно понял задачу, нужно делать следующие вещи:

1. Измерять температуру среды датчиком DS18b20

2. Измерять температуру и влажность воздуха датчиком DHT (только не вздумайте его к рыбкам окунать))

3. Измерять влажность (грунта?) недо-датчиком YL-69. 

4. Показывать попеременно полученные значения на экране.

Из этого логично вытекает структура будущей программы: нам нужны 4 функциональных блока, которые будут вызваться с определенной периодичностью из основного цикла. Определенность периодичности будет достигаться простейшим, но очень эффективным алгоритмом, основанном на встроенной функции millis(). Советую внимательно ознакомиться с ней тут на форуме - в книжках по С++ про нее ничего не найдете.

Как и обещал вчера спьяну, набросал небольшую программку. Сразу отказываюсь от любой ответственности перед рыбками, ибо НЕ ПРОВЕРЯЛ код на железе, просто банально нет ничего под рукой. Выкинул из ваших примеров библиотеку Далласа, поскольку она содержит блокирующий код, а это рыбкам не к чему совсем. Обратите внимание на подключение датчиков. 

Красоту вывода на экран настраивайте сами. 

#include <Wire.h>                          
#include <LiquidCrystal_I2C.h>              
#include <OneWire.h>         
#include <DHT.h>    

const uint8_t ds1Pin{7};            // DS18b20 будем подключать к пину D7
const uint32_t msRepTime {10000};   // DS18b20 будем опрашивать каждые 10 секунд (по факту каждые 11)
uint32_t msTemp {msRepTime};        // Объявляем счетчик для опроса DS18b20 и инициализируем его значением для моментального начала процедуры
const uint8_t simvol[8] {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000}; 
uint8_t ds1Qty {0};                 // Количество датчиков DS18b20 на пине (не более 3-х). Если больше одного, значения будут усредняться 
int8_t  ds1Temp {0};                // Собственно, значение температуры по Цельсию от DS18b20
uint8_t ds1DS[3][8];                // Адреса положу пока здесь. Если кому не лень, их нужно убрать из глобальной ОВ, как и количество датчиков

const uint8_t DHTPin{8};            // DHT будем подключать к пину D8
float dhtTemp {0};                  // DHT значение температуры
float dhtHum {0};                   // DHT значение влажности
const uint32_t msDhtTime {5017};    // DHT будем опрашивать каждые 5+ секунд. "Кривое" значение, чтобы не пересекаться по времени с опросом DS
uint32_t msDht {msDhtTime};         // Объявляем счетчик для опроса DHT и инициализируем его значением для моментального начала процедуры

const uint8_t ylPin{14};            // YL будем подключать к пину A0(14). ВНИМАНИЕ: подключение аналогового выхода датчика!
uint16_t ylVal{0};                  // Переменная для показаний датчика влажности YL
const uint32_t msYlTime {100};      // YL будем опрашивать каждые 0.1 секунд, чтобы МК хоть чем-то был занят в цикле))
uint32_t msYl {0};                  // Объявляем счетчик для опроса YL-69

const uint32_t msPageExpo {5000};   // Устанавливаем по 5 секунд на отображение каждой страницы
uint32_t msPage {0};                // Объявили счетчик для экрана 


LiquidCrystal_I2C lcd(0x27, 16, 2);           
DHT dht(DHTPin, DHT11);



void setup() {
  Serial.begin(115200);     // Скорость должна соответствовать настройкам монитора порта 
  lcd.init();               
  lcd.backlight();
  dht.begin();
  searchSensors();          // Запускаем первоначальный поиск датчиков DS18b20 на пине
}

void loop() {
  if (millis() - msTemp > msRepTime)  updateTemp();       // Опрашиваем температуру DS18b20 с частотой msRepTime
  if (millis() - msDht > msDhtTime)   runDht();           // Опрашиваем DHT
  if (millis() - msYl > msYlTime)     runYl();            // Опрашиваем YL-69
  if (millis() - msPage > msPageExpo) updatePage();       // Листаем страницы
}




//**************  Секция экранчег  ****************************
void updatePage(){                       // Листаем страницы на экранчике
  static uint8_t page {0};              
//  Первая страница
  if (page == 0){
    lcd.setCursor(0,0);
    lcd.print("DS18b20 temp:    ");
    lcd.setCursor(0,1);
    lcd.print((int8_t)ds1Temp);
    lcd.setCursor(3,1);
    lcd.print("C   ");
    msPage = millis(); 
    page++; 
    return;
  }
//  Вторая страница
  if (page == 1){
    lcd.setCursor(0,0);
    lcd.print("DHT temp:         ");
    lcd.setCursor(0,1);
    lcd.print((int8_t)dhtTemp);
    lcd.setCursor(2,1);
    lcd.print("C   ");    
    msPage = millis(); 
    page++; 
    return;
  }
//  Третья страница
  if (page == 2){
    lcd.setCursor(0,0);
    lcd.print("DHT hum:         ");
    lcd.setCursor(0,1);
    lcd.print((uint8_t)dhtHum);
    lcd.setCursor(2,1);
    lcd.print("%   ");    
    msPage = millis(); 
    page++; 
    return;
  }
// Последняя страница
  if (page == 3){  
    lcd.setCursor(0,0);
    lcd.print("YL-69 hum:         ");
    lcd.setCursor(0,1);
    lcd.print((uint16_t)ylVal);
    lcd.setCursor(3,1);
    lcd.print("    ");      
    msPage = millis(); 
    page = 0; 
    return;
  }
}


//**************  Секция YL-69  ****************************
void runYl(void){
  ylVal = analogRead(ylPin);;           //Измеряем влажность. Маппинг пишем сами, если надо
}


//**************  Секция DHT  ****************************
void runDht(void){
  dhtHum = dht.readHumidity();          //Измеряем влажность
  dhtTemp = dht.readTemperature();      //Измеряем температуру
}

//**************  Секция DS18b20  ****************************
void updateTemp(){                       // Основная процедура обновления температурных данных со всех датчиков
  static uint8_t stage {0};
//  Первый этап. Отправка запросов на конвертацию 
  if (stage == 0){
    if (ds1Qty) requestSensor(ds1Pin);
    stage++; 
    msTemp = millis() - msRepTime + 800;    // 0.75 секунды требуется датчику для осуществления конвертации на максимальном разрешении
    return;
  }
// Второй этап. Чтение показаний  
  if (stage == 1){  
    if (ds1Qty) readSensor(&ds1Temp, ds1Pin, ds1DS, ds1Qty);
    msTemp = millis(); 
    stage = 0; 
    return;
  }
}

void readSensor(int8_t* t, uint8_t pin, void* buf, uint8_t qt){       // Чтение температуры с датчика ds18b20
  OneWire ds(pin);
  uint8_t addr[8];
  uint8_t data[9];
  float temp[3];
  uint8_t qty {0};
  for (uint8_t c {0}; c < qt; c++){
    for(uint8_t i {0}; i<8 ;i++) addr[i] = *((uint8_t*)buf+c*8+i);
    ds.reset(); ds.select(addr); ds.write(0xBE); 
    for (uint8_t d {0}; d<9; d++) data[d] = ds.read();    
    int16_t raw = (data[1] << 8) | data[0];
    raw = raw & ~1;
    temp[qty++] = raw / 16.0;  
  }
  float tmp {0};
  for (uint8_t i {0}; i<qty; i++) tmp+= temp[i];
  *t = round(tmp/qty);
  Serial.print("Температура пин "); Serial.print(pin); Serial.print(" : "); Serial.println(*t);
}

void requestSensor(uint8_t pin){          // Отправка запроса на конвертацию ds18b20
  OneWire ds(pin);
  ds.reset();
  ds.skip();
  ds.write(0x44,0);
}

void searchSensors(){                          // Поиск датчиков на всех линиях
  ds1Qty =   src(ds1DS, ds1Pin);
}

uint8_t src(void * adr, uint8_t pin){      // Вспомогательная функция для поиска на одной шине. Возвращает количество найденных датчиков
  if (pin == 0) return 0;
  OneWire ds(pin);
  uint8_t newAddr[8]{0};
  uint8_t count {0};
  ds.reset_search();
  delay(5);
  while (ds.search(newAddr) && count <3){
    if (ds.crc8(newAddr, 7) == newAddr[7]){
       for (uint8_t i{0}; i<8; i++) *((uint8_t*)adr + count * 8 + i) = newAddr[i];
       count++;
    }
  }
  return count;
}

 

parrkof
Offline
Зарегистрирован: 18.04.2021

Благодарю за помощь 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Да, и я там накосячил слегка . Само собой, нужно в функции runYl() и runDht() в конец добавить сброс таймера вида: ms*** = millis();