Views: 1087
Алгоритм управления освещением от нажатия кнопки.
Обработка удержания кнопки:
- Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
- Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
- Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага 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
Итоговый проект двухканального регулятора освещения...Практические добавление к проекту в следующей главе…
Это может быть интересно
NeoPixel LED и PIC18Views: 1922 Еще раз об управлении светодиодами на драйвере WS2812 и ему подобных. Как известно эти светики управляются по однопроводной шине. Основная особенность, что программно можно описать передачу данных, …
TDA7294 part 1Views: 501 TDA7294 має унікальні дані для створення підсилювачів звукової частоти HI-FI класу. Варіант застосування є конфігурація BRIDGE (мостова схема включення), де використовуються два TDA7294, як показано на схематичній діаграмі …
Дисплей KD035C-3A подключение и управлениеViews: 863 Дисплей KD035C-3A производиться компанией SHENZHEN STARTEK ELECTRONIC TECHNOLOGY CO.,LTD Характеристики Параметр Спецификация Единицы измерения Размер дисплея 70.08(H)*52.56(V) (3.5inch) mm Тип дисплея TFT active matrix Цветовая гамма 65K/262K colors Разрешение …
Простой цифровой вольтметр ch-c3200Views: 2661 В этой статье рассмотрен пример создания простого вольтметра постоянного тока на основе печатной платы ch-c0030pcb, а при возможности использования внешнего делителя и вольтметр переменного тока. Дан краткий принцип …
Часы-кухонный таймерViews: 2916 Каждая кухня должна иметь кухонный таймер, который позволяет напоминать хозяйке когда проходить определенный промежуток времени. Например, печем пирог, варим яйца… , чтобы не смотреть постоянно на часы, установим таймер и …
Бегущие огни на WS2812BViews: 5053 В настоящее время большой популярностью стали пользоваться светодиоды со встроенным драйвером WS2812B. Текущий проект предназначен показать возможность использования и управления этими светодиодами. Это и проект и исследование по …
Проект с использованием MCC часть 15Views: 1754 EUSART – Универсальный асинхронный приёмопередатчик (УАПП, англ. Universal Asynchronous Receiver-Transmitter, UART) — узел вычислительных устройств, предназначенный для организации связи с другими цифровыми устройствами. … читать на вики. Внесем изменения в нашу схему, …
Стабилизатор тока для светодиодов SN3350Views: 2784 SN3350 ближайший аналог ZXLD1350 Как собрать готовый вариант, читайте во второй части – http://catcatcat.d-lan.dp.ua/stabilizator-toka-na-sn3350-chast-2/ 40V драйвер светодиодов с внутренним ключом SN3350 – импульсный понижающий преобразователь, разработанный для того, чтобы эффективно управлять одним или …
USB K-L-line адаптерViews: 4771 USB K-L-line адаптер предназначен для связи персонального компьютера с диагностической шиной автомобиля – интерфейс ISO-9141. Этот проект предназначен для сборки недорого устройства с использованием специально для этой цели …
Мониторинг температурыViews: 1488 Настоящий проект создан как обучающий с применением библиотек ds18b20 и LCDHD44780 и компилятора Microchip MPLAB XC8 C Compiler V1.12. Если необходимо иметь информацию по состоянию температуры в помещении или в здании, с количеством до 6 точек (16), то …
Комментарии