PWM мигалка без функции delay

Тема в разделе "Глядите, что я сделал", создана пользователем grx1a, 13 янв 2014.

  1. grx1a

    grx1a Гик

    Это не совсем проект, это больше полезный brick к любому проекту. Написал код для мигалки которая не использует функцию delay которая тормозит работу кода.
    Мигалка не простая, использует код разработанного мною PWM генератора, благодаря чему появляется возможность широких возможностей настройки рабочего процесса. А именно есть возможность регулировки времени вспышки времени между вспышками, а также есть возможность регулировки времени между сериями вспышек (т.е. например 2 быстрых вспышки, длинная пауза снова, две вспышки, и.т.д. )также можно выставить количество вспышек в сери. Также в схему добавил пьезо пищалку

    Код (Text):

    /*************************************************************************************************
    Код ШИМ Генератора серий свето-звуковых импульсов
    БЕЗ ИСПОЛЬЗОВАНИЯ ФУНКЦИИ    delay!!!!!
    ШИМ работает следующим образом:
    Несколько свето-звуковых импульсов (количество задается при помощи pulseQTY) затем длинная пауза и снова Несколько свето-звуковых импульсов, и.т.д.
    Время цикла между повторами импульсов(в серии импульсов) = время импульса(t1) + Время запрета импульса (t1)
    ***************************************************************************************************/

    #define ledPin 12                // Пин светодиода
    #define soundPin 5               // Пин пьезо-пищалки

    boolean BlinkPeriod = 0;         // Триггер периода импульса
    boolean OFF_LED_Period = 0;      // Триггер периода запрета импульса
    boolean longPausePeriod = 0;     // Триггер паузы между серией импульсов
    long time;                       // Таймер
    long t1 = 70;                    // Время импульса  (длинна импульса)
    long t2 = 150;                   // Время запрета импульса (tцикла=t1+t2)
    long t3 = 800;                   // Время паузы между сериями импульсов
                       
    int count;                       // Счетчик импульсов
    int pulseQTY = 2;                // Количество импульсов в серии  
    int Freq = 10;                    // Частота звука пьезо-пищалки [Гц]

    void setup()
    {
      pinMode(ledPin,OUTPUT);
      pinMode(soundPin,OUTPUT);  
    }  

    void loop()  
    {  
      // PWM (ШИМ) ГЕНЕРАТОР**************************************************************************
     
      if((BlinkPeriod==0)&&(OFF_LED_Period==0)&&(longPausePeriod==0))
        {
           time=millis();
           BlinkPeriod=1;
           count++;                                   // Счетчик количества импульсов
        }
      if( BlinkPeriod && (millis() - time) > t1)      // Время импульса
        {
           BlinkPeriod = 0;
           OFF_LED_Period=1;
        }
      if(OFF_LED_Period && (millis() - time) > t2)    // Время запрета импульса
        {
           OFF_LED_Period=0;
        }
      if(count==pulseQTY)
        {
           longPausePeriod=1;
           if(longPausePeriod && (millis() - time) > t3)     // Время паузы между сериями импульсов
               {
                  longPausePeriod=0;
                  count=0;                                   // Сброс счетчика
               }
         }
      //ВЫХОДНОЙ СИГНАЛ***************************************************************************
      if (BlinkPeriod==1)
      {
         digitalWrite(ledPin,HIGH);
         tone(soundPin,Freq);
      }
      else
      {
         digitalWrite(ledPin,LOW);
         noTone(soundPin);
      }

    }
     
  2. grx1a

    grx1a Гик

    Этот код для мигалки работающей сериями вспышек, но если немного его подкоректировать то получится просто PWM мигалка не использующая в работе серии вспышек а просто мигает с заданной частотой
     
  3. grx1a

    grx1a Гик

    Вот код просто PWM мигалки работающей в отличии от первого кода не сериями вспышек а постоянно с заданой частотой
    Код (Text):


    #define ledPin 12                // Пин светодиода
    #define soundPin 5               // Пин пьезо-пищалки

    boolean BlinkPeriod = 0;         // Триггер периода импульса
    boolean OFF_LED_Period = 0;      // Триггер периода запрета импульса

    long time;                       // Таймер
    long t1 = 70;                    // Время импульса  (длинна импульса)
    long t2 = 700;                   // Время запрета импульса (tцикла=t1+t2)


     
    int Freq = 10;                    // Частота звука пьезо-пищалки [Гц]

    void setup()
    {
      pinMode(ledPin,OUTPUT);
      pinMode(soundPin,OUTPUT);  
    }  

    void loop()  
    {  
      // PWM (ШИМ) ГЕНЕРАТОР**************************************************************************
     
      if((BlinkPeriod==0)&&(OFF_LED_Period==0))
        {
           time=millis();
           BlinkPeriod=1;
           
        }
      if( BlinkPeriod && (millis() - time) > t1)      // Время импульса
        {
           BlinkPeriod = 0;
           OFF_LED_Period=1;
        }
      if(OFF_LED_Period && (millis() - time) > t2)    // Время запрета импульса
        {
           OFF_LED_Period=0;
        }
     

      //ВЫХОДНОЙ СИГНАЛ***************************************************************************
      if (BlinkPeriod==1)
      {
         digitalWrite(ledPin,HIGH);
         tone(soundPin,Freq);
      }
      else
      {
         digitalWrite(ledPin,LOW);
         noTone(soundPin);
      }

    }
     
    Nikolai1972 нравится это.
  4. grx1a

    grx1a Гик

    Вот ссылка на ранее созданную полицейскую двухцветную мигалку с сиреной основаной на таком же PWM генераторе, работает следующим образом , две быстрых коротких вспышки синего светодиода, затем две быстрых коротких вспышки красного, светодиода, все сопровождается сиреной http://forum.amperka.ru/threads/Дву...егулировкой-самое-главное-без-delay-for.1521/
     
  5. grx1a

    grx1a Гик

    самое главное во всех этих кодах ни разу не используется функция delay или for
     
  6. grx1a

    grx1a Гик

    извеняюсь но на ссылке с полицейской мигалкой отсутвствует сирена, затупил, вот еще один код охранной системы на ИК датчике движения там встроен код сирены этот код так же основан на таком же генераторе но работает лучше чем код указаной ссылки на полицейскую мигалку за счет внедрения функции void Reset() отключающей светодиоды и пищалку тогда когда сигнал охранного датчика пропадает. во т этот код
    Код (Text):

    Код охранной сигнализации состоящей из PIR ИК датчика движения
    пьезо пищалки, и проблескового маячка в данном случае на 2-х LED(красный, синий).
    При срабатывании ИК датчика движения начинают мигать LED две быстрых вспышки один,
    затем две быстрых вспышки второй, время вспышек и время паузы между вспышками можно менять.
    Количество вспышек можно также менять, но для этого немного придется изменить код.
    Совместно с проблесковым маячком работает сирена, границы частотного диапазона сирены а также скорость
    возростания и затухания звуковой частоты также можно изменять.
    Большое приемущество этого кода в том что он не использует функции delay и for тормозящих работу программы.
    Время работы мигалки с сиреной в данном варианте устанавливается переменным резистором на самом PIR ИК датчике движения
    */

    #define ledPin1 8                // PIN Синий LED        
    #define ledPin2 9                // PIN Красный LED
    #define soundPin 6               // PIN Пьезо пищалки  
    #define PIRPin 7                 // PIN ИК PIR Датчика движения

    boolean BlinkPeriod = 0;         // Триггер периода вспышки за цикл
    boolean OFF_LED_Period = 0;      // Триггер периода запрета вспышки за цикл
    boolean dir = 1;                 // Переменная направления сдига звуковой частоты
    int frequencyMin = 2500;         // Нижняя граница частотного диапазона сирены
    int frequencyMax = 4500;         // Верхняя граница частотного диапазона сирены
    int FreqSpeed = 4;               // Скорость набора/падения звуковой частоты
    int pos = 1;                     // Переменная смены цвета и количеста вспышек (счетчик)
    long t1=50;                      // Время вспышки мигалки (длинна вспышки)
    long t2=100;                     // Время цикла мигалки
    long time;                       // Переменная таймера мигалки
    int count;                       // Счетчик импульсов для мигалки
    int frequency = frequencyMin ;   // Переменная звуковой частоты


    void setup()
    {  
       pinMode(soundPin,OUTPUT);    // Выходной режим PIN-а Пьезо пищалки
       pinMode(ledPin1,OUTPUT);     // Выходной режим PIN-а Синий LED
       pinMode(ledPin2,OUTPUT);     // Выходной режим PIN-а Красный LED
       pinMode(PIRPin,INPUT);       // Входной режим PIN-а ИК PIR Датчика движения
    }  

    void loop()  
    {  
       int PIRRead=digitalRead(PIRPin);  // Читает показания PIR Сенсора (Цифровой сигнал)
       
    // УСЛОВИЕ ЗАПУСКА ПРОГРАММЫ ОХРАННОЙ СИСТЕМЫ ОТ СИГНАЛА С ИК PIR СЕНСОРА ДВИЖЕНИЯ ИЛИ С ДРУГОГО ДАТЧИКА
       if (PIRRead==HIGH)
           {
             Siren();    // функция сирены
             Flash();    // функция мигалки
           }
       else
           {
             Reset();    // Функция Reset останавливает сирену, гасид LED-ы мигалки
           }
    }

    void Flash()         // Функция мигалки
    {
    //ГЕНЕРАТОР ПРЯМОУГОЛЬНЫХ ИМПУЛЬСОВ С ПЕРЕМЕННОЙ СКВАЖНОСТЬЮ ДЛЯ МИГАЛКИ
        if((BlinkPeriod==0)&&(OFF_LED_Period==0))          // Условия работы генератора ШИМ для мигалки
           {
             time=millis();                                // Запуск таймера вспышки
             BlinkPeriod=1;                                // Запуск вспышки
             count++;                                      // Счетчик импульсов вспышки
                  if (count>5) count=1;                    // 5 - позиций счетчика
           }
       if(BlinkPeriod && (millis() - time) > t1)           // Время Вспышки мигалки
           {
             BlinkPeriod = 0;                              // Остановка вспышки
             OFF_LED_Period=1;                             // Запуск запрета на вспышку вкл
           }
       if(OFF_LED_Period && (millis() - time) > t2)        // Время Цикла мигалки
           {
             OFF_LED_Period=0;                             // Остановка запрета на вспышку выкл
           }
     
    //ОПРЕДЕЛЕНИЕ МИГАЮЩЕГО LED (КРАСНЫЙ - СИНИЙ)
       if((count==1)||(count==2))        // Две вспышки
            {pos = 1;}                   // Красный LED
       if(count==3)                      // Пауза между сменой цвета
            {pos = 2;}                   // Одна позиция счетчика на паузу
       if((count==4)||(count==5))        // Две вспышки
            {pos = 3;}                   // Синий LED

    //ВЫХОДНОЙ СИГНАЛ МИГАЛКИ
       if ((BlinkPeriod==1)&&(pos==1))        // Мигает красный LED
             {digitalWrite(ledPin1,HIGH);}
       else
             {digitalWrite(ledPin1,LOW);}

       if((BlinkPeriod==1)&&(pos==3))         // Мигает синий LED
             {digitalWrite (ledPin2,HIGH);}
       else
             {digitalWrite (ledPin2,LOW);}
    }
     
    void Siren()  // Функция сирены
    {            
       if(dir==1)                    // Если dir==1, то частота звука поднимается на скорости FreqSpeed
         {frequency+=FreqSpeed;}        
       if(dir==0)                    // Если dir==0, то частота звука падает на скорости FreqSpeed
         {frequency-=FreqSpeed;}        
       if(frequency>=frequencyMax)   // Верхняя граница частотного диапазона
         {dir=0;}                    // Если частота достигла максимальной точки диапазона, то меняется dirECTION =0
       if(frequency<=frequencyMin)   // Нижняя граница частотного диапазона
         {dir=1;}                    // Если частота достигла минимальной точки диапазона, то меняется dirECTION =1
     
    //ВЫХОДНОЙ СИГНАЛ СИРЕНЫ
       tone(soundPin,frequency);     // Выходной сигнал на сирену
    }

    void Reset()                    // Функция Reset
    {
       noTone(soundPin);            // Останавливает сирену
       digitalWrite(ledPin1,LOW);   // Останавливает 1-ый LED мигалки
       digitalWrite(ledPin2,LOW);   // Останавливает 2-ой LED мигалки
    }
     
  7. grx1a

    grx1a Гик

    Сам того не заметил но первый код может работать абсолютно так же как и второй, то есть меняя исходные данные в заголовке первого кода можно получить и первый и второй код в одном первом
     
    Последнее редактирование: 1 фев 2014
  8. grx1a

    grx1a Гик

    в общем этот код универсален и может работать как сериями вспышек так и без серий вспышек как обычный ШИМ генератор если pulseQTY != 0
     

    Вложения:

    • PWM.jpg
      PWM.jpg
      Размер файла:
      51,6 КБ
      Просмотров:
      736
  9. Andrei brest

    Andrei brest Нерд

    ПОМОГИТЕ
    КАК В МОЙ СКЕТЧ ДОБАВИТЬ ШИМ
    Код (C++):
    // Подсветка столешницы версия 1.0
    // Начата 18.08.2016
    // Автор Левчук А.В.
    //******************************************************************************************************
    int ledPin =9; // подключаем -12в блока питания
    int trigPin = 8; // тригер
    int echoPin = 7; // эхо
    int dist1 = 20; // дистанция срабатывания
    int dist2 =0;  // защита от неисправности датчика HC-SR04
    int ledstate = LOW;
    long zaderhka = 20000;  // время работы 20 сек
    unsigned long nahaloMillis = 0;  // начало отсчета времени

    void setup() {

      Serial.begin (9600);  // выводим на экран
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    pinMode(9, OUTPUT);
    }

    void loop() {

    long duration;  
    int   cm;
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      cm = duration / 82;


    unsigned long prohloMillis; //
    if (ledstate==HIGH)   // если светодиод светится
    {
    prohloMillis=millis();
    if(prohloMillis-nahaloMillis>=zaderhka)  //если больше задоного выключаем
    {
        ledstate = LOW;
        nahaloMillis = 0;
        digitalWrite(ledPin,ledstate);
      }
    }

    if( cm<dist1 ){
    nahaloMillis = prohloMillis; // запоминаем время
      ledstate = HIGH;
      digitalWrite(9,ledstate);
     
     
     
      }

      if( cm==dist2 ){
    nahaloMillis = prohloMillis; // запоминаем время
      ledstate = LOW;
      digitalWrite(9,ledstate);
      }
    //  if( cm==dist2 ){
      //digitalWrite(9,LOW);}
           
      delay(100);
     
    Serial.print(cm);
      Serial.print(".");
       Serial.println(" cm");
      delay(150);
     
     

    }