Отключить кнопкой зависимость от температуры.

Тема в разделе "Arduino & Shields", создана пользователем Djvan, 30 апр 2014.

  1. Djvan

    Djvan Нерд

    В общем делаю приборчик, который в двух емкостях меряет температуру и в зависимости от нее - включает или выключает реле. Вроде все получилось - при температуре до 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);

    }
     
  2. geher

    geher Гуру

    Если в общих чертах, то надо сделать следующее.
    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. Т.е. реле срабатывают при низком уровне на соответствующих пинах?
     
  3. Djvan

    Djvan Нерд

    Ну да - в реле шилде все наоборот как то.... Вот данный скетч - работает - все показывает - включает и выключает... За подсказку спасибо - буду копать. Вот скетч у меня какой то отвратный - я и не программировал то сто лет (да и то на бэйсике и паскале) - так что начинаю почти с нуля. Но как то меня напрягает что все операции проводятся в сетапе.

    Ладно - сейчас ужин приготовлю - и буду по Вашим подсказкам пробовать - надеюсь получится...
     
  4. Mitrandir

    Mitrandir Гуру

    сделать глобальные переменные:
    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();
     
  5. Mitrandir

    Mitrandir Гуру

    Для двух реле:
    Код (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;
       }
    }