дайте ссылку на образец (прерывания)

Тема в разделе "Флудилка", создана пользователем dreadfull, 9 июл 2014.

  1. dreadfull

    dreadfull Гик

    ув. Форумчане.
    необходим образец (пример) прерывания. задача: нажатием кнопки (прерыванием) запустить смену значения переменной.
    п.с. 10 урок Джереми Блюма не особо помог....
     
  2. acos

    acos Официальный гик Администратор

  3. dreadfull

    dreadfull Гик

    так, сейчас попробую обьяснить что именно мне надо и зачем.
    пол года назад была поставлена задача: отреставрировать старый советский инкубатор до современных требований. т.е. у нас был коробка инкубатора с теном и все... необходимо было доделать мозги (блок управления) который бы выполнял следующие задачи:
    1. включал и выключал тен для поддержки температуры 38..42 С
    2. включал с задержкой вентилятор под теном (1 мин) и выключал вместе с теном
    3. вращал лоток с яйцами под углом +45 и -45 градусов каждые 12 часов.

    для этого мы взяли
    1 ардуино уно
    2. 1602 LCD Keypad shield который показывал текущую температуру и т.д.
    3. датчик температуры DS 18B20
    4. датчик наклона MMA7361 который останавливал под нужным углом лоток
    5. релюшки 4 вместе (для прямого хода вращения лотка и реверса) и 2 вместе (для тена и вентилятора)
    6. блок питания от телефона эриксон, 9В и 1,5 А (!) и подходит штатный разьем под ардуинку)))))

    это все было собрано в красивые корпуса для пущей надежности;). (см. картинку в конце, уно и шилд ЛСД в верхнем корпусе, блок релюшек - в нижнем)

    форумчане помогли написать код, за что им спасибо.
    Код (Text):
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <LiquidCrystal.h>//DS18b20 connected to D13
    #define DS18B20 A1 // Connections: Sainsmart LCD/Keypad shield
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
    OneWire ourWire(DS18B20);
    DallasTemperature sensors(&ourWire);
    int dx=348;//задаем положение датчика наклона
    unsigned long startTime1 = 0;
    unsigned long startTime2 = 0;
    unsigned long startTime3 = 0; // для вентилятора
    long timeOut1 = 3600;    //таймаут
    long timeOut2 = 3600;
    long timeOut3 = 15;
    unsigned long time3;
    unsigned long time1;  //это для часов в окне монитора
    unsigned long time2;

    void setup() {
      Serial.begin(9600);
      pinMode(3, OUTPUT);  // Включаем тен
      digitalWrite(3, LOW);
      pinMode(2, OUTPUT);  // Включаем ветилятор
      digitalWrite(2, LOW);
      pinMode(12, OUTPUT);  // задаем выход на мотор
      digitalWrite(12, LOW);
      pinMode(13, OUTPUT);  // задаем выход на мотор
      digitalWrite(13, LOW);
      pinMode(11, OUTPUT);  // задаем выход на реверс мотора
      digitalWrite(11, LOW);
      sensors.begin(); //setup the LCD
      lcd.begin(16, 2); // start the library
      lcd.setCursor(0,0);
      lcd.print("t");
    }

    void loop() {
      sensors.requestTemperatures();
      lcd.setCursor(1,0);
      lcd.print(sensors.getTempCByIndex(0));
      lcd.setCursor(6,0);
      lcd.print("C");
      lcd.setCursor(12,0);
      lcd.print("T");
      lcd.setCursor(8,0);
      lcd.print("B");
      lcd.setCursor(0,1);
      lcd.print("TIME");
      lcd.setCursor(10,1);
      lcd.print("R");

    time1 = millis()/1000;
    lcd.setCursor(5,1);
    lcd.print(time1);

      int x;                  // переменные для хранения значений по осям
      x = analogRead(A2)-dx; // читаем положение по оси Х
        lcd.setCursor(11,1);
    lcd.print(x);
        Serial.println();
        Serial.print("X:");
        Serial.print(x);
        Serial.println(" ");
        Serial.print("T:");
        Serial.print(startTime1);
        Serial.println(" ");
        {Serial.print("Time: ");
        time3 = millis()/10000;
        time1 = millis()/10000;
        time2 = millis()/10000;  //выводит количество миллисекунд с момента начала выполнения программы
        Serial.println(time1);
        delay(10);
        if(x < -40 && (time1 - startTime1) > timeOut1 ){ //задаем условия на включение моторчика
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
    }
    if(x > 90){  //задаем условие на отключение моторчика
      startTime1 = time1;
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
    }
    if(x > 80 && (time2 - startTime2) > timeOut2 ){
      digitalWrite(11, HIGH);  // включаем реверсное вращение моторчика
      }
    else if(x < -60){  //задаем условие на отключение моторчика
      startTime2 = time2;
      digitalWrite(11, LOW);
    }
    if(sensors.getTempCByIndex(0) <= 26){
        digitalWrite(3, HIGH);
        lcd.setCursor(13,0);
        lcd.print("on ");
    }
    if(sensors.getTempCByIndex(0) <= 26 && time3 - startTime3 > timeOut3 ){
        digitalWrite(2, HIGH);
        lcd.setCursor(9,0);
        lcd.print("on ");
    }
    else if(sensors.getTempCByIndex(0) > 27){
        digitalWrite(3, LOW);
        digitalWrite(2, LOW);
        lcd.setCursor(14,0);
        lcd.print("off");
        lcd.setCursor(9,0);
        lcd.print("off");
        startTime3 = time3;
    }
    }
    }

     
    в коде значения времени и температур не соответствуют действительности (пока):cool:

    все тестировалось и как бы все хорошо НО оказывается теперь для полного счастья цикл в 12 часов не совсем подходит. необходимо три цикла
    1. 24 часа (первые 2 недели)
    2. 12 часов (вторые две недели)
    3. 4 часа (последнюю неделю)
    +4. тестовый в 10...20 секунд для настроики или проверки.

    на нашем шилде с ЛСД есть незадействованные кнопки. я так понимаю (допускаю) одну любую можно выделить под переключение (прерывание), которое менялобы в переменных значения.

    теперь о том как я себе это все представляю в общем:

    в самом начале
    Код (Text):
    long timeOut1 = 3600;    //таймаут
    long timeOut2 = 3600;
    меняем на переменные типа (long нужно или нет - не знаю...)
    Код (Text):
    #define long timeOut1  
    #define long timeOut2
     
    а третий таймер для вентилятора не трогаем совсем, т.к. он не меняется
    Код (Text):
    long timeOut3 = 15;
    далее вводим четыре пары постоянных:
    Код (Text):
    int long timeOut1_24 = 86400;  // для 24 задержки
    int long timeOut2_24 = 86400;
    int long timeOut1_12 = 43200;  // для 12 задержки
    int long timeOut2_12 = 43200;
    int long timeOut1_4 = 14400;  // для 4 задержки
    int long timeOut2_4 = 14400;
    int long timeOut1t = 10;  // для теста
    int long timeOut2t = 10;
    теперь прописываем строчку указывающую пин прерывания (не знаю как и какой!!!!!)

    далее в "ВОЙД СЕТАП" указываем тип прерывания, типа такого
    Код (Text):
    attachInterrupt(button, swap, RISING);
    и добавляем блок
    Код (Text):
    void swap()
    мысль пока правильная??????:eek::eek::eek:
     

    Вложения:

    • IMG_6712.jpg
      IMG_6712.jpg
      Размер файла:
      938,7 КБ
      Просмотров:
      557
    Последнее редактирование: 10 июл 2014
  4. dreadfull

    dreadfull Гик

    психанул:rolleyes:
     
  5. acos

    acos Официальный гик Администратор

  6. dreadfull

    dreadfull Гик

    я не знаю как называется то что мне нужно. я описал задачу и прошу напрвить меня в нужное русло. мне нажатием кнопки нужно менять значения....
     
  7. acos

    acos Официальный гик Администратор

    Так я и дал вам ссылку.
    Ок, разжую)
    Код оттуда же, чуть модифицированный http://wiki.amperka.ru/конспект-arduino:кнопочный-переключатель

    Код (Text):
    #define BUTTON_PIN A5

    #define TIMEOUT_24    86400  // для 24 задержки
    #define TIMEOUT_12    43200  // для 12 задержки
    #define TIMEOUT_4      14400  // для 4 задержки
    #define TIMEOUT_T      10  // для теста
    #define TIMEOUT_COUNT  4

    // Не знаю зачем нам 2 одинаковых переменных, ну да ладно
    unsigned long timeouts[4][2] = {
      {TIMEOUT_24, TIMEOUT_24},
      {TIMEOUT_12, TIMEOUT_12},
      {TIMEOUT_4, TIMEOUT_4},
      {TIMEOUT_T, TIMEOUT_T},
    };

    unsigned long currentTimeout1;
    unsigned long currentTimeout2;

    boolean buttonWasUp = true;  // была ли кнопка отпущена?

    byte buttonCounter = 0;

    void setup()
    {
      Serial.begin(9600);
      // Начальное значение
      currentTimeout1 = timeouts[0][0];
      currentTimeout2 = timeouts[0][1];

    }

    void loop()
    {

      // определить момент «клика» несколько сложнее, чем факт того,
      // что кнопка сейчас просто нажата. Для определения клика мы
      // сначала понимаем, отпущена ли кнопка прямо сейчас...
      boolean buttonIsUp = digitalRead(BUTTON_PIN);

      // ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
      if (buttonWasUp && !buttonIsUp) {
        // ...может это «клик», а может и ложный сигнал (дребезг),
        // возникающий в момент замыкания/размыкания пластин кнопки,
        // поэтому даём кнопке полностью «успокоиться»...
        delay(10);
        // ...и считываем сигнал снова
        buttonIsUp = digitalRead(BUTTON_PIN);
        if (!buttonIsUp) {  // если она всё ещё нажата...
          // ...это клик!
          ++buttonCounter;

          if (!(buttonCounter % TIMEOUT_COUNT))
            buttonCounter = 0;

          currentTimeout1 = timeouts[buttonCounter][0];
          currentTimeout2 = timeouts[buttonCounter][1];

        }
      }

      // запоминаем последнее состояние кнопки для новой итерации
      buttonWasUp = buttonIsUp;
      Serial.print("Current timeout 1: ");
      Serial.println(currentTimeout1);

      Serial.print("Current timeout 2: ");
      Serial.println(currentTimeout2);
    }
     
  8. dreadfull

    dreadfull Гик

    многовато мелких вопросов. ну сначала что такое
    Код (Text):
    #define TIMEOUT_COUNT  4
    и что это такое
    Код (Text):
    unsigned long timeouts[4][2] = {
      {TIMEOUT_24, TIMEOUT_24},
      {TIMEOUT_12, TIMEOUT_12},
      {TIMEOUT_4, TIMEOUT_4},
      {TIMEOUT_T, TIMEOUT_T},
    };
     
  9. acos

    acos Официальный гик Администратор

  10. dreadfull

    dreadfull Гик

    как строить массивы все вроде и понятно, но как обнулять время (допустим time1=0;) после нажатия кнопки не получается...:mad: получается что time1 постоянно равен нулю. а как сделать чтоб после нажатия time1 увеличивался???
     
    Последнее редактирование: 21 июл 2014
  11. acos

    acos Официальный гик Администратор

    Извините, я вас не понял. Что мешает вам сделать так, чтобы time1 увеличивался?
     
  12. dreadfull

    dreadfull Гик

    у меня стоит простое логическое сравнение, мол если time1 меньше какого значения (допустим TIMEOUT_24), то ничего не выполняем, если больше выполняем действие А. с этим вроде справились, код работает. НО если мы переключаемся между режимами (подачей сигнал на А0) нам необходимо чтоб time1 обнулилось и начало увеличиваться ежесекундно. я пробовал в массив данных добавить time1 изменив массив с 4:2 на 4:3, что бы при каждом нажатии time1=0, после этого time1 становился как константа и не увеличивался. что подскажите?