Проект с использованием MCC часть 10

Просмотров: 616


Алгоритм управления освещением от нажатия кнопки.

Обработка удержания кнопки:

  1. Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
  2. Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
  3. Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага NAP1 начать изменять переменную яркости канал brightness_chn1 на увеличение или на уменьшение. Естественно проверяя её, чтобы она не вылезла за установленные пределы.
  4. После чего необходимо инициализировать таймер timer_delay1 константой SPEEDIZ которая будет задавать скорость изменения яркости.
  5. Это забегая в перед обнуляет переменную regim1 – это у нас указатель выполнения функции от кратковременного нажатия кнопки.

Как это выглядит в программе:

        if(!BOT1 && bot1_retention)// кнопка нажата
        {
            if(!timer_delay1)
            {
                PWM1EN=1;       // включить модуль
                if(NAP1)
                {
                    // увеличиваем яркость
                    brightness_chn1++;
                    if(brightness_chn1>1023)brightness_chn1=1023;
                    PWM1_LoadDutyValue(brightness_chn1); 
                }
                else
                {
                    // уменьшать яркость
                    brightness_chn1--;
                    if(brightness_chn1<0)brightness_chn1=0;
                    PWM1_LoadDutyValue(brightness_chn1);
                }
                timer_delay1=SPEEDIZ;   // инициализировать задержку
                regim1=0;
            }
        }

Надеюсь вопросов не возникнет, по коду, а если возникнут не стесняйтесь пишите в комментах.

Эта функция будет выполнять следующую работу, нажимаем удерживаем кнопку, включается канал (если он отключен) и изменяется яркость.

Теперь остается придумать как будет выполняться функция кратковременного нажатия. например, включение выключение канала. Логика работы предполагается следующая:

  1. Таймер timer_delay1 при первой инициализации предполагается использовать для определения кратковременное нажатие или удержание. В последующем его задача формировать задержку в изменении параметра переменной яркости и естественно наблюдаемой яркости нами самого канала. Если нажатие кратковременной менее 400 мс, то мы проверим, это при помощи, следующей конструкции else if(!timer_delay1 && bot1_retention) котороя будет следовать после первого блока if(!BOT1 && bot1_retention)// кнопка нажата. Т.е. если кнопка не нажата, таймер “отработал” и флаг bot1_retention установлен.
  2. Выбрать при помощи  оператора switch по значению regim1 какой включить режим работы канала
  3. Если regim1 = 0 – ничего не делать.
  4. Если regim1 = 1 – перевести на противоположное значение бита PWM1EN = !PWM1EN; тем самы включить или выключить канал.
  5. Если regim1 = 2 – запустить таймер для автоотключения.

По такой логике можно придумать по количеству кратковременных нажатий клавиш множество режимов работы канала. Для начала реализуем первый: включить – выключить. Это будет выглядеть так:

        else if(!timer_delay1 && bot1_retention)// таймер выполнения команды == 0, флаг 
        {
            // определение команды
            switch (regim1)
            {
                case 1: // включить выключить
                    PWM1EN = !PWM1EN;       // включить выключить канал 1
                break;    
                case 2: // отключение по таймеру

                break;  
                case 3:

                break;  
                case 4:

                break;  
            }
            bot1_retention=0; // сбросить флаг нажатия кноки  
            regim1=0;
        }

конструкцию

                case 3:

                break;  
                case 4:

                break;

я показал, для того, что бы можно было понять, как расширить функциональные возможности устройства. Скомпилируем проект и прошьем наш PIC. Проверим работу. Промежуточный проект:


Значок

Проект с использованием MCC часть 10 865.35 KB 50 downloads

Промежуточная версия проекта двухканального...

Теперь придумаем функцию автоотключения. Для этого для начала добавим флаги автоотключения, назовем их AUTO_OFF1 и AUTO_OFF2. Их функция если они будут установлены запустить таймер автоотключения и отсчитать заданные 30 секунд и отключить канал.

Значит еще нудны две переменные таймеров (для каждого канала по одному), назовем их timer_OFF1 и timer_OFF2. Область из основной работы это таймер 0, поэтому мы их опишем соответственно в файлах таймера и разрешим из использовать в основной программе описав их как внешние (заодно и добавим переменную таймера для второго канала который пока еще не используем.

В заголовочном файле это будет выглядеть так tmr0.h

extern volatile uint16_t timer_delay1, timer_delay2;    // таймер задержки
extern volatile bool AUTO_OFF1, AUTO_OFF2;              // флаги автоотключения каналов 
extern volatile uint16_t timer_OFF1, timer_OFF2;        // таймер задержки

в рабочем tmr0.c, так:

volatile uint16_t timer_delay1, timer_delay2;   // таймер задержки
volatile bool AUTO_OFF1, AUTO_OFF2;             // флаги автоотключения каналов 
volatile uint16_t timer_OFF1, timer_OFF2;       // таймер задержки

Саму обработку таймера добавим в функцию TMR0_CallBack которая вызывается с периодом 0,5 секунды:

В основном цикле изменим часть отвечающим за режим работы канала:

        else if(!timer_delay1 && bot1_retention)// таймер выполнения команды == 0, флаг 
        {
            // определение команды
            switch (regim1)
            {
                case 1: // включить выключить
                    PWM1EN = !PWM1EN;       // включить выключить канал 1
                break;    
                case 2: // отключение по таймеру
                        AUTO_OFF1=1; // установить флаг автоотключение канала 1
                        timer_OFF1=TIMEOFF*2; // *2 такак отсчет идет в два раза быстерее, по 0,5 секунды
                break;  
                case 3:

                break;  
                case 4:

                break;  
            }
            bot1_retention=0; // сбросить флаг нажатия кноки  
            regim1=0;
        }

При кратковременном нажатии на кнопку установиться флаг автоотключения AUTO_OFF1=1; и будет выполнена инициализация таймера  timer_OFF1=TIMEOFF*2;

После этого в прерываниях таймера 0, будут активированы  строки:

    if(timer_OFF1)timer_OFF1--;     // уменьшить таймер на 1 если он больше нуля.
    
    if(AUTO_OFF1 && !timer_OFF1)
    {
        AUTO_OFF1=0;    // сбросить флаг функция выполнена
        PWM1EN = 0;     // отключить канал 1
    }

Так как переменная timer_OFF1 будет больше нуля, начнется её уменьшение с частотой 0,5 герца. И начнет условие if(AUTO_OFF1 && !timer_OFF1) ожидать когда таймер станет равен 0. И при выполнении это чуда флаг  AUTO_OFF1=0; будет сброшен, а канал 1 PWM1EN = 0; отключен.

Скомпилируем проект и проверим его работу.


Теперь добавим аналогичные функции для второго канала:

Для этого еще раз проверим какие необходимо внести изменения:

в файле main.c писание переменной проверим должно быть так:

// константы
#define SPEEDIZ 2   // скорость изменение яркости
#define TIMEOFF 30  // время автоотключения канала

// переменные
bool bot1_retention, bot2_retention; // флаги удержания кнопки
bool NAP1, NAP2;  // направление изменения яркости
int16_t brightness_chn1, brightness_chn2;    // состояние яркости каналов
uint8_t regim1, regim2;     // режимы управления каналами

Обработка прерываний таймера 0:

// обработка прерываний
void TMR0_ISR(void)
{
    static volatile uint16_t CountCallBack = 0;

    // Clear the TMR0 interrupt flag
    INTCONbits.TMR0IF = 0;

    TMR0 = timer0ReloadVal;
//------------------------------------------------------------------------------
    if(timer_delay1>0)timer_delay1--;   // обработка таймера
    if(timer_delay2>0)timer_delay2--;   // обработка таймера
//------------------------------------------------------------------------------
    // callback function - called every 504th pass
    if (++CountCallBack >= TMR0_INTERRUPT_TICKER_FACTOR)
    {
        // ticker function call
        TMR0_CallBack();

        // reset ticker counter
        CountCallBack = 0;
    }

    // add your TMR0 interrupt custom code
}

Обработка таймеров автоотключения:

void TMR0_CallBack(void)
{
    // Add your custom callback code here
//    LD1=!LD1;
//    LD2=!LD2;
    if(timer_OFF1)timer_OFF1--;     // уменьшить таймер на 1 если он больше нуля.
    
    if(AUTO_OFF1 && !timer_OFF1)
    {
        AUTO_OFF1=0;    // сбросить флаг функция выполнена
        PWM1EN = 0;     // отключить канал 1
    }
    
    if(timer_OFF2)timer_OFF2--;     // уменьшить таймер на 1 если он больше нуля.
    
    if(AUTO_OFF2 && !timer_OFF2)
    {
        AUTO_OFF2=0;    // сбросить флаг функция выполнена
        PWM2EN = 0;     // отключить канал 1
    }
    
    if(TMR0_InterruptHandler)
    {
        TMR0_InterruptHandler();
    }
}

В основном цикле добавим аналогичную процедуру обработки нажатия кнопки 2 для управления 2 каналом:

if(bot2_pressure)//было нажатие клавиши
        {
            bot2_pressure=0;    // сбросить флаг нажатия
            
            bot2_retention=1;   // событие нажатия произошло
            if(PWM2EN) // если модуль включен (свет горит)
            {
               NAP2=!NAP2;  // изменить напраление
            }        
            regim2++;           // выбор режима
            timer_delay2=400;   // время задержки нажатия первого нажатия 
        }
        
        if(!BOT2 && bot2_retention)// кнопка нажата
        {
            if(!timer_delay2)
            {
                PWM2EN=1;       // включить модуль
                if(NAP2)
                {
                    // увеличиваем яркость
                    brightness_chn2++;
                    if(brightness_chn2>1023)brightness_chn2=1023;
                    PWM2_LoadDutyValue(brightness_chn2); 
                }
                else
                {
                    // уменьшать яркость
                    brightness_chn2--;
                    if(brightness_chn2<0)brightness_chn2=0;
                    PWM2_LoadDutyValue(brightness_chn2);
                }
                timer_delay2=SPEEDIZ;   // инициализировать задержку
                regim2=0;
            }
        }
        else if(!timer_delay2 && bot2_retention)// таймер выполнения команды == 0, флаг 
        {
            // определение команды
            switch (regim2)
            {
                case 1: // включить выключить
                    PWM2EN = !PWM2EN;       // включить выключить канал 1
                break;    
                case 2: // отключение по таймеру
                        AUTO_OFF2=1; // установить флаг автоотключение канала 1
                        timer_OFF2=TIMEOFF*2; // *2 такак отсчет идет в два раза быстерее, по 0,5 секунды
                break;  
                case 3:

                break;  
                case 4:

                break;  
            }
            bot2_retention=0; // сбросить флаг нажатия кноки  
            regim2=0;
        }

С компилируем проект и проверим работу, протестим все режимы работы и управление каналами.


Итоговый проект двухканального регулятора освещения на светодиодах.

Функции – одно кратковременное нажатие включение выключение канала (соответствующей кнопкой), двух кратковременное нажатие кнопки (когда когда канал включен) отключает его через 30 секунд, это так намазываемый “коридорный режим”, вы уходите и пока закрываете дверь, мам необходимо, чтобы освещение было, а потом выключилось. Долговременное нажатие на кнопку изменяет яркость канала возрастает или уменьшается, т.е. например, нажали держим яркость увеличивается, опусти нажали и удерживаем, яркость теперь уменьшаться (и так по кругу).

Скорость изменения яркости и время отключения можно задать в константах  SPEEDIZ  – скорость изменение яркости и TIMEOFF – время автоотключения канала (с).

Значок

Проект с использованием MCC часть 10 (итог) 879.13 KB 228 downloads

Итоговый проект двухканального регулятора освещения...


Практические добавление к проекту в следующей главе…


Это может быть интересно


  • MCC PIC24 – модуль OUTPUT COMPARE – режиме ШИМMCC PIC24 – модуль OUTPUT COMPARE – режиме ШИМ
    Просмотров: 909 Во многих системах управления, для формирования управляющих сигналов требуется модуль ШИМ, он позволяет не только формировать импульсы заданной длительности, но и с применением обычного RC фильтра строить простые …
  • Емкостной сенсорЕмкостной сенсор
    Просмотров: 2703 Изучаем изготовление емкостных сенсоров на PIC-микроконтроллере. Конструкция емкостных сенсоров имеет вид: Емкостные сенсоры строятся по схеме высокочастотного генератора, сам принцип основан на измерение частоты этого генератора. Частота зависит …
  • VU Meter Tower ARTVU Meter Tower ART
    Просмотров: 1443 Стерео индикатор уровня аудио сигнала. Компактность и удобство проектирования устройств на светодиодах WS2812B, а также легкость реализации алгоритма родило идею созданию своей конструкции. В этом проекте я предоставлю …
  • Проект с использованием MCC часть 07Проект с использованием MCC часть 07
    Просмотров: 792 Модуль PWM – широтно импульсная модуляция (ШИМ). ПИК контроллеры часто на борту имеют модули ШИМ. На их основе строятся многие узлы управления электро приводами. В нашем варианте мы …
  • Стабилизатор тока для светодиодов SN3350Стабилизатор тока для светодиодов SN3350
    Просмотров: 2397 SN3350 ближайший аналог ZXLD1350 Как собрать готовый вариант, читайте во второй части – http://catcatcat.d-lan.dp.ua/stabilizator-toka-na-sn3350-chast-2/ 40V  драйвер светодиодов с внутренним ключом  SN3350 – импульсный понижающий преобразователь, разработанный для того, чтобы эффективно управлять одним или …
  • Самый простой диммер для светодиодного освещенияСамый простой диммер для светодиодного освещения
    Просмотров: 2744 Светодиоды все больше входят в нашу жизнь как источники освещения и как само собой разумеющееся, это вопрос регулировки яркости. Существует множество схемных решений, но в нашем варианте мы …
  • Toyota Auto Fader – Модуль включения усилителяToyota Auto Fader – Модуль включения усилителя
    Просмотров: 1722 Toyota Auto Fader – Модуль включения усилителя. Часто автолюбители прибегают к замене штатного головного устройства на универсальное мультимедийное, в котором значительно расширены функциональные возможности. Если возникает желание оставить …
  • Moving average – скользящее среднееMoving average – скользящее среднее
    Просмотров: 1932 Скользящая средняя, скользящее среднее (англ. moving average, MA) — общее название для семейства функций, значения которых в каждой точке определения равны среднему значению исходной функции за предыдущий период. Скользящие средние обычно используются с данными временных рядов для сглаживания …
  • AD9833 – Programmable Waveform Generator – part twoAD9833 – Programmable Waveform Generator – part two
    Просмотров: 1303 Прошло время и появилась тема, что-бы закончить проект AD9833 – Programmable Waveform Generator. Приехали печатные платы. В этот раз я печатные платы заказывал в https://jlcpcb.com/ делал это в …
  • APA102 – светодиоды со встроенным драйвером и SPI интерфейсомAPA102 – светодиоды со встроенным драйвером и SPI интерфейсом
    Просмотров: 3058 APA102 В 2014 году фирма Shenzhen Led Color Optoelectronic Co., Ltd http://www.szledcolor.com/ начала производство светодиодов на драйвере APA102. Это серия так называемых светодиодов со встроенным драйвером. Основной особенностью этих …



Поделись этим!

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

Комментарии

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.