Термостат на мега 2560 + DS18B20
- Войдите на сайт для отправки комментариев
Пт, 25/01/2019 - 18:13
Прошу помощи в небольшой переделке кода по этой теме:
http://arduinolab.pw/index.php/2015/12/02/termostat-na-arduino-do-5-datc...
Там 4 датчика и 4 реле. Надо 1 датчик и 4шт реле. И если возможно - устранить дребезг
контактов реле на выходе. Цель: по одной и той же температуре управлять двумя устройствами:
1е реле - открыть шиберную заслонку по своей t
2е реле - закрыть шиберную заслонку по своей t
3е реле - пуск вентилятора по своей t
4е реле - стоп вентилятора по своей t.
Так я хочу управлять температурой воздуха в компрессорной круглогодично.
Прописал на каждом канале один и тот же адрес датчика, но в итоге показывает
lcd шилд мне только один канал..Код, мною измененный немного:
// Термостат, до пяти датчиков DS18B20.
//
// v 0.2.1 beta
#include <EEPROM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
OneWire oneWire(63); // A9 вход датчиков 18b20
DallasTemperature ds(&oneWire);
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // пины lcd мега 2560
const byte OUT[4] = {3, 11, 12, 13}; // используем эти номера выходов платы мега 2560
byte pos;
byte tempOUTon[4]; // массив с температурой включения выхода
float tempSensor[4]; // массив куда читается температура
byte qty; // количество градусников на шине.
// адреса градусников:
DeviceAddress sensor1 = {0x28, 0xFF, 0x0B, 0xD2, 0x90, 0x16, 0x04, 0x31};
DeviceAddress sensor2 = {0x28, 0xFF, 0x0B, 0xD2, 0x90, 0x16, 0x04, 0x31};
DeviceAddress sensor3 = {0x28, 0xFF, 0x0B, 0xD2, 0x90, 0x16, 0x04, 0x31};
DeviceAddress sensor4 = {0x28, 0xFF, 0x0B, 0xD2, 0x90, 0x16, 0x04, 0x31};
//один и тот же градусник для управления выходами № 3, 11, 12, 13 - изменил
//DeviceAddress sensor5 = {0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
//отсутствует 5й градусник
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); // было HIGH изменил
}
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); //LOW было, изменил
else digitalWrite(OUT[i], LOW); //HIGH было, изменил
}
/////// вывод инфы на экран ////////
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); // ввел для попытки устранения дребезга контактов реле
}
Странно - подключаю все 4 датчика - появляются все 4 канала управления реле..
Чистка EEPROM не помогает
Прошу помощи в небольшой переделке кода по этой теме:
http://arduinolab.pw/index.php/2015/12/02/termostat-na-arduino-do-5-datc...
А почему просите здесь, а не в той теме?
Уважаемый, вставьте программу по правилам, а то оч трудно ссылаться на строки с Вашими косяками
Уважаемый, вставьте программу по правилам, а то оч трудно ссылаться на строки с Вашими косяками
Извиняюсь. Код интересен мне тем, что позволяет посмотреть (пролистать) на LCD шилде уставку по каждому каналу и состояние каналов (вкл - выкл)
Вот, сегодня сделал из этого кода что мне надо (добавил два канала), но! я не понимаю как сделать прокрутку чтобы глянуть можно было состояние каждого канала (уставку, включено-выключено). На шилде помещаются только два канала.. Вот мой код:
Уважаемый, замените все Ваши конструкции if - ele if по отношению к кнопкам на switch - case. У Вас может быть только одно значение кнопки и программа станет читаеемей. Далее - я бы посоветовал считывать кнопки по отпусканию - избежите кучу ошибок по дребезгу. А прокрутка - почитайте описание библиотеки LiquidCrystal.h
Уважаемый, замените все Ваши конструкции if - ele if по отношению к кнопкам на switch - case. У Вас может быть только одно значение кнопки и программа станет читаеемей. Далее - я бы посоветовал считывать кнопки по отпусканию - избежите кучу ошибок по дребезгу. А прокрутка - почитайте описание библиотеки LiquidCrystal.h
Спасибо за подсказки, добрый человек)
Далее - я бы посоветовал считывать кнопки по отпусканию - избежите кучу ошибок по дребезгу.
Правильно ли я понимаю, что attachInterrupt на FALLING лучше борется с дребезгом, чем attachInterrupt на RISING?
наверно вопрос скорее в том, доверяете вы своему прерыванию или нет.
Доверяете тут в том смысле, насколько вероятен его старт по помехе, не нажатию, а именно внешней помехе.