Проект с использованием MCC часть 10

Views: 990


Алгоритм управления освещением от нажатия кнопки.

Обработка удержания кнопки:

  1. Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да
  2. Проверить таймер удержания “отработал” – это значит, что кнопка нажата и удерживается, если да
  3. Включить модуль, естественно он включиться на ранее заданной яркости. После чего в зависимости от состояния флага NAP1 начать изменять переменную яркости канал brightness_chn1 на увеличение или на уменьшение. Естественно проверяя её, чтобы она не вылезла за установленные пределы.
  4. После чего необходимо инициализировать таймер timer_delay1 константой SPEEDIZ которая будет задавать скорость изменения яркости.
  5. Это забегая в перед обнуляет переменную 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;
            }
        }

Надеюсь вопросов не возникнет, по коду, а если возникнут не стесняйтесь пишите в комментах.

Эта функция будет выполнять следующую работу, нажимаем удерживаем кнопку, включается канал (если он отключен) и изменяется яркость.

Теперь остается придумать как будет выполняться функция кратковременного нажатия. например, включение выключение канала. Логика работы предполагается следующая:

  1. Таймер timer_delay1 при первой инициализации предполагается использовать для определения кратковременное нажатие или удержание. В последующем его задача формировать задержку в изменении параметра переменной яркости и естественно наблюдаемой яркости нами самого канала. Если нажатие кратковременной менее 400 мс, то мы проверим, это при помощи, следующей конструкции else if(!timer_delay1 && bot1_retention) котороя будет следовать после первого блока if(!BOT1 && bot1_retention)// кнопка нажата. Т.е. если кнопка не нажата, таймер “отработал” и флаг bot1_retention установлен.
  2. Выбрать при помощи  оператора switch по значению regim1 какой включить режим работы канала
  3. Если regim1 = 0 – ничего не делать.
  4. Если regim1 = 1 – перевести на противоположное значение бита PWM1EN = !PWM1EN; тем самы включить или выключить канал.
  5. Если 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

Итоговый проект двухканального регулятора освещения...


Практические добавление к проекту в следующей главе…


Это может быть интересно


  • Простой цифровой вольтметр ch-c3200Простой цифровой вольтметр ch-c3200
    Views: 2575 В этой статье рассмотрен пример создания простого вольтметра постоянного тока на основе печатной платы ch-c0030pcb, а при возможности использования внешнего делителя и вольтметр переменного тока. Дан краткий принцип …
  • BMP280 – температура и атмосферное давление – учебный проектBMP280 – температура и атмосферное давление – учебный проект
    Views: 2174 Учебный проект на PIC32 и светодиодной панели P5 (2121)-168-6432-80 (32*64). Проект позволяет ознакомиться с простой графикой и с чтением давления и температуры с датчика BMP280. Для тестирования необходимо …
  • Проект с использованием MCC часть 11Проект с использованием MCC часть 11
    Views: 925 Можно несколько облагородить программу вынести наши процедуры обработки нажатия кнопок в отдельные функции. Но вы должны понимать, что это хоть и не значительно, но будет тормозить общую скорость …
  • Бегущие огни (ch-bo-36)Бегущие огни (ch-bo-36)
    Views: 2556 Проект на PIC-микроконтроллере PIC16F648A. Количество каналов 36. Для индикации используется подключение по матрице 6х6. Расположение светодиодов в одну линию. Все эффекты написаны для возможности увеличения количества светодиодов. Рекомендуется …
  • Проект с использованием MCC часть 07Проект с использованием MCC часть 07
    Views: 1134 Модуль PWM – широтно импульсная модуляция (ШИМ). ПИК контроллеры часто на борту имеют модули ШИМ. На их основе строятся многие узлы управления электро приводами. В нашем варианте мы …
  • AD9833 – Programmable Waveform GeneratorAD9833 – Programmable Waveform Generator
    Views: 2957 Простой генератор звуковых частот на AD9833. Для тестирования БПФ в светомузыке мне нужен был генератор звуковых частот. Я  использовал советский Г3-112, но он себя давно изжил.  Все думал купить …
  • CLUBBEST-50-LightCLUBBEST-50-Light
    Views: 374 CLUBBEST-50-LIGHT   Зміст Короткий опис проекту. 1 Опис схемотехніки візуалізатора музики. 2 Аудіо вхід. 3 MCU. 4 Цифровий вихід. 5 Схема живлення MCU. 6 Складання пристрою. 7 Список …
  • CCP – модуль в режиме Compare на примере PIC18CCP – модуль в режиме Compare на примере PIC18
    Views: 3132 CCP – модуль можно использовать в трех режимах: Capture – позволяет захватывать входной сигнал и определять его параметры (длительность или частоту). Дополнительно управлять внутренними модулями. Compare –  позволяет …
  • USB K-L-line адаптерUSB K-L-line адаптер
    Views: 4688 USB K-L-line адаптер предназначен для связи персонального компьютера с диагностической шиной автомобиля – интерфейс ISO-9141. Этот проект предназначен для сборки недорого устройства с использованием специально для этой цели …
  • REFERENCE CLOCK OUTPUT MODULEREFERENCE CLOCK OUTPUT MODULE
    Views: 522 REFERENCE CLOCK OUTPUT MODULE Модуль формирования опорного тактового сигнала Модуль опорного тактового сигнала обеспечивает возможность посылать сигнал синхронизации на тактовый опорный выходной контакт или контакты (CLKR) в зависимости от …



Поделись этим!

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

Продолжайте читать

НазадДалее

Комментарии

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.