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

Views: 996


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

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

  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

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


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


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


  • Простой цифровой вольтметр ch-c3200Простой цифровой вольтметр ch-c3200
    Views: 2578 В этой статье рассмотрен пример создания простого вольтметра постоянного тока на основе печатной платы ch-c0030pcb, а при возможности использования внешнего делителя и вольтметр переменного тока. Дан краткий принцип …
  • Проект с использованием MCC часть 02Проект с использованием MCC часть 02
    Views: 2407 Когда мы запустили конфигуратор, самое главное понять, что с этим делать и как проверить, то что мы делаем работает или нет. Для начала настроим регистры конфигурации микроконтроллера и настроем …
  • JDY-62A Audio bluetooth moduleJDY-62A Audio bluetooth module
    Views: 1794 Простой модуль для простого аудио блютуса. Встроенные подсказки на английском языке. Модуль включён, режим муте – после подачи питания. Контроль разряда батареи предупреждение что батарея разряжена и необходима …
  • Мультимедийная сеть – AVC-LAN TOYOTAМультимедийная сеть – AVC-LAN TOYOTA
    Views: 5830 AVC LAN – протокол обмена данными мультимедийных систем автомобиля. Кодирование данных. При кодировании различаться три типа данных : преамбула – её назначение, это сообщение устройствам на шине, что начинается передача данных. …
  • DS18B20 – удаленный контроль температурыDS18B20 – удаленный контроль температуры
    Views: 3201 Контроль температуры с использованием датчиков температуры DS18B20 и платы ILLISSI-4B-09-primum Проект позволяет подключать к плате ILLISSI-4B-09-primum до 16 датчиков температуры DS18B20, удаленных более 300 метров,  и выводить информацию …
  • The art of DJThe art of DJ
    Views: 174 The art of DJ. The art of DJ has gained wide popularity. Today, a DJ is not just someone whose task is to mix tracks; a DJ is …
  • Altium Designer – создание рисунков на печатной платеAltium Designer – создание рисунков на печатной плате
    Views: 3445   Для создание рисунков на печатной платы в Altium Designer можно использовать возможность использовать в Altium Designer сторонних скриптов. Мне возможность эта очень понравилась и я решил её расшарить …
  • Часы-кухонный таймерЧасы-кухонный таймер
    Views: 2841 Каждая кухня должна иметь кухонный таймер, который позволяет напоминать хозяйке когда проходить определенный промежуток времени. Например, печем пирог, варим яйца… , чтобы не смотреть постоянно на часы, установим таймер и …
  • APA102 – светодиоды со встроенным драйвером и SPI интерфейсомAPA102 – светодиоды со встроенным драйвером и SPI интерфейсом
    Views: 3415 APA102 В 2014 году фирма Shenzhen Led Color Optoelectronic Co., Ltd http://www.szledcolor.com/ начала производство светодиодов на драйвере APA102. Это серия так называемых светодиодов со встроенным драйвером. Основной особенностью этих …
  • Емкостной сенсорЕмкостной сенсор
    Views: 3153 Изучаем изготовление емкостных сенсоров на PIC-микроконтроллере. Конструкция емкостных сенсоров имеет вид: Емкостные сенсоры строятся по схеме высокочастотного генератора, сам принцип основан на измерение частоты этого генератора. Частота зависит …



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

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

НазадДалее

Комментарии

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

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