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

Views: 826


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

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

  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

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


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


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


  • Простой цифровой милливольтметр постоянного токаПростой цифровой милливольтметр постоянного тока
    Views: 4091 Простой цифровой вольтметр постоянного тока. Три диапазона измерений с автоматическим переключением 1 – 0,001 – 0,999 V, 2 – 0,01-9,99 V, 3 – 0,1-99,9. Четыре управляемых выхода с возможностью задания функции контроля …
  • MPLAB X IDE – управление проектамиMPLAB X IDE – управление проектами
    Views: 956 Среда  MPLAB X IDE позволяет оперативно работать с несколькими проектами, например, если у вас в работе несколько проектов: Для того чтобы переключиться достаточно выбрать другой проект: Для выбора …
  • NeoPixel LED and PIC24NeoPixel LED and PIC24
    Views: 626 Популярность однопроводной шины для управления светодиода типа WS2812 не ослабевает, а новые типы светодиодов в корпусах 3,5*3,5мм, 2,0*2,0мм становяться все больше привлекательными. Построение дисплеев для анимации требуют все …
  • APA102 – светодиоды со встроенным драйвером и SPI интерфейсомAPA102 – светодиоды со встроенным драйвером и SPI интерфейсом
    Views: 3250 APA102 В 2014 году фирма Shenzhen Led Color Optoelectronic Co., Ltd http://www.szledcolor.com/ начала производство светодиодов на драйвере APA102. Это серия так называемых светодиодов со встроенным драйвером. Основной особенностью этих …
  • AD9833 – Programmable Waveform Generator – part twoAD9833 – Programmable Waveform Generator – part two
    Views: 1744 Прошло время и появилась тема, что-бы закончить проект AD9833 – Programmable Waveform Generator. Приехали печатные платы. В этот раз я печатные платы заказывал в https://jlcpcb.com/ делал это в …
  • УКВ – радиоприем, часть 1УКВ – радиоприем, часть 1
    Views: 9601 Музыкальная тема к статье, слушаем: Первый мой радиоприемник, выглядел так. Использовал исключительно в школе на уроках, держась за одно ухо и преданно смотря на училку и сладко улыбаясь. …
  • Защита датчиков температуры DS18B20 от статического электричестваЗащита датчиков температуры DS18B20 от статического электричества
    Views: 1800 Статья перепечатана с сайта http://svetomuzyka.narod.ru При удалении датчика на большие расстояния возникает опасность наведения импульсов высокого напряжения на кабель, который соединяет датчик с контролером. Если не принимать меры защиты, …
  • LED модуль P10C4V12LED модуль P10C4V12
    Views: 3098 LED панели на обычных регистрах типа 74HC595. Они выпускаются как монохромные так двух и полно цветные, особенность, что они предназначены для текстовой информации и имеют один уровень яркости. Общую яркость …
  • Проект с использованием MCC часть 10Проект с использованием MCC часть 10
    Views: 826 Алгоритм управления освещением от нажатия кнопки. Обработка удержания кнопки: Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да Проверить таймер удержания “отработал” – …
  • Интерактивные LedИнтерактивные Led
    Views: 456 Тема проекта   продолжение следует…. Это может быть интересно



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

Продолжайте читать

НазадДалее

Комментарии

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

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