Термостат на нескольких датчиках DS18B20
- Войдите на сайт для отправки комментариев
Ср, 26/07/2017 - 18:53
пытаюсь соорудить сабж. Пробежался по форуму и как то не очень я понимаю смысл используемых алгоритмов.
Скажите правильно ли я делаю?
Вопрос еще и к тому что временами это вдруг перестает работать. Температура выше порога включения, а реле не встаёт под ток. А флажки "X" и "Y" на каждом круге оба увеличиваются на 1.
if (cooler == false) // включение кулера
{
if (tmp_bp1 > tmp_max || tmp_bp2 > tmp_max || tmp_dc1 > tmp_max || tmp_dc2 > tmp_max || tmp_r1 > tmp_max || tmp_r2 > tmp_max || tmp_r3 > tmp_max)
{
cooler = true;
digitalWrite(cooler_pin, HIGH); //включить кулер
x = x + 1;
}
}
if (cooler == true) // выключение кулера
{
if (tmp_bp1 < tmp_min && tmp_bp2 < tmp_min && tmp_dc1 < tmp_min && tmp_dc2 < tmp_min && tmp_r1 < tmp_min && tmp_r2 < tmp_min && tmp_r3 < tmp_min)
{
cooler = false;
digitalWrite(cooler_pin, LOW); //выключить кулер
y = y + 1;
}
}
Все верно, увеличиваются, только не на каждом круге от
coolerзависит. И от той мути после if. А изредка и резко уменшатся. А чего Вы хотели то?А флажки "X" и "Y" на каждом круге оба увеличиваются на 1.
если, к примеру, tmp_min>tmp_max - то это нормально. Но отсюда невидать :(
Все верно, увеличиваются, только не на каждом круге
в том то и дело что на каждом ... т.е. это когда глючит. А так да ... включилось реле - вырос Х, выключилось - вырос Y. Я их для этого и воткнул - чтобы следить выполнилось условие или нет.
coolerзависитэээ ... ну да, зависит .. от предыдущего состояния, если выключен, то проверяю только на включение и наоборот
:) про неё и вопрос ... если хоть одна температура выше верхнего предела - включается кулер. А выключается когда все температуры снижаются за нижний предел.
эт Вы про температуры с датчиков? резко они никуда не скачат, я ж в порту (порте) за ними смотрю
эт вопрос риторический? :) хотел бы что б "работало" :)
если, к примеру, tmp_min>tmp_max - то это нормально. Но отсюда невидать :(
диапазон конечно маленький ... но это на время отладки, чтобы от тепла рук срабатывало. от комнатных 27град до 33 срабатывания датчик греется секунд 5. температура растет плавно
Опять же - это происходит не всегда и не сразу ... работает - работает вдруг раз и перестало ... вот Этими фражками увидел такое ... почему так происходит я не пойму
и ладно бы клацало реле - ведь попав в первое условие, к Х - оно должно включится, и тут же выключится раз и Y увеличился. А оно же не клацает
Ну, для начала хотелось бы увидеть скетч целиком. И почти наверняка придётся посмотреть и на схему.
Forvad, я бы посоветовал все температуры собрать в массив и проверять выход за границу в цикле. Это позволит избежать этих безумных IF, что у вас в скетче, да и код будет куда удобнее модернизировать и поддерживать.
Ну, для начала хотелось бы увидеть скетч целиком. И почти наверняка придётся посмотреть и на схему.
а схема, схема по скетчу. собрана пока на сенсор-шилде.
на А4\А5 экран , на D2 - гирлянда датчиков, на D8 - релюшка
/* * блок питания v. 0.1 * */ #include <OneWire.h> #include <DallasTemperature.h> #include "ASOLED.h" OneWire oneWire(2); // вход датчиков 18b20 DallasTemperature ds(&oneWire); DeviceAddress ard_bp1 = {0x28, 0xFF, 0xC1, 0x8B, 0x01, 0x17, 0x03, 0x21}; DeviceAddress ard_bp2 = {0x28, 0xFF, 0x23, 0x93, 0x01, 0x17, 0x03, 0x5C}; DeviceAddress ard_dc1 = {0x28, 0xFF, 0x94, 0x99, 0x01, 0x17, 0x03, 0x59}; DeviceAddress ard_dc2 = {0x28, 0xFF, 0xE4, 0x08, 0x02, 0x17, 0x04, 0x3D}; DeviceAddress ard_r1 = {0x28, 0xFF, 0x1D, 0x98, 0x01, 0x17, 0x03, 0xEE}; DeviceAddress ard_r2 = {0x28, 0xFF, 0x52, 0xA4, 0x01, 0x17, 0x05, 0xEF}; DeviceAddress ard_r3 = {0x28, 0xFF, 0xA0, 0xDD, 0x01, 0x17, 0x04, 0xAF}; float tmp_bp1 = 0; float tmp_bp2 = 0; float tmp_dc1 = 0; float tmp_dc2 = 0; float tmp_r1 = 0; float tmp_r2 = 0; float tmp_r3 = 0; byte buzz_gnd=4; //динамик земля byte buzz_pin=5; //динамик сигнал byte cooler_pin = 8; //пин реле включения кулера unsigned long prevMillis; unsigned long testStart; boolean cooler = false; //флаг работы кулера float tmp_min = 30.0; float tmp_max = 33.0; int x = 0; int y = 0; void setup() { Serial.begin(115200); ds.begin(); pinMode(buzz_pin, OUTPUT); //пищалка pinMode(buzz_gnd, OUTPUT); //пищалка digitalWrite(buzz_gnd, 0); LD.init(); //иниц OLED диспл LD.clearDisplay(); testStart = millis(); //время начала теста в системе отсчёта ардуины prevMillis = millis(); //время первого шага pinMode(cooler_pin, OUTPUT); //пин реле как выход digitalWrite(cooler_pin, LOW); //обесточить реле, выключить кулер Serial.println("BP1 BP2 DC1 DC2 R1 R2 R3 Cool X Y"); } void sendData() // данные в порт { Serial.print(tmp_bp1, 1); Serial.print(" "); Serial.print(tmp_bp2, 1); Serial.print(" "); Serial.print(tmp_dc1, 1); Serial.print(" "); Serial.print(tmp_dc2, 1); Serial.print(" "); Serial.print(tmp_r1, 1); Serial.print(" "); Serial.print(tmp_r2, 1); Serial.print(" "); Serial.print(tmp_r3, 1); Serial.print(" "); Serial.print(cooler); Serial.print(" "); Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.println(millis()); } void DispPrint() //отображения данных на экране { // первая строка LD.printString_12x16(""); LD.printNumber((long)tmp_bp1, 0, 0); // переменная, столбец, строка LD.printString_6x8(" "); LD.printString_12x16(""); LD.printNumber((long)tmp_bp2); // переменная, столбец, строка LD.printString_6x8(" "); LD.printString_12x16(""); LD.printNumber((long)tmp_dc1); // переменная, столбец, строка LD.printString_6x8(" "); LD.printString_12x16(""); LD.printNumber((long)tmp_dc2); // переменная, столбец, строка // вторая строка LD.printString_12x16(""); LD.printNumber((long)tmp_r1, 0, 2); // переменная, столбец, строка LD.printNumber((long)tmp_r2, 45, 2); // переменная, столбец, строка LD.printNumber((long)tmp_r3, 90, 2); // переменная, столбец, строка } void loop() { ds.requestTemperatures(); // считываем температуру с датчиков tmp_bp1 = ds.getTempC(ard_bp1); tmp_bp2 = ds.getTempC(ard_bp2); tmp_dc1 = ds.getTempC(ard_dc1); tmp_dc2 = ds.getTempC(ard_dc2); tmp_r1 = ds.getTempC(ard_r1); tmp_r2 = ds.getTempC(ard_r2); tmp_r3 = ds.getTempC(ard_r3); sendData(); // отправка данных DispPrint(); if (cooler == false) // включение кулера { if (tmp_bp1 > tmp_max || tmp_bp2 > tmp_max || tmp_dc1 > tmp_max || tmp_dc2 > tmp_max || tmp_r1 > tmp_max || tmp_r2 > tmp_max || tmp_r3 > tmp_max) { cooler = true; digitalWrite(cooler_pin, HIGH); //включить кулер x = x + 1; } } if (cooler == true) // выключение кулера { if (tmp_bp1 < tmp_min && tmp_bp2 < tmp_min && tmp_dc1 < tmp_min && tmp_dc2 < tmp_min && tmp_r1 < tmp_min && tmp_r2 < tmp_min && tmp_r3 < tmp_min) { cooler = false; digitalWrite(cooler_pin, LOW); //выключить кулер y = y + 1; } } }ой жуть. Вам не надоело писать одно и то же по 7 раз? Программирование - хобби ленивых, используйте циклы и массивы, скетч станет короче раза в четыре. думаю. И ошибки станет искать легче.
Forvad, я бы посоветовал все температуры собрать в массив и проверять выход за границу в цикле. Это позволит избежать этих безумных IF, что у вас в скетче, да и код будет куда удобнее модернизировать и поддерживать.
можно и попробовать .. только я даж не знаю с чего начать :( программер я аховый. Если "if" как то понимаю то - с массивом сложнее.
А что в том "if" безумного? ну переменных много .. а было бы их две?
if (tmp_bp1 > 30 || tmp_bp2 > 30) ... уже имхо совсем не безумно :)
А что в том "if" безумного? ну переменных много .. а было бы их две?
с массивом будет одна. И что важно - сделаете вы вместо 7 датчиков 77 - а код останется тем же. Попробуйте представить. во что превратится ваш скетч для 77 датчиков :)
ой жуть. Вам не надоело писать одно и то же по 7 раз? Программирование - хобби ленивых, используйте циклы и массивы, скетч станет короче раза в четыре. думаю. И ошибки станет искать легче.
да как Вам сказать .. я же шел от малого. Поставил 1 датчик. Ну какой масив на 1 датчик? :) Покумекал с алгоритмом - вроде с одним работает. Припаял еще датчиков - и добавил их в условие :)
можно и попробовать .. только я даж не знаю с чего начать :( программер я аховый. Если "if" как то понимаю то - с массивом сложнее.
ну как-то так (компилить не пробовал, могут быть ошипки)
#define SENSORS 7 float temp[SENSORS]; for(int i=0;i<SENSORS;i++) { if (temp[i] > temp_max) { cooler = true; digitalWrite(cooler_pin, HIGH); //включить кулер x = x + 1; break; } }как то так ...
мне кажется стало "безумнее" ... мне понятнее не стало дак это точно. на вскидку с "if" логика видна сразу. Да и в 4 раза меньше не стало :) с 19 строк выросло до 31
вроде работает .. но надо потестить ... помогло ли
/* * блок питания v. 0.1 * */ #include <OneWire.h> #include <DallasTemperature.h> #include "ASOLED.h" #define SENSORS 6 OneWire oneWire(2); // вход датчиков 18b20 DallasTemperature ds(&oneWire); DeviceAddress ard_bp1 = {0x28, 0xFF, 0xC1, 0x8B, 0x01, 0x17, 0x03, 0x21}; DeviceAddress ard_bp2 = {0x28, 0xFF, 0x23, 0x93, 0x01, 0x17, 0x03, 0x5C}; DeviceAddress ard_dc1 = {0x28, 0xFF, 0x94, 0x99, 0x01, 0x17, 0x03, 0x59}; DeviceAddress ard_dc2 = {0x28, 0xFF, 0xE4, 0x08, 0x02, 0x17, 0x04, 0x3D}; DeviceAddress ard_r1 = {0x28, 0xFF, 0x1D, 0x98, 0x01, 0x17, 0x03, 0xEE}; DeviceAddress ard_r2 = {0x28, 0xFF, 0x52, 0xA4, 0x01, 0x17, 0x05, 0xEF}; DeviceAddress ard_r3 = {0x28, 0xFF, 0xA0, 0xDD, 0x01, 0x17, 0x04, 0xAF}; float tmp[SENSORS]; byte buzz_gnd=4; //динамик земля byte buzz_pin=5; //динамик сигнал byte cooler_pin = 8; //пин реле включения кулера unsigned long prevMillis; unsigned long testStart; boolean cooler = false; //флаг работы кулера float tmp_min = 30.0; float tmp_max = 33.0; int x = 0; int y = 0; void setup() { Serial.begin(115200); ds.begin(); pinMode(buzz_pin, OUTPUT); //пищалка pinMode(buzz_gnd, OUTPUT); //пищалка digitalWrite(buzz_gnd, 0); LD.init(); //иниц OLED диспл LD.clearDisplay(); testStart = millis(); //время начала теста в системе отсчёта ардуины prevMillis = millis(); //время первого шага pinMode(cooler_pin, OUTPUT); //пин реле как выход digitalWrite(cooler_pin, LOW); //обесточить реле, выключить кулер Serial.println("BP1 BP2 DC1 DC2 R1 R2 R3 Cool X Y"); } void sendData() // данные в порт { Serial.print(tmp[0], 1); Serial.print(" "); Serial.print(tmp[1], 1); Serial.print(" "); Serial.print(tmp[2], 1); Serial.print(" "); Serial.print(tmp[3], 1); Serial.print(" "); Serial.print(tmp[4], 1); Serial.print(" "); Serial.print(tmp[5], 1); Serial.print(" "); Serial.print(tmp[6], 1); Serial.print(" "); Serial.print(cooler); Serial.print(" "); Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.println(millis()); } void DispPrint() //отображения данных на экране { // первая строка LD.printString_12x16(""); LD.printNumber((long)tmp[0], 0, 0); // переменная, столбец, строка LD.printString_6x8(" "); LD.printString_12x16(""); LD.printNumber((long)tmp[1]); // переменная, столбец, строка LD.printString_6x8(" "); LD.printString_12x16(""); LD.printNumber((long)tmp[2]); // переменная, столбец, строка LD.printString_6x8(" "); LD.printString_12x16(""); LD.printNumber((long)tmp[3]); // переменная, столбец, строка // вторая строка LD.printString_12x16(""); LD.printNumber((long)tmp[4], 0, 2); // переменная, столбец, строка LD.printNumber((long)tmp[5], 45, 2); // переменная, столбец, строка LD.printNumber((long)tmp[6], 90, 2); // переменная, столбец, строка } void loop() { ds.requestTemperatures(); // считываем температуру с датчиков tmp[0] = ds.getTempC(ard_bp1); tmp[1] = ds.getTempC(ard_bp2); tmp[2] = ds.getTempC(ard_dc1); tmp[3] = ds.getTempC(ard_dc2); tmp[4] = ds.getTempC(ard_r1); tmp[5] = ds.getTempC(ard_r2); tmp[6] = ds.getTempC(ard_r3); sendData(); // отправка данных DispPrint(); if (cooler == false) // включение кулера { for(int i=0;i<SENSORS;i++) { if (tmp[i] > tmp_max) { cooler = true; digitalWrite(cooler_pin, HIGH); //включить кулер x = x + 1; break; } } } if (cooler == true) // выключение кулера { int z = 0; for(int i=0;i<SENSORS;i++) { if (tmp[i] < tmp_min) { z = z + 1; } } if (z == SENSORS) { cooler = false; digitalWrite(cooler_pin, LOW); //включить кулер y = y + 1; } } }вот просто спать не смогу, пока не выясню. А если tmp_bp1 > tmp_max,а в то же время tmp_bp2 < tmp_min то чего бедному кулеру, хоть разорвись? В чем физический смысл одного кулера на много датчиков?
как то так ...
мне кажется стало "безумнее" ... мне понятнее не стало дак это точно. на вскидку с "if" логика видна сразу. Да и в 4 раза меньше не стало :) с 19 строк выросло до 31
вроде работает .. но надо потестить ... помогло ли
Ну так надо же везде циклы вставить, а не в одном месте. Считывание температуры - в цикле, вывод в сериал - тоже
вот просто спать не смогу, пока не выясню. А если tmp_bp1 > tmp_max,а в то же время tmp_bp2 < tmp_min то чего бедному кулеру, хоть разорвись? В чем физический смысл одного кулера на много датчиков?
напрасно вы, все там нормально с логикой. Если хоть один датчик показывает перегрев - включается охлаждение, которое работает, пока сигналы со всех датчиков не придут в норму. А tmp_min и tmp_max - это просто гистерезис.
Задача вполне жизненная, у меня сейчас такая же. Есть несколько приборов, на каждом датчик перегрева. А система кондиционирования - общая.
вот просто спать не смогу, пока не выясню. А если tmp_bp1 > tmp_max,а в то же время tmp_bp2 < tmp_min то чего бедному кулеру, хоть разорвись?
включится кулер .. т.к. для его включение достаточно превышение tmp_max ЛЮБОГО из датчиков. для это стоит "или" ... или bp1 или bp2 или .. и т.д. А вот выключится он только когда ВСЕ датчики опустятся за tmp_min. Для это используется "и" ... и bp1 и bp2 и .. тд
Есть несколько приборов, на каждом датчик перегрева. А система кондиционирования - общая.
совершенной верно ...в одном корпусе несколько устройств греющихся независимо друг от друга. А кулер один на всех :)
вот просто спать не смогу, пока не выясню. А если tmp_bp1 > tmp_max,а в то же время tmp_bp2 < tmp_min то чего бедному кулеру, хоть разорвись?
включится кулер .. т.к. для его включение достаточно превышение tmp_max ЛЮБОГО из датчиков. для это стоит "или" ... или bp1 или bp2 или .. и т.д. А вот выключится он только когда ВСЕ датчики опустятся за tmp_min. Для это используется "и" ... и bp1 и bp2 и .. тд
Есть несколько приборов, на каждом датчик перегрева. А система кондиционирования - общая.
совершенной верно ...в одном корпусе несколько устройств греющихся независимо друг от друга. А кулер один на всех :)
Пробежал в цикле по датчикам, вычислил максимальное значение. Потом сравнил это значение с нормативными.