Views: 826
Алгоритм управления освещением от нажатия кнопки.
Обработка удержания кнопки:
- Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
- Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
- Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага NAP1 начать изменять переменную яркости канал brightness_chn1 на увеличение или на уменьшение. Естественно проверяя её, чтобы она не вылезла за установленные пределы.
- После чего необходимо инициализировать таймер timer_delay1 константой SPEEDIZ которая будет задавать скорость изменения яркости.
- Это забегая в перед обнуляет переменную 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; } }
Надеюсь вопросов не возникнет, по коду, а если возникнут не стесняйтесь пишите в комментах.
Эта функция будет выполнять следующую работу, нажимаем удерживаем кнопку, включается канал (если он отключен) и изменяется яркость.
Теперь остается придумать как будет выполняться функция кратковременного нажатия. например, включение выключение канала. Логика работы предполагается следующая:
- Таймер timer_delay1 при первой инициализации предполагается использовать для определения кратковременное нажатие или удержание. В последующем его задача формировать задержку в изменении параметра переменной яркости и естественно наблюдаемой яркости нами самого канала. Если нажатие кратковременной менее 400 мс, то мы проверим, это при помощи, следующей конструкции else if(!timer_delay1 && bot1_retention) котороя будет следовать после первого блока if(!BOT1 && bot1_retention)// кнопка нажата. Т.е. если кнопка не нажата, таймер “отработал” и флаг bot1_retention установлен.
- Выбрать при помощи оператора switch по значению regim1 какой включить режим работы канала
- Если regim1 = 0 – ничего не делать.
- Если regim1 = 1 – перевести на противоположное значение бита PWM1EN = !PWM1EN; тем самы включить или выключить канал.
- Если 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 – управление проектамиViews: 956 Среда MPLAB X IDE позволяет оперативно работать с несколькими проектами, например, если у вас в работе несколько проектов: Для того чтобы переключиться достаточно выбрать другой проект: Для выбора …
- NeoPixel LED and PIC24Views: 626 Популярность однопроводной шины для управления светодиода типа WS2812 не ослабевает, а новые типы светодиодов в корпусах 3,5*3,5мм, 2,0*2,0мм становяться все больше привлекательными. Построение дисплеев для анимации требуют все …
- APA102 – светодиоды со встроенным драйвером и SPI интерфейсомViews: 3250 APA102 В 2014 году фирма Shenzhen Led Color Optoelectronic Co., Ltd http://www.szledcolor.com/ начала производство светодиодов на драйвере APA102. Это серия так называемых светодиодов со встроенным драйвером. Основной особенностью этих …
- AD9833 – Programmable Waveform Generator – part twoViews: 1744 Прошло время и появилась тема, что-бы закончить проект AD9833 – Programmable Waveform Generator. Приехали печатные платы. В этот раз я печатные платы заказывал в https://jlcpcb.com/ делал это в …
- УКВ – радиоприем, часть 1Views: 9601 Музыкальная тема к статье, слушаем: Первый мой радиоприемник, выглядел так. Использовал исключительно в школе на уроках, держась за одно ухо и преданно смотря на училку и сладко улыбаясь. …
- Защита датчиков температуры DS18B20 от статического электричестваViews: 1800 Статья перепечатана с сайта http://svetomuzyka.narod.ru При удалении датчика на большие расстояния возникает опасность наведения импульсов высокого напряжения на кабель, который соединяет датчик с контролером. Если не принимать меры защиты, …
- LED модуль P10C4V12Views: 3098 LED панели на обычных регистрах типа 74HC595. Они выпускаются как монохромные так двух и полно цветные, особенность, что они предназначены для текстовой информации и имеют один уровень яркости. Общую яркость …
- Проект с использованием MCC часть 10Views: 826 Алгоритм управления освещением от нажатия кнопки. Обработка удержания кнопки: Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да Проверить таймер удержания “отработал” – …
- Интерактивные LedViews: 456 Тема проекта продолжение следует…. Это может быть интересно
Комментарии