Прерывания в Ардуино

Тема в разделе "Arduino & Shields", создана пользователем kvitko1, 25 мар 2018.

  1. Securbond

    Securbond Гуру

    Вот после такого вопроса, я бы на Вашем месте убрал слово «Програмист» из подписи!
    По вопросу
    В сетапе назначаем порт на вывод.
    В лупе включаем Светик ждём 5000 мс, выключаем Светик, ждём 3000 мс.
     
  2. kvitko1

    kvitko1 Гик

    ребята вы меня не поняли:confused:
     
  3. kvitko1

    kvitko1 Гик

    ну как 2 цифры?
     
  4. ostrov

    ostrov Гуру

    Стереть неправильные и набрать правильные.
     
  5. kvitko1

    kvitko1 Гик

    каждый дурак сумеет написать такую программу, но допустим у меня есть насос включается и работает определенный период времени потом выключается через опцию "дилэй" останавливается вся программа а допустим у меня еще датчик уровня воды и так далее и тому подобное функция дилей все остановила !!!
    А вот если был бы милисс то программа продолжала работу
    Понятно? Вот то, что я в вас просил!
     
  6. Asper Daffy

    Asper Daffy Иксперд

    Так тебе ж сказали, что "в примерах есть вариант и без delay". Поправь в нём две цифири и используй.
     
  7. Airbus

    Airbus Радиохулиган Модератор

    Всё просто.В Сетапе прописываешь прерывания
    Код (C++):
    void setup()
    {
        // 0-Int 0 пин 2
       // blink функция которая будет что то делать
       // RISING – активирует прерывание по переднему фронту на выводе прерывания
       // FALLING – активирует прерывание по спаду
       //  CHANGE – реагирует на любое изменение значения вывода прерывания
       //   LOW – вызывает всякий раз, когда на выводе низкий уровень.
      attachInterrupt(0, blink, CHANGE);
    }
    // и где то потом в коде
    void loop()
    {
    // это основной код мигаем качаем пищим
    }
    void blink ()
    {
    // это будет выполнятся в прерывании основной код тормозиться
    }
     
    как то так. Подробнее здеся.
     
    Последнее редактирование: 2 апр 2018
  8. Airbus

    Airbus Радиохулиган Модератор

    А вот Вам millis
    Код (C++):

    unsigned long timing; // Переменная для хранения точки отсчета
    unsigned long period; // подставьте нужное вам значение паузы
    void setup()
    {
    Serial.begin(9600);
    }
    void loop() {
    /*
    В этом месте начинается выполнение аналога delay()
    Вычисляем разницу между текущим моментом и ранее сохраненной точкой отсчета.
    Если разница больше нужного значения, то выполняем код.
    Если нет - ничего не делаем
    */

    if (millis() - timing > period)
    {    
      timing = millis(); //снова обнуляем разницу для следующего счёта
      Serial.println ("10 seconds"); //выводим в порт но можно делать что угодно
    }
    }
     
    Последнее редактирование: 2 апр 2018
  9. kvitko1

    kvitko1 Гик

    в каком примере?
     
  10. kvitko1

    kvitko1 Гик

    спасибо
     
  11. kvitko1

    kvitko1 Гик

    смотрите я додумался
    Код (C++):

    volatile bool timerLED1On;      //переменная вкл/выкл таймера
    volatile unsigned long int timerLED1; //переменная подсчета миллисекунд

    unsigned long int timerLED1Loop;  //переменная для хранения значения таймера
    bool LED1On;  //переменная для хранения состояния светодиода

    ISR (TIMER0_COMPA_vect) //функция, вызываемая таймером-счетчиком каждые 0,001 сек.
    {
      if(timerLED1On)       //если включен миллисекудный таймер для LED1
      {
        timerLED1++;        //инкремент переменной таймера (+1)
      }
    }

    void setup()
    {
      pinMode(10, OUTPUT);    //настроить 13-й порт как "выход"
      /**** настройка прерывания по таймеру каждую 0,001 сек (вызов функции ISR (TIMER0_COMPA_vect)) ****/
      TCCR0A |= (1 << WGM01);              //сброс при совпадении
      OCR0A = 0xF9;                        //начало отсчета до переполнения (249)
      TIMSK0 |= (1 << OCIE0A);             //разрешить прерывание при совпадении с регистром А
      TCCR0B |= (1 << CS01) | (1 << CS00); //установить делитель частоты на 64
      sei();                               //разрешить прерывания
    }

    void loop()
    {  
      timerLED1On = 1;    //разрешение инкремента переменной таймера timerLED1
      cli();              //остановка прерываний
      timerLED1Loop = timerLED1; //сохранение текущего значения таймера
      sei();              //разрешение прерываний

      if(timerLED1Loop >= 1000) //если таймер отсчитал больше заданного значения
      {     //то включить/выключить светодиод и обнулить таймер
        if(LED1On == 0)   //если светодиод был выключен
        {
          LED1On = 1;     //поставить флаг включения
          digitalWrite(10, LED1On);   //включить светодиод
        }
      {
      unsigned long start = millis();
      while (millis() - start < 10000);
      }
       // else //иначе, если светодиод был выключен
        {
          LED1On = 0;     //поставить флаг выключения
          digitalWrite(10, LED1On);  //выключить светодиод
        }
        cli();    //остановить прерыания
        timerLED1 = 0;  //обнулить таймер
        sei();    //запустить прерывания
      }
    }







     
     
  12. ostrov

    ostrov Гуру

    [​IMG]
     
    kvitko1 нравится это.
  13. parovoZZ

    parovoZZ Гуру

    А вот это для чего такая хитрая конструкция? В 16 бит таймерах с использованием регистра TEMP оно всё понятно.
    миллис на каком таймере крутится? Ты не поломал её?
     
  14. kvitko1

    kvitko1 Гик

    нет
     
  15. b707

    b707 Гуру

    kvitko. зачем это все? Заново изобрели миллис? - он как раз на таймере0 с частотой 1000 раз в секунду тикает - ну прям ваш код.
     
  16. b707

    b707 Гуру

    ха. слона то я и не приметил :))))
    Вот это круче :)

    Код (C++):
     {
      unsigned long start = millis();
      while (millis() - start < 10000);
      }
    на сленге программистов называется "выстрелить себе в ногу".
     
    ostrov нравится это.
  17. ostrov

    ostrov Гуру

    Вот это делается все тремя строками. Или четырьмя. Напишу вечером, если не опередит никто.
     
    b707 нравится это.
  18. b707

    b707 Гуру

    и главное - оно работает, в отличии от кода ТС
     
  19. ostrov

    ostrov Гуру

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

    Код (C++):
    #define LED 13        // светодиод
    #define timeON  5000  // длительность вкл
    #define timeOFF 3000  // длительность выкл

    void setup() {
      pinMode(LED, OUTPUT);
    }

    void loop() {
      blinker(); // функция мигания
      /*
        сюда лепим что угодно, будет работать независимо от мигалки
      */

    }

    void blinker() { // мигалка (прозрачная)
      static unsigned long timerBlink;
      static unsigned int longBlink = timeOFF;
      static byte ONOFF = 0;
      if (millis() - timerBlink < longBlink) return;
      ONOFF = !ONOFF;
      longBlink =  ONOFF ? timeON : timeOFF;
      digitalWrite(LED, ONOFF);
      timerBlink = millis();
    }
     
    Tomasina нравится это.