Код кнопок

Тема в разделе "Arduino & Shields", создана пользователем moskovskiy82, 16 авг 2015.

  1. moskovskiy82

    moskovskiy82 Нерд

    Друг распаял для меня плату кухонной вытяжки.
    У нее 4 кнопки.
    Необходимо чтобы d2 просто включало выключало свет через реле 2

    А вот кнопки d3 и d4 рулят первым реле - включая его на 30 минут и час.
    Код компилируется но увы ничего не происходит

    Код (Text):
    #include <Arduino.h>
    //для удобства обзываем выводы
    #define rel1 11 //вывод на реле вытяжки
    #define rel2 12 //вывод на реле света
    void setup()
    {
    pinMode(2, INPUT_PULLUP); //сообщаем ардуине о том, что
    pinMode(3, INPUT_PULLUP); //пины 2-4 используются как
    pinMode(4, INPUT_PULLUP); //кнопки с внутренней подтяжкой
    pinMode(13, OUTPUT); //тестовый вывод; будет зажигаться в режиме ожидания
    pinMode(11, OUTPUT); //реле вытяжки
    pinMode(12, OUTPUT); //реле света
    }
    void loop()
    {
    int btn2 = digitalRead(2); //кнопка2, вход D2
    int btn3 = digitalRead(3); //кнопка3, вход D3
    int btn4 = digitalRead(4); //кнопка4, вход D4
    int btn4state = 0; //хранилище текущего стейта кнопки
    int btn4state_old = 0; //хранилище прошлого состояния кнопки
    int lightstate = 0; //переменная, в которую мы кладём статус света
    begin:
    if (btn2 == HIGH) //если кнопка 2 отпущена
        {
        digitalWrite(rel1, LOW); //то ничего не делаем
            if (btn3 == HIGH) //если кнопка 3 отпущена
                {
                digitalWrite(rel1, LOW); //то ничего не делаем
                btn4state = btn4;
                if ((btn4state == LOW) && (btn4state_old == HIGH)) //если кнопка 4 нажата, а до этого была отпущена
                    {
                    lightstate = 1 - lightstate; //то делаем магию
                    delay(50); //защита от дребезга кнопки
                    }
                btn4state_old = btn4state; //теперь значение btn4 старое, записываем
                if (lightstate == 1) //если lightstate стал равен одному
                    {
                    digitalWrite(13, HIGH); //то включаем свет
                    }
                        else
                            {
                            digitalWrite(13, LOW); //если нет, выключаем
                                goto begin;
                            }
                }
                else
                    {
                    digitalWrite(rel1, HIGH); //врубаем вытяжку
                    delay(3600000); //ждем час
                    digitalWrite(rel1, LOW); //вырубаем
                    goto begin;
                    }
        }
            else
                {
                digitalWrite(rel1, HIGH); //врубаем вытяжку
                delay(1800000); //ждем 30 минут
                digitalWrite(rel1, LOW); //вырубаем
                goto begin;
                }
    goto begin;
    }
     
  2. Megakoteyka

    Megakoteyka Оракул Модератор

    Для начала проверьте работоспособность платы на каком-нибудь простом коде.
    Использование goto - зло, не нужно его использовать. Тем более, в вашем коде goto вообще никакого смысла не имеет, можно его просто убрать и ничего не изменится.
    Вы используете очень большие задержки. Как собираетесь пользоваться платой?
    Распишите подробно желаемый алгоритм работы.
     
  3. moskovskiy82

    moskovskiy82 Нерд

    Стандартная кухонная вытяжка из которой был выкинут вентилятор (стоит приточка).

    По результатам переделки - есть 4 кнопки (используем пока 3) и два реле (220В)

    Одно реле отвечает rel2 отвечает как на всех вытяжках за освещение. Т.е нажал кнопку btn4 - свет есть. Нажал - света нет.

    Второе реле rel 1 подает 220В на клапан вентиляции (при подаче закрывается - отрубая другие ветки).

    И вот по нажатию кнопки btn2 и btn3 подает напряжение на 1ое реле на полчаса и час соответсвенно.
     
  4. Salk

    Salk Гик

    А вот это:
    PHP:
    int btn4state = 0; //хранилище текущего стейта кнопки
    int btn4state_old = 0; //хранилище прошлого состояния кнопки
    int lightstate = 0; //переменная, в которую мы кладём статус света
    так и должно быть в loop?
     
  5. Megakoteyka

    Megakoteyka Оракул Модератор

    delay(3600000); //ждем час
    delay(1800000); //ждем 30 минут
    На этих строчках контроллер не будет реагировать ни на какие воздействия в течение часа и 30 минут соответственно. Свет включить/выключить в это время уже не получится.
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Допустим, напряжение подали 10 минут назад. Что должно произойти, если кнопку нажали повторно?

    Продумайте хорошенько поведение системы для всех воздействий при всех состояниях.
     
  7. moskovskiy82

    moskovskiy82 Нерд

    Как обойти это ограничение?
     
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    Не делать задержку на delay. Используйте millis. На форуме много тем с примерами реализации, поищите.
     
  9. vvr

    vvr Инженерище

    использовать millis()
     
  10. moskovskiy82

    moskovskiy82 Нерд

    Судя по примерам должен тупо сработать такой код
    11 реле вытяжки и 2 и 3 кнопки на полчаса и час


    Код (Text):

    enum { nkinds=2, debounced=5 }; // # of activity kinds;  debounce-criterion
    const byte outPins[nkinds] = {11}; // Output pin numbers
    const byte inPins[nkinds]  = {2, 3}; // Input pin numbers
    const unsigned int actLens[nkinds] = {1800000, 3600000}; // Activity lengths, ms
    byte states[nkinds] = {0, 0};
    unsigned long actEnds[nkinds] = {0, 0};
    int lightState = 0;
    const int lightPin = 4;
    const int lightrelePin =  13;


    void setup() {
    // Set input/output modes of pins
      for (byte i=0; i<nkinds; ++i) {
        pinMode(outPins[i], OUTPUT);
        pinMode(inPins[i], INPUT);
      }
      pinMode(lightrelePin, OUTPUT);
      pinMode(lightPin, INPUT);
    }

    // Once per millisecond, for each kind of activity
    // check for new beginning or deal with ongoing action
    void loop() {
      lightState = digitalRead(lightPin);
      if (lightState == HIGH) {
        digitalWrite(lightrelePin, HIGH);  
      }
      else {
        // turn LED off:
        digitalWrite(lightrelePin, LOW);
      }
      unsigned long now = millis();
      for (byte i=0; i<nkinds; ++i) {
        if (states[i] < debounced) {  // Is activity off?
          // It's off, look for a turnon
          if (digitalRead(inPins[i])) {
            ++states[i];        // Button is closed at the moment
            // See if button has been debounced
            if (states[i] >= debounced) { // If so, start its action
              digitalWrite(outPins[i], HIGH);
              actEnds[i] = now + actLens[i];
            }
          }
          else {
            states[i] = 0;      // Button is not closed at moment
          }
        }
        else { // It's on, see if end-time has arrived
          if (now >= actEnds[i]) {
            digitalWrite(outPins[i], LOW); // Clear output when done
            states[i] = 0;        // Return to button-seeking state
          }
        }
      }
      while (now == millis()) {};       // Finish current millisecond
    }

     
     
    Последнее редактирование: 19 авг 2015