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

Просмотров: 613


С выводом данных на дисплей мы справились (но могу сразу сказать библиотеку графики к этой статьи пришлось доработать, поэтому в этом проекте она обновлена).

У нас на текущем этапе имеется двухканальный регулятор светодиодного освещения подключенный к ОЛЭД дисплею, воспользуемся этим для индикации состояния работы регулятора. Будем делать индикацию по мере продвижения по логики работы регулятора.

Для начала сделаем, что бы на дисплей выводились надпись канала и значение яркости.

Параметр яркости изменяется в пределах от 0 – минимальная яркость, до 1023 – максимальная яркость. Такой параметр выводить можно, но для восприятия параметра яркости это будет как-то некрасиво. Эффективно показывать яркость в процентах.

для этого добавим в нашу программу следующие переменные pro_bri1, pro_bri2 – в которых будет храниться текущее значение яркости. Т.к. яркость будет изменяться в пределах 0-100 то величина переменной будет достаточна 8 бит или 1 байт (uint8_t).

Для расчета будет использовать следующее выражение (на примере канала 1) преобразование параметра в проценты:

pro_bri1=(uint8_t)((long)brightness_chn1*100/1023);

Думаю стоит объяснить, почему именно так написано, в этом выражении присутствует два раза преобразования данных. Переменная brightness_chn1 имеет формат int16_t это значит, что его значение может быть в пределах от минус – 32768 до +32767. Сам параметр яркости может иметь максимальное значение 1023. Если его умножить на 100, то получим значение 1023*100 = 102300, что больше значения которое может поместить переменная типа int16_t. Для этого мы используем преобразование типов, для этого перед переменной указываем (long), что говорит компилятору, что необходимо её преобразовать в 32 битное число. Все выражение заключается в скобки ((long)brightness_chn1*100/1023), это даст возможность выполнить вычисление в 32 формате. После вычисления необходимо число преобразовать в формат uint8_t и присвоить его переменной pro_bri1.

Для индикации числа будем использовать библиотечную функцию OLED_BinDec.

Вычисление значения процента яркости канала поместим в функцию channel_1 и channel_2, это будет выполняться после нажатия кнопки, функция канала 1, на текущем этапе будет иметь вид:

void channel_1 (void) // управление каналом 1
{
    if(bot1_pressure)//было нажатие клавиши
    {
        bot1_pressure=0;    // сбросить флаг нажатия

        bot1_retention=1;   // событие нажатия произошло
        if(PWM1EN) // если модуль включен (свет горит)
        {
           NAP1=!NAP1;  // изменить напраление
        }        
        regim1++;           // выбор режима
        timer_delay1=400;   // время задержки нажатия первого нажатия 
    }

    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);
            }
            pro_bri1=(uint8_t)((long)brightness_chn1*100/1023);
            timer_delay1=SPEEDIZ;   // инициализировать задержку
            regim1=0;
            AUTO_OFF1=0;    //
        }
    }
    else if(!timer_delay1 && bot1_retention)// таймер выполнения команды == 0, флаг 
    {
        // определение команды
        switch (regim1)
        {
            case 1: // включить выключить
                PWM1EN = !PWM1EN;       // включить выключить канал 1
                AUTO_OFF1=0;    //
            break;    
            case 2: // отключение по таймеру
                if(PWM1EN) // если модуль включен (свет горит)
                {
                    AUTO_OFF1=1; // установить флаг автоотключение канала 1
                    timer_OFF1=TIMEOFF*2; // *2 такак отсчет идет в два раза быстерее, по 0,5 секунды
                } 
            break;  
            case 3:

            break;  
            case 4:

            break;  
        }
        bot1_retention=0; // сбросить флаг нажатия кноки  
        regim1=0;
    }
}

Следующую задачу которую предстоит решить (но которая с первого раза не видна), это вывод данных на дисплей. Если информацию выводить постоянно в главном цикле работы, то это будет сильно замедлять главный цикл и эффективность управления будет низкой. По этому данные на дисплей должны выводиться только по необходимости. Как это сделать?

Сделаем это на следующем принципе, если параметр процента яркости измениться, то необходимо изменить изображение на дисплее, если нет, то обновление дисплея выполнять нет необходимости. для этого добавит еще два параметр pro_bri1p, pro_bri2p. Эти параметры будут хранить “прошлые” значения яркости. Как это будет работать?

В главном цикле мы будем сравнивать эти значения на равенство, если они не равно, то необходимо будет обновить значение параметра на дисплее:

        if(pro_bri1!=pro_bri1p)
        {
            pro_bri1p=pro_bri1;  // сбросить несоответствие
            OLED_curcor(50,4);
            OLED_BinDec(pro_bri1, 0, 0, 4, 1, 2, 2);
        }
        if(pro_bri2!=pro_bri2p)
        {
            pro_bri2p=pro_bri2;  // сбросить несоответствие
            OLED_curcor(50,1);
            OLED_BinDec(pro_bri2, 0, 0, 4, 1, 2, 2);
        }

В приведенном тексте программы, мы выводим значение процента яркости для первого канала в 4 (символьной) строке дисплея с 50 позиции с двойной шириной и высотой, а второго канала в 1 строке. Предварительно для понимания что за цифры на дисплее, перед главным циклом вставить надписи:

    OLED_String ("Канал 1", 0, 1, 1, 1, 4);
    OLED_String ("Канал 2", 0, 1, 1, 1, 1);
    
    pro_bri1p = 1;    // обновить дисплей
    pro_bri2p = 1;

Запись значения 1 в регистры “прошлой” яркости даст возможность в первом включении регулятора полностью прорисовать дисплей. Скомпилировав проект мы получим изображение:

Попробуем изменить яркость на дисплее мы увидим изменяющееся значение:


Проект для тестирования:

Значок

Проект с использованием MCC часть 14 (1) 716.66 KB 14 downloads

Проект для первой части: мы вывели параметр...
Login Required Message:

Когда мы выключаем канал значение на дисплее остается неизменным, а желательно, что бы писалось выключено. Сделаем это!

За включение или выключения модуля ШИМ отвечают биты управления PWM1EN и PWM2EN модулей. Добавим в модуль индикации функцию которая будет  изменять надпись процентов на надпись выключено. Для этого добавим еще два флага который будут запоминать предыдущие состояние работы модулей ШИМ.

Изменим функцию индикации канала:

        // индикация для канала 1
        if(!PWM1EN && !SHIM1)
        {
            SHIM1=1;  //
            OLED_String ("откл", 0, 2, 2, 60, 4);
            pro_bri1p=200;
        }
        else if(PWM1EN && (pro_bri1 != pro_bri1p))
        {
            pro_bri1p=pro_bri1;  // сбросить несоответствие
            SHIM1=0;
            OLED_curcor(60,4);
            OLED_BinDec(pro_bri1, 0, 0, 4, 1, 2, 2);
        }

В не проверяем состояние работы модуля ШИМ если бит PWM1EN установлен значить необходимо показывать значение яркости. Если нет, то прорисовать в этом месте надпись “откл”. Для того, чтобы при выключении прорисовка была только один раз используется флаг SHIM1. Он позволяет заблокировать выполнение прорисовки надписи №откл” второй раз если модуль выключен. Значение этого флага изменяется на противоположное при включении и выключении модуля. Для первичной прорисовки значения параметра при включении модуля, когда нет изменения процента яркости, мы предварительно (при выключении модуля) устанавливает “предыдущее” значение в новый параметр 200. При этом после включения модуля ШИМ, при проверке значения яркости Программа воспримет это как изменение яркости и при этом надпись “откл” измениться на значение текущей яркости.

Предварительно за комментируем строки в проекте

//    pro_bri1p = 1;    // обновить дисплей
//    pro_bri2p = 1;

Что бы получить разнообразную индикацию при включении и при работе регулятора.

Как будет выглядеть индикация дисплея после включения регулятора:

В рабочем режиме когда когда включены два канала:

Когда один из каналов выключен:


Проект на текущем этапе для тестирования:

 

Значок

Проект с использованием MCC часть 14 (2) 719.28 KB 13 downloads

Добавления состояния индикации выключения...
Login Required Message:


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

Используя принцип контроля предыдущего состояния таймера автоотключения и его флаг добавим в нашу программу следующие строки:

uint16_t timer_OFF1p, timer_OFF2p;                  // предыдущее состояние таймера автоотключения

Изменим функцию индикации, для этого в конец добавим проверку условия (пример для канала 1):

        else if(AUTO_OFF1 && (timer_OFF1 != timer_OFF1p))
        {
            timer_OFF1p=timer_OFF1;// сбросить несоответствие
            OLED_curcor(60,4);
            OLED_BinDec(timer_OFF1/2, 0, 0, 4, 1, 2, 2);
        }

Теперь кода мы сделаем двойной щелчок и запустим таймер вместо значений процентов, будет индицироваться работа таймера и будет видно сколько секунд осталось до отключения освещения. По окончанию отсчета появиться стандартное сообщение “откл”.


Проект для проверки:

Значок

Проект с использованием MCC часть 14 (3) 723.44 KB 12 downloads

Часть три - индикация работы таймера отключения...
Login Required Message:


Вроде все, но надписи  канал 1 ,  канал 2  как-то не совсем к теме, сделаем это ближе к домашней автоматике, добавим следующие надписи и заменим наши “каналы”:

    OLED_String ("Освещение", 0, 1, 1, -1, 7);
    OLED_String ("Прихожая", 0, 1, 1, 1, 4);
    OLED_String ("Коридор", 0, 1, 1, 1, 1);

Теперь уже можно все это слепить с корпусом и получить регулятор освещенности для прихожей и коридора с таймером автоотключения. Теперь уходя вечером вам не надо закрывать или дверь в полной темноте, достаточно включить таймер выйти и свет автоматически выключиться.

ОЛЭД дисплей достаточно много потребляет при индикации, в нашем состоянии это может составлять 15-20 мАм. Оставлять его светиться “Это есть нехорошо”, поэтому когда два канала отключены, будем стирать индикацию, а для того, что бы было видно, что устройство работает, нарисуем несколько черточек, в темноте будет видно где расположен “выключатель”.

        if(!ECONOM && !PWM1EN && !PWM2EN) // когда два канала отключены. очистить дисплей и прорисовать линию
        {
            ECONOM = 1;
            OLED_clear (0);
            OLED_String ("------", 0, 1, 1, -1, 3);
        }

В программу мы добавили флаг эконом который отвечает за работу с индикатором когда все ШИМ регуляторы отключены. Это состояние нельзя назвать спящим режимом, т.к. им и не “пахнет” поэтому назовем его “эконом режим”. При включении необходимо будет обновить состояние индикации дисплея, для этого необходимо типа “взбудоражить” наши функции индикации, это будет сделано инициализацией параметров:

            // выполнить функцию один раз
            if(ECONOM) // когда любой канал включен
            {
                ECONOM = 0;
                OLED_clear (0);
                OLED_String ("Освещение", 0, 1, 1, -1, 7);
                OLED_String ("Прихожая", 0, 1, 1, 1, 4);
                OLED_String ("Коридор", 0, 1, 1, 1, 1);
                // для первого включения
                PWM1_LoadDutyValue(brightness_chn1);
                PWM2_LoadDutyValue(brightness_chn2);
                // для прорисовки значений 
                pro_bri1p=200;
                pro_bri2p=200;
                SHIM1=0;
                SHIM2=0;
            }

Уберем из программы еще одно не соответствие. Когда устанавливается яркость 0% света нет, но и ШИМ  не отключен, а по значению отключения ШИМа мы формируем индикацию включен свет или нет, для этого добавим в регуляторы, когда устанавливается яркость 0 – отключается регулятор. Для этого изменим модуль индикации для канала 1 это будет так:

           // индикация для канала 1
            if(!PWM1EN && !SHIM1)
            {
                SHIM1=1;  //
                OLED_String ("откл", 0, 2, 2, 60, 4);
                pro_bri1p=200;
            }
            else if(PWM1EN && (pro_bri1 != pro_bri1p))
            {
                pro_bri1p=pro_bri1;  // сбросить несоответствие
                SHIM1=0;
                OLED_curcor(60,4);
                OLED_BinDec(pro_bri1, 0, 0, 4, 1, 2, 2);
                if(!pro_bri1)
                {
                    __delay_ms (500);   // показать, что значение установленной яркости 0
                    OLED_String ("откл", 0, 2, 2, 60, 4);
                    pro_bri1p=200;  // инициализировать яркость для возможности следующей индикации
                    PWM1EN=0;       // отключить шим
                    SHIM1=1;        // установить флаг
                    NAP1 = 1;       // изменить направление 
                    __delay_ms (500); // показать что регулятор отключен
                }
            }
            else if(AUTO_OFF1 && (timer_OFF1 != timer_OFF1p))
            {
                timer_OFF1p=timer_OFF1;// сбросить несоответствие
                OLED_curcor(60,4);
                OLED_BinDec(timer_OFF1/2, 0, 0, 4, 1, 2, 2);
            }

Что мы тут добавили, при ситуации когда яркость канала 0 и при попытки его включить однократным нажатием на канал, свет не включиться, но чтобы не вводить пользователя в заблуждение контроллер покажет, что яркость ноль и необходимо изменение яркости на полсекунды будет выведено индикация яркости канала и на полсекунды индикация отключения. Пользователю необходимо будет после этого нажать и удерживать кнопку управления каналом для увеличения яркости.


Итоговый проект по части 4:

Значок

Проект с использованием MCC часть 14 (4) 738.51 KB 15 downloads

Итоговый проект по 14 части, Светорегулятор с...
Login Required Message:

 


В следующей главе добавим вывод информации на компьютер и дистанционное управление с ПК. Дошла очередь для изучения USART…


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


  • Стробоскоп для автомобиляСтробоскоп для автомобиля
    Просмотров: 1723 Одним из популярных решений светового тюнинга автомобиля, мотоцикла или скутера стал эффект –  “полицейский стробоскоп“. На база платы ch-c0050 реализовано несколько проектов. В этой статье приводятся две версии …
  • ch-светомузыка и AK4113ch-светомузыка и AK4113
    Просмотров: 1112 Пришло время вернуться к светомузыке. На сегодня использование аналогового входа стало непрактичным, на сегодня необходимо использовать S/PDIF и Toslink. С этим надо было как то разобрать, что это …
  • LED модуль P10C4V12LED модуль P10C4V12
    Просмотров: 2794 LED панели на обычных регистрах типа 74HC595. Они выпускаются как монохромные так двух и полно цветные, особенность, что они предназначены для текстовой информации и имеют один уровень яркости. Общую яркость …
  • Гаджеты для домашней автоматики – Датчик движенияГаджеты для домашней автоматики – Датчик движения
    Просмотров: 1284 Управление светодиодным освещением – Датчик движения. Данный гаджет предназначен для управления освещением рабочих столов (кухонных столов), освещение прихожих, освещение зеркал в прихожих, автоматическое включение света в коридорах. Датчик позволяет …
  • Модуль CAN в микроконтроллерах PIC18Модуль CAN в микроконтроллерах PIC18
    Просмотров: 5326 Введение   CAN последовательный интерфейс связи, который эффективно поддерживает распределенное управление в реальном масштабе времени с высокой помехозащищенностью. Протокол связи полностью определен Robert Bosch GmbH, в спецификации требований …
  • ch-4060 – регулятор температуры и влажности на датчике DHT11/DHT22/AM2302ch-4060 – регулятор температуры и влажности на датчике DHT11/DHT22/AM2302
    Просмотров: 2188 На плате ch-4000 очень легко собрать устройство регулятора температуры и влажности. Датчик DHT11  самый недорогой вариант для создания такого устройства, правда точность его не велика, но для бытовых устройств …
  • Контроллер управления светодиодным освещением с дистанционным управлениемКонтроллер управления светодиодным освещением с дистанционным управлением
    Просмотров: 1822 Все активнее светодиоды входят в нашу жизнь. Всё эффективнее становится светодиодное освещение. Всё ниже опускаются цены. Всё больше появляется возможностей получения сочных цветов, простоты в управлении. Всё чаще …
  • Датчик контроля протечки воды ch-c0020Датчик контроля протечки воды ch-c0020
    Просмотров: 1789 Как здорово летом под теплым дождем с тобою вдвоем оказаться. Как классно по лужам бежать босиком, с тобою играть и смеяться! Но совсем грустно оказаться под таким дождем, который течет с …
  • MPLAB® Harmony – или как это просто! Часть 3.MPLAB® Harmony – или как это просто! Часть 3.
    Просмотров: 1866 Часть третья – копнём немного глубже. Вы наверное заметили, что во второй главе, вроде сначала все шло как по маслу, а потом, что бы заморгали светики, я вставил …
  • Простой сенсорный регулятор светаПростой сенсорный регулятор света
    Просмотров: 2181 Простой сенсорный регулятор. Проект – 2007 года. Регулятор выполнена на микроконтроллере PIC12F683 и имеет минимальное количество элементов. Выполняет стандартные функции, включение выключение света, изменение яркости, запоминание последнего установленного уровня …



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

2 комментария для “Проект с использованием MCC часть 14

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

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