В общем делаю приборчик, который в двух емкостях меряет температуру и в зависимости от нее - включает или выключает реле. Вроде все получилось - при температуре до 30С реле включаются, как только за 30С - отключаются. Но вот хочу поставить две кнопки - которые будут отключать прибор если не используется - т.е. на экран температура будет выводится, будет написано R:OFF, и реле включаться не будет, даже если температура показывает ниже 30С. Ну в общем 2 реле, 2 термодатчика и 2 кнопки... Подскажите - как мне это сделать... Всю программу делал из разных примеров (совсем еще новичок...) - поэтому все получилось криво (но работает ) - Как то все у меня в сетапе, а не в лупсе... Ну в общем буду премного благодарен за подсказки Код (Text): #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define ONE_WIRE_BUS 2 LiquidCrystal_I2C lcd(0x27,16,2); // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2) int interval = 0; int temp1; int temp2; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress Thermometer1 = { 0x28, 0x4D, 0x32, 0xC8, 0x05, 0x00, 0x00, 0x36 }; // адрес датчика DS18B20 DeviceAddress Thermometer2 = { 0x28, 0x9E, 0x95, 0xB5, 0x04, 0x00, 0x00, 0x57 }; void setup() { sensors.begin(); sensors.setResolution(Thermometer1, 10); sensors.setResolution(Thermometer2, 10); Serial.begin(9600); pinMode(3, OUTPUT); digitalWrite(3, HIGH); pinMode(4, OUTPUT); digitalWrite(4, HIGH); lcd.init(); // инициализация LCD lcd.backlight(); // включаем подсветку lcd.clear(); // очистка дисплея } void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.println(tempC); float temp1 = sensors.getTempC(Thermometer1); Serial.println(temp1); if (temp1 < 30) { digitalWrite(3, LOW); lcd.setCursor(3, 0); // устанавливаем курсор на 1 строку, 4 символ lcd.print("ON "); } // вывод надписи else { digitalWrite(3, HIGH); lcd.setCursor(3, 0); // устанавливаем курсор на 1 строку, 4 символ lcd.print("OFF"); // вывод надписи } float temp2 = sensors.getTempC(Thermometer2); Serial.println(temp2); if (temp2 < 30) { digitalWrite(4, LOW); lcd.setCursor(11, 0); // устанавливаем курсор на 1 строку, 12 символ lcd.print("ON "); } else { digitalWrite(4, HIGH); lcd.setCursor(11, 0); // устанавливаем курсор на 1 строку, 12 символ lcd.print("OFF"); } lcd.setCursor(0, 0); // устанавливаем курсор на 1 строку, 1 символ lcd.print("R1:"); // вывод надписи lcd.setCursor(0, 1); lcd.print(sensors.getTempC(Thermometer1),1); lcd.print((char)223); lcd.print("C "); lcd.setCursor(8, 0); // устанавливаем курсор на 1 строку, 9 символ lcd.print("R2:"); lcd.setCursor(8, 1); lcd.print(sensors.getTempC(Thermometer2),1); lcd.print((char)223); lcd.print("C "); } void loop() { sensors.requestTemperatures(); //Serial.print("Sensor1 "); printTemperature(Thermometer1); // Serial.print("Sensor2 "); printTemperature(Thermometer2); }
Если в общих чертах, то надо сделать следующее. 1. Завести где-нибудь выше setup две переменные состояния для каждого датчика. Допустим, значения будут false - реле разрешены, true - реле запрещены. Соответственно, при объявлении инициализировать требуемым значением для начального состояния. boolean relayoff1=false; boolean relayoff2=false; Можно сделать сохранение и считывание состояния этих переменных в EPROM. 2. Проверять последовательно кнопки (можно и на прерывания повесить, но это отдельная история). Если кнопка для датчика нажата, то соответствующей переменной изменять значение на противоположное. relayoff1=!relayoff1; 3. При индикации и переключении реле учитывать не только температуру, но и состояние соответствующей переменной что-то вроде if (relayoff2){ lcd.setCursor(11, 0); // устанавливаем курсор на 1 строку, 12 символ lcd.print("BLOCKED "); // выводим сообщение, что реле не работает, состояние не меняем. //Можно добавить выключение реле, если нужно } else { if (temp2 < 30) { digitalWrite(4, LOW); lcd.setCursor(11, 0); // устанавливаем курсор на 1 строку, 12 символ lcd.print("ON "); } else { digitalWrite(4, HIGH); lcd.setCursor(11, 0); // устанавливаем курсор на 1 строку, 12 символ lcd.print("OFF"); } } PS. не вполне понял логику, на реле выдает LOW, а пишет ON. Т.е. реле срабатывают при низком уровне на соответствующих пинах?
Ну да - в реле шилде все наоборот как то.... Вот данный скетч - работает - все показывает - включает и выключает... За подсказку спасибо - буду копать. Вот скетч у меня какой то отвратный - я и не программировал то сто лет (да и то на бэйсике и паскале) - так что начинаю почти с нуля. Но как то меня напрягает что все операции проводятся в сетапе. Ладно - сейчас ужин приготовлю - и буду по Вашим подсказкам пробовать - надеюсь получится...
сделать глобальные переменные: bool relayEnabled; byte relayState; в сетапе relayState присвоить 0. Кнопа вкл ставит её в true кнопка выкл ставит ее в false. далее пишем функцию: Код (Text): void triggerRelay() { if(! relayEnabled ) { digitalWrite(RELAY_PIN,0); relayState = false; return; } else { relayState = ! relayState; digitalWrite(RELAY_PIN, relayState); } } когда надо перещелкнуть реле, вызываете функцию triggerRelay();
Для двух реле: Код (Text): //Коды реле #DEFINE RELAY_1 1 #DEFINE RELAY_2 2 //операции с реле //активировать #DEFINE RELAY_ENABLE 1 //деактивировать #DEFINE RELAY_DISABLE 2 //включить #DEFINE RELAY_ON 3 //OFF #DEFINE RELAY_ON 4 //в данной переменной храним инфу о реле //1 бит статус первого реле //2 бит - доступность первого реле //3 бит статус второго реле //4 бит - доступность второго реле byte relayState; function relayOperation(byte relay, byte oper) { switch(oper) { case RELAY_ENABLE: relayState |= (1 << (relay*2)); break; case RELAY_DISABLE: relayState &= ~(1<< (relay*2)); break; case RELAY_ON: if( relayState & (1<<(relay*2))) { digitalWrite(RELAY_PIN, 1); relayState |= (1 << ((relay*2)-1)); } break; case RELAY_OFF: if( relayState & (1<<(relay*2))) { digitalWrite(RELAY_PIN, 1); relayState &= ~(1<< ((relay*2)-1)); } break; } }