Views: 1059
Алгоритм управления освещением от нажатия кнопки.
Обработка удержания кнопки:
- Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
- Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
- Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага 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
Итоговый проект двухканального регулятора освещения...Практические добавление к проекту в следующей главе…
Это может быть интересно
CCP модуль для декодирования ИК-кодов пультов ДУViews: 1146 Множество изготовителей для своих пультов дистанционного управления на ИК лучах используют принцип широтно-импульсной модуляции. В таких кодах бит единицы представляется импульсом большой длительности, а ноль импульсом короткой длительности. …
Гаджеты для домашней автоматики – Емкостной сенсорViews: 1820 Управление светодиодным освещением – Сенсор емкостной. Данный гаджет предназначен для управления освещением где необходимо включением освещение сенсорным прикосновением. Датчик позволяет управлять светодиодной нагрузкой в виде модулей или светодиодных лент …
NeoPixel LED and PIC24Views: 753 Популярность однопроводной шины для управления светодиода типа WS2812 не ослабевает, а новые типы светодиодов в корпусах 3,5*3,5мм, 2,0*2,0мм становяться все больше привлекательными. Построение дисплеев для анимации требуют все …
Kitchen timer with contactless gesture controlViews: 779 Кухонний таймер з безконтактним керуванням жестами дозволяє встановити необхідний період часу для приготування страв, не торкаючись пристрою. Дуже зручно під час приготування їжі, коли руки забрудниться. Усі …
Дисплей KD035C-3A подключение и управлениеViews: 837 Дисплей KD035C-3A производиться компанией SHENZHEN STARTEK ELECTRONIC TECHNOLOGY CO.,LTD Характеристики Параметр Спецификация Единицы измерения Размер дисплея 70.08(H)*52.56(V) (3.5inch) mm Тип дисплея TFT active matrix Цветовая гамма 65K/262K colors Разрешение …
Acquaintance with audio-bluetooth modules F-6888 (BK3254).Views: 2379 Для проектов появилось необходимость познакомиться с недорогими модулями китайского производства, которые можно приобрести у нас в Украине и у китацев, на алиэкспрессе. Так как меня интересует не просто, …
Контроллер управления светодиодным освещением с дистанционным управлениемViews: 2064 Все активнее светодиоды входят в нашу жизнь. Всё эффективнее становится светодиодное освещение. Всё ниже опускаются цены. Всё больше появляется возможностей получения сочных цветов, простоты в управлении. Всё чаще …
Акриловый корпус для платы ch-4000Views: 860 Плата ch-4000 подходит для монтажа в корпуса на дин рейку, но для домашней автоматики необходимо что-то другое, поэтому был разработан корпус из акрила который позволит создавать настольные и настенные устройства. Корпус …
Система AT команд версии V2.0 для ESP8266 и ESP32Views: 13677 Появление нового модуля на базе ESP32 заставило систематизировать систему AT команд, а так же систему обновления и для модулей на базе ESP8266. Начиная с версии v2.0 в ESP8266 …
MPLAB® Code ConfiguratorViews: 1818 MPLAB ® Code конфигуратор (MCC) является свободно распространяемым плагином, это графическая среда программирования, которая генерирует бесшовный, легкий для понимания кода на Cи, чтобы вставить его в свой проект.
Комментарии