Термостат с LCD на 5 датчиков
- Войдите на сайт для отправки комментариев
Всем привет!
Взял готовый код, все работает отлично. Но появилась необходимость изменить работу.
Экран с кнопками и цифровые датчики, каждый датчик привязан к своему выходу, пробую привязать к одному датчику пару выходов, но не выходит( как не извращался не хочет садится на один датчик несколько выходов.
#include
#include
#include
#include
OneWire oneWire(15); // A1 вход датчиков 18b20
DallasTemperature ds(&oneWire);
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
const byte OUT[5] = {2, 3, 11, 12, 13}; // номера выходов
byte pos;
byte tempOUTon[5]; // массив с температурой включения выхода
float tempSensor[5]; // массив куда читается температура
byte qty; // количество градусников на шине.
// адреса градусников.
DeviceAddress sensor1 = {0x28, 0xEE, 0x28, 0x3D, 0x1E, 0x16, 0x01, 0x91};
DeviceAddress sensor2 = {0x28, 0xEE, 0xBF, 0x75, 0x1E, 0x16, 0x01, 0x8B};
DeviceAddress sensor3 = {0x00, 0xEE, 0xBF, 0x75, 0x1E, 0x16, 0x01, 0x8B};
DeviceAddress sensor4 = {0x00, 0xEE, 0xBF, 0x75, 0x1E, 0x16, 0x01, 0x8B};
DeviceAddress sensor5 = {0x00, 0xEE, 0xBF, 0x75, 0x1E, 0x16, 0x01, 0x8B};
byte gradus[8] = {
0b00110,
0b01001,
0b01001,
0b00110,
0b00000,
0b00000,
0b00000,
0b00000
};
byte on[8] = {
0b00110,
0b01111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11110,
0b01100
};
void readSet(){
for (byte i = 0; i < qty; i++) tempOUTon[i] = EEPROM.read(i);
}
void outOff(){ // выключает выходы
for (byte i = 0; i < qty; i++) digitalWrite(OUT[i], LOW);
}
void erorr(){ // останавливает работу программы и сигнализирует ошибку
outOff(); // выключаем выходы
lcd.clear();
lcd.print("sensor error");
while(1){ // крутим бесконечный цикл
analogWrite(10, 100);
delay(500);
analogWrite(10, 255);
delay(500);
}
}
////
byte key(){ //// для кнопок ЛСДшилда
int val = analogRead(0);
if (val < 50) return 5;
else if (val < 150) return 3;
else if (val < 350) return 4;
else if (val < 500) return 2;
else if (val < 800) return 1;
else return 0;
}
////
void setMenu(byte pos){ // установка температуры
outOff();
lcd.clear();
while(1){ // крутим бесконечный цикл
byte KEY = key(); // читаем состояние кнопок
lcd.setCursor(2, 0); // выводим на экран
lcd.print("Out:");
lcd.print(pos+1);
lcd.setCursor(9, 0);
lcd.print("Pin:");
lcd.print(OUT[pos]);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" PinON: ");
lcd.print(tempOUTon[pos]);
lcd.write(1);
lcd.print("C <>");
if (KEY == 2) { // если нажата кнопка
tempOUTon[pos]--; // изменяем значение
if (tempOUTon[pos] > 125) tempOUTon[pos] = 0;
EEPROM.write(pos, tempOUTon[pos]); // сохраняем в еепром
}
else if (KEY == 5){
tempOUTon[pos]++;
if (tempOUTon[pos] > 125) tempOUTon[pos] = 0;
EEPROM.write(pos, tempOUTon[pos]);
}
delay(200);
}/////
}//
void getTemp(){ // читаем температуру и заполняем массив
ds.requestTemperatures();
tempSensor[0] = ds.getTempC(sensor1); // немного китайского кода
tempSensor[1] = ds.getTempC(sensor2);
tempSensor[2] = ds.getTempC(sensor3);
tempSensor[3] = ds.getTempC(sensor4);
tempSensor[4] = ds.getTempC(sensor5);
}
void sensorTest(){ // ищим датчики на шине, если количество изменилось, останавливаем работу
ds.begin();
if(ds.getDeviceCount() != qty) erorr();
}
void setup() {
// Serial.begin(9600);
ds.begin();
qty = ds.getDeviceCount(); // при включении, сохраняем количество градусников,
// можно и лучше количество указать руками.
for (int i = 0; i < qty; i++) pinMode(OUT[i], OUTPUT);
for (int i = 0; i < qty; i++) digitalWrite(OUT[i], LOW);
lcd.createChar(1, gradus);
lcd.createChar(2, on);
lcd.begin(16, 2);
lcd.clear();
readSet(); // читаем настройки из еепром
}
void loop() {
if (key() == 1) setMenu(pos); // если нажата селект, уходим в настройки
else if (key() == 4 && pos < qty-1) pos++; // крутим позицию
else if (key() == 3 && pos != 0) pos--;
sensorTest(); // тест наличия градусников на шине
getTemp(); // читаем температуру с датчиков
//// сверяем температуру и управляем выходами
for (int i = 0; i < qty; i++) {
if (tempSensor[i] < tempOUTon[i]) digitalWrite(OUT[i], HIGH);
else digitalWrite(OUT[i], LOW);
}
/////// вывод инфы на экран
lcd.setCursor(0, 0);
lcd.print(pos+1);
lcd.print(". ");
lcd.print(tempSensor[pos], 1); // показываем температуру с датчика
lcd.write(1);
lcd.print("C ");
lcd.setCursor(2, 1);
lcd.print(tempOUTon[pos]); // показываем установленную температуру
lcd.write(1);
lcd.print("C ");
lcd.setCursor(11, 0); // рисуем статус выхода
for (int i = 0; i < qty; i++){
if (digitalRead(OUT[i])) lcd.write(2);
else lcd.print(" ");
}
lcd.setCursor(11, 1); // рисуем номера выходов
for (int i = 0; i < qty; i++) lcd.print(i+1);
// delay(500); // необязательная задержка
}
В 127-130 строках измените способ обработки данных.
пробовал забивать один адрес на 2 сенсора и менял в киайском коде . не видит подмены почему то DeviceAddress sensor1 = {0x28, 0xEE, 0x28, 0x3D, 0x1E, 0x16, 0x01, 0x91}; DeviceAddress sensor2 = {0x28, 0xEE, 0x28, 0x3D, 0x1E, 0x16, 0x01, 0x91}; DeviceAddress sensor3 = {0x00, 0xEE, 0x41, 0x3E, 0x16, 0x16, 0x01, 0xDE}; DeviceAddress sensor4 = {0x00, 0xEE, 0x44, 0x77, 0x16, 0x16, 0x01, 0x7F}; DeviceAddress sensor5 = {0x00, 0xEE, 0x44, 0x77, 0x16, 0x16, 0x01, 0x7F}; и так пробовал tempSensor[0] = ds.getTempC(sensor1); // немного китайского кода tempSensor[1] = ds.getTempC(sensor1); tempSensor[2] = ds.getTempC(sensor3); tempSensor[3] = ds.getTempC(sensor4); tempSensor[4] = ds.getTempC(sensor5);For который отвечает за обработку данных переделайте на if-ы.
И пять датчиков теперь обязательно нужны?
переписать это , а нужно 2 датчика и 4 пина управлять.
//// сверяем температуру и управляем выходами for (int i = 0; i < qty; i++) { if (tempSensor[i] < tempOUTon[i]) digitalWrite(OUT[i], HIGH); else digitalWrite(OUT[i], LOW); } так? да? if tempSensor[0] < tempOUT[2] { digitalWrite(OUT[2], HIGH); else digitalWrite(OUT[2], LOW); if tempSensor[0] < tempOUT[3] { digitalWrite(OUT[3], HIGH); else digitalWrite(OUT[3], LOW);Примерно так
Уважаемый автор aleksey19ru проекта, просьба поподробнее расказать о своем проекте и откуда брали исходный код. Проект заинтересовал. Заранее благодарен.
Уважаемый автор aleksey19ru проекта, просьба поподробнее расказать о своем проекте и откуда брали исходный код. Проект заинтересовал. Заранее благодарен.
Для этого нужен чей то код? Читаете датчики, присваиваете значения переменным, проверяете if-ами, выполняте или не выполняете действия. Все.
Если датчиков много, чтобы лишние строки не плодить, чтение удобнее в for обернуть, ну а проверку смотря по обстоятельствам.
Чей то код взял потому как он под экран с кнопками, с этим пока туго только вникаю, без экрана написал тоже скетч
переписал маленько код и все работает, не стал пока убирать массивы.
вопрос далее в коде прописал где условие на if-ах строки ниже 160, хочу сделать управление нагревателем с тремя ТЕНами, с рандомом голову ломал, но не получается того что хочу
#include <EEPROM.h> #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> OneWire oneWire(55); // A1 вход датчиков 18b20 DallasTemperature ds(&oneWire); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); const int out1 =48; const int out2 =50; const int out3 =52; const byte OUT[5] = {2, 3, 11, 12, 13}; // номера выходов byte pos; byte tempOUTon[5]; // массив с температурой включения выхода float tempSensor[5]; // массив куда читается температура byte qty; // количество градусников на шине. // адреса градусников. DeviceAddress sensor1 = {0x28, 0xEE, 0x41, 0x3E, 0x16, 0x16, 0x01, 0xDE}; DeviceAddress sensor2 = {0x28, 0xEE, 0xBF, 0x75, 0x1E, 0x16, 0x01, 0x8B}; DeviceAddress sensor3 = {0x28, 0xEE, 0xBF, 0x75, 0x1E, 0x16, 0x01, 0x00}; DeviceAddress sensor4 = {0x28, 0xEE, 0x44, 0x77, 0x16, 0x16, 0x01, 0x00}; DeviceAddress sensor5 = {0x00, 0xEE, 0x44, 0x77, 0x16, 0x16, 0x00, 0x7F}; byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00110, 0b01111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11110, 0b01100 }; void readSet(){ for (byte i = 0; i < qty; i++) tempOUTon[i] = EEPROM.read(i); } void outOff(){ // выключает выходы for (byte i = 0; i < qty; i++) digitalWrite(OUT[i], LOW); } void erorr(){ // останавливает работу программы и сигнализирует ошибку outOff(); // выключаем выходы lcd.clear(); lcd.print("sensor error"); while(1){ // крутим бесконечный цикл analogWrite(10, 100); delay(500); analogWrite(10, 255); delay(500); } } //// byte key(){ //// для кнопок ЛСДшилда int val = analogRead(0); if (val < 50) return 5; else if (val < 150) return 3; else if (val < 350) return 4; else if (val < 500) return 2; else if (val < 800) return 1; else return 0; } //// void setMenu(byte pos){ // установка температуры outOff(); lcd.clear(); while(1){ // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок lcd.setCursor(2, 0); // выводим на экран lcd.print("Out:"); lcd.print(pos+1); lcd.setCursor(9, 0); lcd.print("Pin:"); lcd.print(OUT[pos]); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" PinON: "); lcd.print(tempOUTon[pos]); lcd.write(1); lcd.print("C <>"); if (KEY == 2) { // если нажата кнопка tempOUTon[pos]--; // изменяем значение if (tempOUTon[pos] > 125) tempOUTon[pos] = 0; EEPROM.write(pos, tempOUTon[pos]); // сохраняем в еепром } else if (KEY == 5){ tempOUTon[pos]++; if (tempOUTon[pos] > 125) tempOUTon[pos] = 0; EEPROM.write(pos, tempOUTon[pos]); } delay(200); }///// }// void getTemp(){ // читаем температуру и заполняем массив ds.requestTemperatures(); tempSensor[0] = ds.getTempC(sensor1); // немного китайского кода tempSensor[1] = ds.getTempC(sensor2); tempSensor[2] = ds.getTempC(sensor3); tempSensor[3] = ds.getTempC(sensor4); tempSensor[4] = ds.getTempC(sensor5); } void sensorTest(){ // ищим датчики на шине, если количество изменилось, останавливаем работу ds.begin(); if(ds.getDeviceCount() != qty) erorr(); } void setup() { pinMode(out1, OUTPUT); pinMode(out2, OUTPUT); pinMode(out3, OUTPUT); // Serial.begin(9600); ds.begin(); qty = ds.getDeviceCount(); // при включении, сохраняем количество градусников, // можно и лучше количество указать руками. for (int i = 0; i < qty; i++) pinMode(OUT[i], OUTPUT); for (int i = 0; i < qty; i++) digitalWrite(OUT[i], LOW); lcd.createChar(1, gradus); lcd.createChar(2, on); lcd.begin(16, 2); lcd.clear(); readSet(); // читаем настройки из еепром } void loop() { if (key() == 1) setMenu(pos); // если нажата селект, уходим в настройки else if (key() == 4 && pos < qty-1) pos++; // крутим позицию else if (key() == 3 && pos != 0) pos--; sensorTest(); // тест наличия градусников на шине getTemp(); // читаем температуру с датчиков //// сверяем температуру и управляем выходами if (tempSensor[0] < (tempOUTon[0] - 4)) { // тут считываем температуру и если она меньше заданой на 4 град то включаем 3 пина digitalWrite(out1, HIGH); digitalWrite(out2, HIGH); digitalWrite(out3, HIGH); } if (((tempOUTon[0] - 4) < tempSensor[0]) && (tempSensor[0] < (tempOUTon[0] - 2))) { digitalWrite(out1, HIGH); // тут считываем температуру и если она меньше заданой на 4 град и меньше на 2 град, то включаем 2 пина и вот тут хотелось бы сделать чтобы случайным образом выбирались два из трех пинов, для того чтобы был меньше износ нагрузки digitalWrite(out2, HIGH); digitalWrite(out3, LOW); } if (((tempOUTon[0] - 2) < tempSensor[0]) && (tempSensor[0] < tempOUTon[0])) { digitalWrite(out1, LOW); // тут считываем температуру и если она меньше заданой на 2 град и меньше заданой, то включаем 1 пина и вот тут хотелось бы сделать чтобы случайным образом выбирался один из трех пинов, цель та же.... digitalWrite(out2, LOW); digitalWrite(out3, HIGH); } if (tempSensor[0] > tempOUTon[0]) { digitalWrite(out1, LOW); // тут считываем температуру и если она больше заданой то все выключаем digitalWrite(out2, LOW); digitalWrite(out3, LOW); } /////// вывод инфы на экран lcd.setCursor(0, 0); lcd.print(pos+1); lcd.print(". "); lcd.print(tempSensor[pos], 1); // показываем температуру с датчика lcd.write(1); lcd.print("C "); lcd.setCursor(2, 1); lcd.print(tempOUTon[pos]); // показываем установленную температуру lcd.write(1); lcd.print("C "); lcd.setCursor(11, 0); // рисуем статус выхода for (int i = 0; i < qty; i++){ if (digitalRead(OUT[i])) lcd.write(2); else lcd.print(" "); } lcd.setCursor(11, 1); // рисуем номера выходов for (int i = 0; i < qty; i++) lcd.print(i+1); // delay(500); // необязательная задержка }aleksey19ru, а рандом то зачем? Для снижения максимума тока на холодном лучше диммер прикрутить, чтобы плавно выводил, а дальше уже и мощностью рулить сможете.
Вы не поняли. Будет подключаться 3 тены, и чтобы количество часов работы всех тен уровнять между собой хоть немного... для этого и рандом включения на режимах где одна или две тены всего работают.
Понял изначально, только снижение подаваемой мощности увеличивает ресурс в геометрической прогрессии.
Дело конечно Ваше. Можете стандартную функцию использовать или к миллис привязаться и прописать зависимость, либо в епром записывать время работы каждого (условно по 10 минут.) При круглосуточной работе одной ячейки хватит на 2 года (по даташиту), а скорее лет на 20-30.