Views: 840
Алгоритм управления освещением от нажатия кнопки.
Обработка удержания кнопки:
- Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
- Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
- Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага 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
Итоговый проект двухканального регулятора освещения...Практические добавление к проекту в следующей главе…
Это может быть интересно
- Trimax – кодирование и декодирование ИК-командViews: 2215 Первое, что надо понять назначение кнопок клавиш пульта, а также, что за кодирование реализовано в ИК- пульте. Для назначения клавиш обратимся к описанию, а для взлома кодирования воспользуемся …
- Проект с использованием MCC часть 13Views: 1073 Так как используя MCC мы можем его использовать со своими библиотеками, поэтому настало время и свое создать. Для начала откроем наш заголовочный файл в нем очень много букв: По …
- Проект с использованием MCC часть 11Views: 863 Можно несколько облагородить программу вынести наши процедуры обработки нажатия кнопок в отдельные функции. Но вы должны понимать, что это хоть и не значительно, но будет тормозить общую скорость …
- Проект с использованием MCC часть 05Views: 1943 Эту часть назовем так как избавься от delay, там где а это реально не надо. Для это нам потребуется научиться использовать прерывания и работать с таймерами. Что такое …
- Сумеречное релеViews: 1457 Реле управления освещением, датчик день-ночь – одним словом фотореле для управления освещением или формирования сигнала для системы умный дом о понижении или повышении освещенности относительно заданного уровня. Реле выполнено по классической схеме, конденсаторный блок питания, от сети переменного тока …
- Проект с использованием MCC часть 02Views: 2295 Когда мы запустили конфигуратор, самое главное понять, что с этим делать и как проверить, то что мы делаем работает или нет. Для начала настроим регистры конфигурации микроконтроллера и настроем …
- Altium Designer first projectViews: 298 Эта статья подразумевает, что у вас установлен и настроен Altium Designer как описано в статье Altium Designer my setup system and project structure. Обратите внимание! Библиотека постоянно обновляется, …
- Мониторинг температурыViews: 1389 Настоящий проект создан как обучающий с применением библиотек ds18b20 и LCDHD44780 и компилятора Microchip MPLAB XC8 C Compiler V1.12. Если необходимо иметь информацию по состоянию температуры в помещении или в здании, с количеством до 6 точек (16), то …
- Простой сенсорный регулятор светаViews: 2319 Простой сенсорный регулятор. Проект – 2007 года. Регулятор выполнена на микроконтроллере PIC12F683 и имеет минимальное количество элементов. Выполняет стандартные функции, включение выключение света, изменение яркости, запоминание последнего установленного уровня …
- DS18B20 – удаленный контроль температурыViews: 3042 Контроль температуры с использованием датчиков температуры DS18B20 и платы ILLISSI-4B-09-primum Проект позволяет подключать к плате ILLISSI-4B-09-primum до 16 датчиков температуры DS18B20, удаленных более 300 метров, и выводить информацию …
Комментарии