Вывод на экран 2004

plymba
Offline
Зарегистрирован: 20.04.2016

Приветствую, уважаемые! Пишу скетч для управления отоплением, солнечными коллекторами, рекуператором, индикацией температур и пр. 

Сейчас дело притормозилось из-за отсутствия знаний по выводу инфы на экран I2C 2004. Промлема в том, что нужно сделать несколько экранов, которые можно было бы пролистывать энкодером.

Как на Андройде, короче):

на главном экране температура и влажность дома и за бортом

на другом показания водо-воздушного коллектора

на третьем отопление

на четвёртом воздушные коллекторы

Один экран то я могу сделать, а вот с несколькими проблема. Подскажите, где почитать инфу о том как это сделать? Ну или может пример кто сможет скинуть?

 

James
Offline
Зарегистрирован: 26.02.2016

делаешь 4 разных, switch case, листаешь энкодером или гугли по форуму "меню"

plymba
Offline
Зарегистрирован: 20.04.2016

а как гуглить по форуму? справа вверху гугл поиск только

James
Offline
Зарегистрирован: 26.02.2016

пробуй, все получится

MacSim
Offline
Зарегистрирован: 28.11.2012

введи переменную состояния экрана. меняй ее энкодером. проверяй и выводи то, что нужно в зависимости от значения.

plymba
Offline
Зарегистрирован: 20.04.2016

сделал так, но где-то ошибка. пока не могу понять где именно
 



// Контроллер солнечного отопления подпола на датчиках DS18B20.
//  


#include <EEPROM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <stDHT.h>
#include <Encoder.h>
#include <LiquidCrystal_I2C.h>
#define TEMPERATURE_PRECISION 12
DHT sens(DHT22); // Указать датчик DHT11, DHT21, DHT22
LiquidCrystal_I2C lcd(39,20,4);  // установка адреса дисплея
OneWire  oneWire(A0); // A0 вход датчиков 18b20
DallasTemperature ds(&oneWire);

//________________Энкодер________________
#define PIN_ENCODER_CLK 2
#define PIN_ENCODER_DT 3
#define PIN_ENCODER_SW 24
Encoder myEnc( PIN_ENCODER_DT, PIN_ENCODER_CLK );
long oldPosition = 0;

//________________Для меню____________________

int m=0; //переменная для экранов меню
int p1=0; // переменная для примера 1
int p2=0; // -//- 2
int p3=0; // -//- 3

//________________Установки температур____________________

int BoilerMaxTemp = 55; // Установка максимальной температуры на бойлере
int WAcollPumpTemp = 5; // Установка разницы температур между коллектором и ёмкостью преднагрева, при которой начнёт работать насос Водо-воздушного коллектора
int RoofBoilerMaxTemp = 50; // Установка максимальной температуры, до которой будет работать насос Водо-воздушного коллектора и греть воду в ёмкости преднагрева
int WAcollFanTemp = 30; // Установка температуры, при которой будет работать вентилятор Водо-воздушного коллектора в режиме сброса излишек тепла
int AirColl_1FanTemp = 30; // Установка температуры, при которой будет работать вентилятор воздушного коллектора 1
int AirColl_2FanTemp = 30; // Установка температуры, при которой будет работать вентилятор воздушного коллектора 2
boolean BoilerStatus = false; //Статус ТЭНа. true - включено, false - выключено 
boolean WAcollStatus = false; //Статус вентилятора Водо-воздушного коллектора. true - включено, false - выключено 
boolean AirColl_1Status = false; //Статус вентилятора воздушного коллектора 1. true - включено, false - выключено
boolean AirColl_2Status = false; //Статус вентилятора воздушного коллектора 2. true - включено, false - выключено
int tempC;
//_______________Чтение температур_______________________

int  Temp_BoilerC   = 20;  // Переменная. Чтение с датчика бойлера
int  Temp_WAcollC = 20;  // Переменная. Чтение с датчика Водо-воздушного коллектора
int  Temp_WAcollINC = 20; // Переменная. Чтение с датчика температуры вхядящего теплоносителя Водо-воздушного коллектора
int  Temp_WAcollOUTC = 20; // Переменная. Чтение с датчика температуры вЫхядящего теплоносителя Водо-воздушного коллектора
int  Temp_AirColl_1C = 20;  // Переменная. Чтение с датчика воздушного коллектора 1
int  Temp_AirColl_2C = 20;  // Переменная. Чтение с датчика воздушного коллектора 2
int  Temp_RoofBoilerC   = 20;  // Переменная. Чтение с датчика бойлера преднагрева (крыша)
int  TempBoilerC   = 20;  // Переменная. Итоговая температура с датчика бойлера
int  TempWAcollC = 20;  // Переменная. Итоговая температура воздуха Водо-воздушного коллектора
int  TempWAcollINC = 20; // Переменная. Итоговая температура вхядящего теплоносителя Водо-воздушного коллектора
int  TempWAcollOUTC = 20; // Переменная. Итоговая температура температуры вЫхядящего теплоносителя Водо-воздушного коллектора
int  TempAirColl_1C = 20;  // Переменная. Итоговая температура с датчика воздушного коллектора 1
int  TempAirColl_2C = 20;  // Переменная. Итоговая температура с датчика воздушного коллектора 2
int  TempRoofBoilerC   = 20;  // Переменная. Итоговая температура с датчика бойлера преднагрева (крыша)

//_______________Счётчики ошибок_________________________
int dsBshet=0;         // Подсчет кол-ва ошибок DS18B20 на бойлере
int dsWAshet=0;         // Подсчет кол-ва ошибок DS18B20 на Водо-воздушном коллекторе
int dsWA_INshet=0;         // Подсчет кол-ва ошибок DS18B20 на Водо-воздушном коллекторе
int dsWA_OUTshet=0;         // Подсчет кол-ва ошибок DS18B20 на Водо-воздушном коллекторе
int dsA1shet=0;         // Подсчет кол-ва ошибок DS18B20 на коллекторе 1
int dsA2shet=0;         // Подсчет кол-ва ошибок DS18B20 на коллекторе 2
int dsRshet=0;         // Подсчет кол-ва ошибок DS18B20 на бойлере преднагрева
int dsshet=0;         // Подсчет общего кол-ва ошибок DS18B20 


int WAcollEfficiency; // значение мощности водяного контура коллектора
int PumpPerformance = 15; // Фактический расход воды в контуре коллектора (л/мин)
byte pos;
byte tempOUTon[5];  // массив с температурой включения выхода
float tempSensor[5]; // массив куда читается температура
byte qty; // количество градусников на шине.

//__________________Назначаем выходы________________________________
int KotelThermostatpin = 48; // назначаем пин управления термостатом Котла отопления
int KotelPumppin = 47; // назначаем пин управления насоса Котла отопления
int boilerpin = 49; // назначаем пин управления бойлером
int WAcollPumppin = 50; // назначаем пин управления Водо-воздушным коллектором (насос)
int WAcollFanpin = 51; // назначаем пин управления Водо-воздушным коллектором (вентилятор)
int AirColl_1pin = 52; // назначаем пин управления воздушным коллектором 1 (вентилятор)
int AirColl_2pin = 53; // назначаем пин управления воздушным коллектором 2 (вентилятор)


// адреса градусников.

DeviceAddress BoilerSensor = {0x28, 0x18, 0xC0, 0xB4, 0x06, 0x00, 0x00, 0x88}; // датчик Бойлера
DeviceAddress WAcollSensor = {0x28, 0xB4, 0x61, 0x88, 0x06, 0x00, 0x00, 0x0D}; // датчик температуры воздуха Водо-воздушного коллектора
DeviceAddress WAcollSensorIN = {0x28, 0xB4, 0x61, 0x88, 0x06, 0x00, 0x00, 0x0D}; // датчик температуры вхядящего теплоносителя Водо-воздушного коллектора
DeviceAddress WAcollSensorOUT = {0x28, 0xB4, 0x61, 0x88, 0x06, 0x00, 0x00, 0x0D}; // датчик температуры вЫхядящего теплоносителя Водо-воздушного коллектора
DeviceAddress AirColl_1Sensor = {0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // датчик температуры воздуха воздушного коллектора 1
DeviceAddress AirColl_2Sensor = {0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // датчик температуры воздуха воздушного коллектора 1
DeviceAddress RoofBoilerSensor = {0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // датчик температуры Бойлера преднагрева

byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};
byte on[8] = {
  0b00110,
  0b01111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11110,
  0b01100
};

          
void erorr(){ // останавливает работу программы и сигнализирует ошибку
    
  lcd.clear();
  lcd.print("sensor error");
   while(1){ // крутим бесконечный цикл
      analogWrite(10, 100);
      delay(500);
      analogWrite(10, 255);
      delay(500);
  }
}

void getTemp(){ // читаем температуру и заполняем массив
   ds.requestTemperatures();  
   
        
   Temp_BoilerC    = ds.getTempC(BoilerSensor);    // Считываем температуру с бойлера
     if(-55 < Temp_BoilerC && Temp_BoilerC < 120){TempBoilerC = Temp_BoilerC ;} delay(50);// Если нет ошибки, то обновляем температуру
   Temp_WAcollC    = ds.getTempC(WAcollSensor);    // Считываем температуру с Водо-воздушного коллектора
     if(-55 < Temp_WAcollC && Temp_WAcollC < 120){TempWAcollC = Temp_WAcollC;} delay(50);// Если нет ошибки, то обновляем температуру
   Temp_WAcollINC    = ds.getTempC(WAcollSensorIN);    // Считываем температуру с входящего теплоносителя Водо-воздушного коллектора
     if(-55 < Temp_WAcollINC && Temp_WAcollINC < 120){TempWAcollINC = Temp_WAcollINC;} delay(50);// Если нет ошибки, то обновляем температуру
   Temp_WAcollOUTC    = ds.getTempC(WAcollSensorOUT);    // Считываем температуру с вЫходящего теплоносителя Водо-воздушного коллектора
     if(-55 < Temp_WAcollOUTC && Temp_WAcollOUTC < 120){TempWAcollOUTC = Temp_WAcollOUTC;} delay(50);// Если нет ошибки, то обновляем температуру
   Temp_AirColl_1C    = ds.getTempC(AirColl_1Sensor);    // Считываем температуру с воздушного коллектора 1
     if(-55 < Temp_AirColl_1C && Temp_AirColl_1C < 120){TempAirColl_1C = Temp_AirColl_1C;} delay(50);// Если нет ошибки, то обновляем температуру
   Temp_AirColl_2C    = ds.getTempC(AirColl_2Sensor);    // Считываем температуру с воздушного коллектора 2
     if(-55 < Temp_AirColl_2C && Temp_AirColl_2C < 120){TempAirColl_2C = Temp_AirColl_2C;} delay(50);// Если нет ошибки, то обновляем температуру
   Temp_RoofBoilerC    = ds.getTempC(RoofBoilerSensor);    // Считываем температуру с бойлера преднагрева
     if(-55 < Temp_RoofBoilerC && Temp_RoofBoilerC < 120){TempRoofBoilerC = Temp_RoofBoilerC;} delay(50);// Если нет ошибки, то обновляем температуру

     if(   Temp_BoilerC < -55 && Temp_BoilerC > 120)   {dsshet++; dsBshet++; } // +1 к счетчикам ошибок
     if(   Temp_WAcollC < -55 && Temp_WAcollC > 120)   {dsshet++; dsWAshet++; } // +1 к счетчикам ошибок
     if(   Temp_WAcollINC < -55 && Temp_WAcollINC > 120)   {dsshet++; dsWA_INshet++; } // +1 к счетчикам ошибок
     if(   Temp_WAcollOUTC < -55 && Temp_WAcollOUTC > 120)   {dsshet++; dsWA_OUTshet++; } // +1 к счетчикам ошибок
     if(   Temp_AirColl_1C < -55 && Temp_AirColl_1C > 120)   {dsshet++; dsA1shet++; } // +1 к счетчикам ошибок
     if(   Temp_AirColl_2C < -55 && Temp_AirColl_2C > 120)   {dsshet++; dsA2shet++; } // +1 к счетчикам ошибок
     if(   Temp_RoofBoilerC < -55 && Temp_RoofBoilerC > 120)   {dsshet++; dsRshet++; } // +1 к счетчикам ошибок
} 


void sensorTest(){  // ищим датчики на шине, если количество изменилось, останавливаем работу
   ds.begin();
   if(ds.getDeviceCount() != qty) erorr();
}

  

void setup() {
 //  Serial.begin(9600);
  Wire.begin();
  lcd.begin(39,20,4); 
  ds.begin();  
  
// Назначаем пины датчиков влажности 
  pinMode(22, INPUT);
  digitalWrite(22, HIGH);
  pinMode(23, INPUT);
  digitalWrite(23, HIGH);

// Назначаем пины выходных сигналов  
  pinMode(boilerpin, OUTPUT); // Выход на реле бойлера
  pinMode(WAcollPumppin, OUTPUT); // Выход на реле управления Водо-воздушным коллектором (насос)
  pinMode(WAcollFanpin, OUTPUT); // Выход на реле управления Водо-воздушным коллектором (вентилятор)
  pinMode(AirColl_1pin, OUTPUT); // Выход на реле управления воздушного коллектора 1
  pinMode(AirColl_2pin, OUTPUT); // Выход на реле управления воздушного коллектора 2



  
  qty = ds.getDeviceCount(); // при включении, сохраняем количество градусников, 
                             // можно и лучше количество указать руками. 
  
  lcd.createChar(1, gradus);
  lcd.createChar(2, on);
  lcd.clear();
  lcd.init();                   // initialize the lcd 
  lcd.backlight();
 
   
}

void loop() 
{   

  long newPosition = myEnc.read() / 4;
  sensorTest(); // тест наличия градусников на шине
  getTemp(); // читаем температуру с датчиков  
  
  //// Управление бойлером
  
  if(TempBoilerC<BoilerMaxTemp) digitalWrite(boilerpin,HIGH);
  if (dsBshet >2) digitalWrite(boilerpin,LOW); // Если нет связи с датчиком температуры отключить бойлер
  else digitalWrite(boilerpin,LOW);
  if (digitalRead(boilerpin)==LOW) {BoilerStatus=false;} // Присваиваем статус работы бойлера (вкл / выкл)
  else {BoilerStatus=true;}

 //// Управление Водо-воздушным коллектором
  
  if(TempWAcollC>25) digitalWrite(WAcollFanpin,HIGH);
  if (dsWAshet >2) digitalWrite(WAcollFanpin,LOW); // Если нет связи с датчиком температуры отключить вентилятор
  else digitalWrite(WAcollFanpin,LOW);
  if (digitalRead(WAcollFanpin)==LOW) {WAcollStatus=false;} // Присваиваем статус работы вентилятора коллектора (вкл / выкл)
  else {WAcollStatus=true;}
  
  int WAcollEfficiency = (4200*(PumpPerformance/60)*(TempWAcollOUTC-TempWAcollINC)/1000);

 //// Управление воздушными коллекторами
  
  if(TempAirColl_1C>25) digitalWrite(AirColl_1pin,HIGH);
  if (dsA1shet >2) digitalWrite(AirColl_1pin,LOW); // Если нет связи с датчиком температуры отключить вентилятор
  else digitalWrite(AirColl_1pin,LOW);
  if (digitalRead(AirColl_1pin)==LOW) {AirColl_1Status=false;} // Присваиваем статус работы вентилятора коллектора (вкл / выкл)
  else {AirColl_1Status=true;}

  if(TempAirColl_2C>25) digitalWrite(AirColl_2pin,HIGH);
  if (dsA2shet >2) digitalWrite(AirColl_2pin,LOW); // Если нет связи с датчиком температуры отключить вентилятор
  else digitalWrite(AirColl_2pin,LOW);
  if (digitalRead(AirColl_2pin)==LOW) {AirColl_2Status=false;} // Присваиваем статус работы вентилятора коллектора (вкл / выкл)
  else {AirColl_2Status=true;}
  

 // Работа датчиков DHT22
    
  int t = sens.readTemperature(22); // чтение датчика на пине 22
  int h = sens.readHumidity(22);    // чтение датчика на пине 22
  delay(2000);
  
  int t2 = sens.readTemperature(23); // чтение датчика на пине 23
  int h2 = sens.readHumidity(23);    // чтение датчика на пине 23
  
  delay(2000);

  //Обработка энкодера вперед
  if (newPosition > oldPosition)
  {
  m++;//увеличиваем переменную уровня меню
  if (m>3)//если уровень больше 3
  {
  m=0;// то вернуться к началу
  }
  delay (100);
  lcd.clear();
  }
  //Обработка энкодера назад
  if (newPosition < oldPosition)
  {
  m--;
  if (m<0)
  {
  m=3;
  }
  delay (100);
  lcd.clear();
  }
  
  //сдесь код для уменьшения значений
  //аналогичен коду увеличения


 
  

  /////// Основной экран 
  switch (m){
        case 0:
  lcd.setCursor(0, 0);
  lcd.print(" HOME");
  lcd.setCursor(14, 0);
  lcd.print("OUT ");
  lcd.setCursor(0, 1);
  lcd.print(t);
  lcd.write(1);
  lcd.setCursor(5, 1);
  lcd.print("Temperature");
  lcd.setCursor(17, 1);
  lcd.print(t2);
  lcd.write(1);
  lcd.setCursor(0, 2);
  lcd.print(h);
  lcd.print("%");
  lcd.setCursor(6, 2);
  lcd.print("Humidity");
  lcd.setCursor(17, 2);
  lcd.print(h2);
  lcd.print("%");
  
  /////// Экран Водо-воздушного коллектора  
  case 1: 
  lcd.setCursor(0, 0);
  lcd.print("Air/water collector");
  lcd.setCursor(0, 1);
  lcd.print("Air: "); 
  lcd.print(TempWAcollC); 
  lcd.write(1); 
  lcd.print(" Fan:"); 
  lcd.setCursor(19, 1);  // рисуем статус вентилятора 
    { 
      if (WAcollStatus=true) lcd.write(2);
      else lcd.print(" ");
    }
  lcd.setCursor(0, 2); 
  lcd.print("In: ");
  lcd.print(TempWAcollINC);
  lcd.write(1);
  lcd.print("Out: ");
  lcd.print(TempWAcollOUTC);
  lcd.write(1);
  lcd.setCursor(3, 3);
  lcd.print("Power: ");
  lcd.print(WAcollEfficiency);
  lcd.print("kWt");
  


  
  
  /////// Экран Бойлера
  case 2: 
  lcd.setCursor(6, 0); 
  lcd.print("Boiler"); 
  lcd.setCursor(0, 2); 
  lcd.print("Temp:"); 
  lcd.print(TempBoilerC, 1);  // показываем температуру с датчика бойлера
  lcd.write(1);  
  
  lcd.setCursor(0, 3); 
  lcd.print("TEN status:");
   // рисуем статус выхода  
    { 
      if(tempSensor[0]>tempSensor[1] && tempSensor[0]>25) lcd.write(2);
      else if(tempSensor[0]<20 || tempSensor[0]<tempSensor[1]) lcd.print(" ");
      
}
}
} 
 

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

plymba пишет:

сделал так, но где-то ошибка. пока не могу понять где именно

Спросите у компелятора, он Вам и номер строки выдаст, и даже номер символа. Если Вы с ним на разных языках говорите то скиньте сюда ошибку, тут переводчиков много

plymba
Offline
Зарегистрирован: 20.04.2016

Ошибок не выдает, всё дело в самой работе.

1. На экране вместо слов отображается только первая буква

2. При повороте энкодера на 1,2 или 3 щелчка ничего не происходит. а если больше пролистнуть, то начинает просто крутить менюшки без остановки..

3. почему-то подаёт HIGHT на пины с 49 по 53

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

plymba пишет:
На экране вместо слов отображается только первая буква

Plymba, проблема много раз обсасывалась, например здесь.

phoenixoid
Offline
Зарегистрирован: 14.07.2015

А oldPosition у Вас обновляется?

if(newPosition > oldPosition){

oldPosition=newPosition;

И делаем еще что-то

}