Views: 1064
Алгоритм управления освещением от нажатия кнопки.
Обработка удержания кнопки:
- Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
- Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
- Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага 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
Итоговый проект двухканального регулятора освещения...Практические добавление к проекту в следующей главе…
Это может быть интересно
PIC32MZ – Core Timer (библиотека)Views: 582 Переработанные файлы от Microchip, библиотека для работы с Core Timer.
Altium Designer my Libraries, Project templates, System settings by Catcatcat V23.09Views: 667 September 2023 component base update. Release updates V. – 23_09 added new components. Changed the structure of the database. Configuration file name – DXPPreferences1.DXPPrf. Added project CLUBBEST_50_Light. …
MPLAB® Harmony – или как это просто! Часть 3.Views: 2233 Часть третья – копнём немного глубже. Вы наверное заметили, что во второй главе, вроде сначала все шло как по маслу, а потом, что бы заморгали светики, я вставил …
ch-4050 – дифференциальный терморегуляторViews: 2079 ch-4050 – это не новая модель, это расширенная версия универсального терморегулятора ch-4000. Различия коснулись в появлении новой функции дифференциального регулирования. Это вид регулирования по разности температур измеренного двумя …
APA102 – светодиоды со встроенным драйвером и SPI интерфейсомViews: 3536 APA102 В 2014 году фирма Shenzhen Led Color Optoelectronic Co., Ltd http://www.szledcolor.com/ начала производство светодиодов на драйвере APA102. Это серия так называемых светодиодов со встроенным драйвером. Основной особенностью этих …
Проект с использованием MCC часть 16Views: 1299 Продолжим изучение EUSART. На этом этапе отработает передачи данных с ПК и получения эха. Для этого в основной цикл программы добавим код if(EUSART_DataReady) // проверим флаг готовности данных …
HVLD модуль на примере PIC24FJ128GA204Views: 826 HVLD модуль представляет собой простое устройство, для контроля напряжения питания микроконтроллера или внешнего напряжения (через делитель). Его задача при “выходе” напряжения за заданные пределы сформировать сообщение микроконтроллеру, что …
Регулятор влажностиViews: 1365 Регулятор ILLISSI-CH-1000 предназначен для контроля и регулировки относительной влажности в диапазоне от 0 до 100%. Регулятор позволяет работать как в режиме осушения, так и увлажнения. Для измерения возможно …
Customs codes for exportViews: 375 Митні коди (HS Code) для надсилання посилок за кордон. Для відправки товару за кордон на сьогодні необхідно зазначати митні коди. Часто визначення коду займає багато часу. Для …
Самый простой диммер для светодиодного освещенияViews: 3201 Светодиоды все больше входят в нашу жизнь как источники освещения и как само собой разумеющееся, это вопрос регулировки яркости. Существует множество схемных решений, но в нашем варианте мы …
Комментарии