├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
├── dimBresMultiTest
│ └── dimBresMultiTest.ino
├── dimBresTest
│ └── dimBresTest.ino
├── dimFewTestHard
│ └── dimMultiTestHard.ino
├── dimFewTestSoft
│ └── dimMultiTestSoft.ino
├── dimTestHard
│ └── dimTestHard.ino
└── dimTestSoft
│ └── dimTestSoft.ino
├── keywords.txt
├── library.properties
└── src
└── GyverDimmer.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AlexGyver
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/GyverDimmer/releases/latest/download/GyverDimmer.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/GyverDimmer)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/GyverDimmer?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # GyverDimmer
10 | Библиотека для управления симисторным диммером с Arduino
11 | - Одноканальный и многоканальный диммер по алгоритму Брезенхема
12 | - Одноканальный и многоканальный фазовый диммер
13 |
14 | ### Совместимость
15 | Совместима со всеми Arduino платформами (используются Arduino-функции)
16 |
17 | ## Содержание
18 | - [Установка](#install)
19 | - [Инициализация](#init)
20 | - [Использование](#usage)
21 | - [Пример](#example)
22 | - [Версии](#versions)
23 | - [Баги и обратная связь](#feedback)
24 |
25 |
26 | ## Установка
27 | - Библиотеку можно найти по названию **GyverDimmer** и установить через менеджер библиотек в:
28 | - Arduino IDE
29 | - Arduino IDE v2
30 | - PlatformIO
31 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverDimmer/archive/refs/heads/main.zip) .zip архивом для ручной установки:
32 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
33 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
34 | - Распаковать и положить в *Документы/Arduino/libraries/*
35 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
36 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
37 | ### Обновление
38 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
39 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
40 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
41 |
42 |
43 |
44 | ## Инициализация
45 | ```cpp
46 | DimmerBres<пин> dim; // диммер по Брезенхему
47 | DimmerBresMulti<количество> dim; // многоканальный диммер по Брезенхему
48 | Dimmer<пин> dim; // фазовый диммер
49 | DimmerMulti<количество> dim; // многоканальный фазовый диммер
50 | ```
51 |
52 |
53 | ## Использование
54 | ```cpp
55 | // ====== DimmerBres ======
56 | void write(uint8_t dim); // установить величину диммирования 0-255
57 | void tick(); // вызывать в прерывании детектора нуля
58 |
59 | // ====== DimmerBresMulti ======
60 | void attach(uint8_t num, uint8_t pin); // подключить канал под номером num на пин pin
61 | void write(uint8_t ch, uint8_t dim); // установить величину диммирования 0-255 на канал ch
62 | void tick(); // вызывать в прерывании детектора нуля
63 |
64 | // ====== Dimmer ======
65 | void write(uint8_t dim); // установить величину диммирования 0-255
66 | bool tickZero(); // вызывать в прерывании детектора нуля
67 | void tickTimer(); // вызывать в прерывании таймера
68 | int getPeriod(); // получить период для таймера
69 |
70 | // ====== DimmerMulti ======
71 | void attach(uint8_t num, uint8_t pin); // подключить канал под номером num на пин pin
72 | void write(uint8_t ch, uint8_t dim); // установить величину диммирования 0-255 на канал ch
73 | bool tickZero(); // вызывать в прерывании детектора нуля
74 | void tickTimer(); // вызывать в прерывании таймера
75 | int getPeriod(); // получить период для таймера
76 | ```
77 |
78 |
79 | ## Пример
80 | Остальные примеры смотри в **examples**!
81 | ```cpp
82 | // тест одного канала по Брезенхему
83 |
84 | #define D_PIN 5
85 | // zero cross на D2
86 |
87 | #include
88 | DimmerBres dim; // указать пин диммера
89 |
90 | void setup() {
91 | // завести прерывание на детектор нуля
92 | attachInterrupt(0, isr, RISING); // D2 == 0
93 | }
94 |
95 | void isr() {
96 | dim.tick(); // вызывать тик в прерывании детектора нуля
97 | }
98 |
99 | void loop() {
100 | // принимает 0-255
101 | dim.write(analogRead(A0) / 4);
102 | delay(100);
103 | }
104 | ```
105 |
106 |
107 | ## Версии
108 | - v1.0
109 | - v1.1 - переделан FastIO
110 | - v1.1.1 - убран FastIO
111 | - v1.2 - исправил баг в DimmerBres и DimmerBresMulti
112 |
113 |
114 | ## Баги и обратная связь
115 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
116 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
117 |
118 |
119 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
120 | - Версия библиотеки
121 | - Какой используется МК
122 | - Версия SDK (для ESP)
123 | - Версия Arduino IDE
124 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
125 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
126 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
127 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # GyverDimmer
4 | Triac dimmer control library with Arduino
5 | - Single and multi-channel Bresenham dimmer
6 | - Single and multi-channel phase dimmer
7 |
8 | ### Compatibility
9 | Compatible with all Arduino platforms (using Arduino functions)
10 |
11 | ## Content
12 | - [Install](#install)
13 | - [Initialization](#init)
14 | - [Usage](#usage)
15 | - [Example](#example)
16 | - [Versions](#versions)
17 | - [Bugs and feedback](#feedback)
18 |
19 |
20 | ## Installation
21 | - The library can be found by the name **GyverDimmer** and installed via the library manager in:
22 | - Arduino IDE
23 | - Arduino IDE v2
24 | - PlatformIO
25 | - [Download library](https://github.com/GyverLibs/GyverDimmer/archive/refs/heads/main.zip) .zip archive for manual installation:
26 | - Unzip and put in *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
27 | - Unzip and put in *C:\Program Files\Arduino\libraries* (Windows x32)
28 | - Unpack and put in *Documents/Arduino/libraries/*
29 | - (Arduino IDE) automatic installation from .zip: *Sketch/Include library/Add .ZIP library…* and specify the downloaded archive
30 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE% D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
31 |
32 |
33 | ## Initialization
34 | ```cpp
35 | DimmerBres dim;// Bresenham dimmer
36 | DimmerBresMulti dim; // Bresenham multi-channel dimmer
37 | Dimmer dim; // phase dimmer
38 | DimmerMulti dim; // multi-channel phase dimmer
39 | ```
40 |
41 |
42 | ## Usage
43 | ```cpp
44 | // ====== DimmerBres ======
45 | void write(uint8_t dim); // set dimming amount 0-255
46 | void tick(); // call in zero detector interrupt
47 |
48 | // ====== DimmerBresMulti ======
49 | void attach(uint8_t num, uint8_t pin); // connect channel number num to pin pin
50 | void write(uint8_t ch, uint8_t dim); // set dimming amount 0-255 per channel ch
51 | void tick(); // call in zero detector interrupt
52 |
53 | // ====== Dimmer ======
54 | void write(uint8_t dim); // set dimming amount 0-255
55 | bool tickZero(); // call in zero detector interrupt
56 | void tickTimer(); // call in a timer interrupt
57 | int getPeriod(); // get period for timer
58 |
59 | // ====== DimmerMulti ======
60 | void attach(uint8_t num, uint8_t pin); // connect channel number num to pin pin
61 | void write(uint8_t ch, uint8_t dim); // set dimming amount 0-255 per channel ch
62 | bool tickZero(); // call in zero detector interrupt
63 | void tickTimer(); // call in a timer interrupt
64 | int getPeriod(); // get period for timer
65 | ```
66 |
67 |
68 | ## Example
69 | See **examples** for other examples!
70 | ```cpp
71 | // test of one channel according to Bresenham
72 |
73 | #define D_PIN 5
74 | // zero cross on D2
75 |
76 | #include
77 | DimmerBres dim; // specify dimmer pin
78 |
79 | void setup() {
80 | // start an interrupt on the zero detector
81 | attachInterrupt(0, isr, RISING); // D2 == 0
82 | }
83 |
84 | void isr() {
85 | dim.tick(); // call tick in null detector interrupt
86 | }
87 |
88 | void loop() {
89 | // takes 0-255
90 | dim.write(analogRead(A0) / 4);
91 | delay(100);
92 | }
93 | ```
94 |
95 |
96 | ## Versions
97 | - v1.0
98 | - v1.1 - redesigned FastIO
99 | - v1.1.1 - yBran FastIO
100 | - v1.2 - fixed bug in DimmerBres and DimmerBresMulti
101 |
102 |
103 | ## Bugs and feedback
104 | When you find bugs, create an **Issue**, or better, immediately write to the mail [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
105 | The library is open for revision and your **Pull Request**'s!
--------------------------------------------------------------------------------
/examples/dimBresMultiTest/dimBresMultiTest.ino:
--------------------------------------------------------------------------------
1 | // тест нескольких диммеров по Брезенхему
2 | // zero cross на D2
3 |
4 | #include
5 | DimmerBresMulti<2> dim; // указать количество диммеров
6 |
7 | void setup() {
8 | // завести общее прерывание на детектор нуля
9 | attachInterrupt(0, isr, RISING); // D2 == 0
10 |
11 | // подключить пины
12 | dim.attach(0, 4); // канал 0, пин 4
13 | dim.attach(1, 5); // канал 1, пин 5
14 | }
15 |
16 | void isr() {
17 | dim.tick(); // вызывать тик в прерывании детектора нуля
18 | }
19 |
20 | void loop() {
21 | byte val = analogRead(A0) / 4;
22 | // врубаем, принимает 0-255
23 | dim.write(0, val); // канал 0
24 | dim.write(1, 255 - val); // канал 1
25 | delay(100);
26 | }
27 |
--------------------------------------------------------------------------------
/examples/dimBresTest/dimBresTest.ino:
--------------------------------------------------------------------------------
1 | // тест одного канала по Брезенхему
2 |
3 | #define D_PIN 5
4 | // zero cross на D2
5 |
6 | #include
7 | DimmerBres dim; // указать пин диммера
8 |
9 | void setup() {
10 | // завести прерывание на детектор нуля
11 | attachInterrupt(0, isr, RISING); // D2 == 0
12 | }
13 |
14 | void isr() {
15 | dim.tick(); // вызывать тик в прерывании детектора нуля
16 | }
17 |
18 | void loop() {
19 | // принимает 0-255
20 | dim.write(analogRead(A0) / 4);
21 | delay(100);
22 | }
23 |
--------------------------------------------------------------------------------
/examples/dimFewTestHard/dimMultiTestHard.ino:
--------------------------------------------------------------------------------
1 | // тест многоканального диммера
2 | // библиотека универсальная, поэтому требуется свой таймер
3 | // в этом примере делаем на аппаратном таймере
4 | #include // библиотека таймера
5 |
6 | // zero cross на D2
7 |
8 | #include
9 | DimmerMulti<2> dim; // указать количество диммеров
10 | //DimmerMulti<2> dim(60); // можно указать 60 Гц (умолч 50)
11 |
12 | void setup() {
13 | // завести прерывание на детектор нуля
14 | attachInterrupt(0, isr, RISING); // D2 == 0
15 |
16 | // разрешаем прерывания по таймеру
17 | Timer2.enableISR();
18 |
19 | // настроить таймер на период в мкс (37 us для 50 гц сети)
20 | Timer2.setPeriod(dim.getPeriod());
21 |
22 | // подключить пины
23 | dim.attach(0, 4); // канал 0, пин 4
24 | dim.attach(1, 5); // канал 1, пин 5
25 | }
26 |
27 | // прерывание детектора нуля
28 | void isr() {
29 | // вызывать в прерывании детектора нуля
30 | dim.tickZero();
31 | Timer2.restart();
32 | }
33 |
34 | // прерывание таймера
35 | ISR(TIMER2_A) {
36 | dim.tickTimer(); // вызвать tickTimer()
37 | }
38 |
39 | void loop() {
40 | byte val = analogRead(A0) / 4;
41 | // врубаем, принимает 0-255
42 | dim.write(0, val); // канал 0
43 | dim.write(1, 255 - val); // канал 1
44 | delay(100);
45 | }
46 |
--------------------------------------------------------------------------------
/examples/dimFewTestSoft/dimMultiTestSoft.ino:
--------------------------------------------------------------------------------
1 | // тест многоканального диммера
2 | // библиотека универсальная, поэтому требуется свой таймер
3 | // в этом примере делаем на микросе!
4 |
5 | class TimerUs {
6 | public:
7 | bool ready() {
8 | if (state && micros() - tmr >= prd) {
9 | tmr = micros();
10 | return true;
11 | }
12 | return false;
13 | }
14 | void stop() {
15 | state = false;
16 | }
17 | void restart() {
18 | tmr = micros();
19 | state = true;
20 | }
21 | void setPeriod(uint32_t period) {
22 | restart();
23 | prd = period;
24 | if (prd == 0) prd++;
25 | }
26 |
27 | private:
28 | bool state = 0;
29 | uint32_t tmr = 0, prd = 0;
30 | };
31 | TimerUs timer;
32 |
33 | // zero cross на D2
34 |
35 | #include
36 | DimmerMulti<2> dim; // указать количество диммеров
37 | //DimmerMulti<2> dim(60); // можно указать 60 Гц (умолч 50)
38 |
39 | void setup() {
40 | // завести прерывание на детектор нуля
41 | attachInterrupt(0, isr, RISING); // D2 == 0
42 |
43 | // настроить таймер на период в мкс (37 us для 50 гц сети)
44 | timer.setPeriod(dim.getPeriod());
45 |
46 | // подключить пины
47 | dim.attach(0, 4); // канал 0, пин 4
48 | dim.attach(1, 5); // канал 1, пин 5
49 | }
50 |
51 | void isr() {
52 | // вызывать в прерывании детектора нуля
53 | dim.tickZero();
54 | timer.restart();
55 | }
56 |
57 | void loop() {
58 | byte val = analogRead(A0) / 4;
59 | // врубаем, принимает 0-255
60 | dim.write(0, val); // канал 0
61 | dim.write(1, 255 - val); // канал 1
62 | delay(100);
63 | }
64 |
65 | void yield() {
66 | // в "прерывании" таймера
67 | if (timer.ready()) dim.tickTimer(); // вызвать tickTimer()
68 | }
69 |
--------------------------------------------------------------------------------
/examples/dimTestHard/dimTestHard.ino:
--------------------------------------------------------------------------------
1 | // тест одного канала
2 | // библиотека универсальная, поэтому требуется свой таймер
3 | // в этом примере делаем на аппаратном таймере
4 | #include // библиотека таймера
5 |
6 | #define D_PIN 5
7 | // zero cross на D2
8 |
9 | #include
10 | Dimmer dim; // указать пин диммера
11 | //Dimmer dim(60); // можно указать 60 Гц (умолч 50)
12 |
13 | void setup() {
14 | // завести прерывание на детектор нуля
15 | attachInterrupt(0, isr, RISING); // D2 == 0
16 |
17 | // разрешаем прерывания по таймеру
18 | Timer2.enableISR();
19 | }
20 |
21 | // прерывание детектора нуля
22 | void isr() {
23 | // вызывать в прерывании детектора нуля
24 | // если tickZero() - true - нужно перезапустить таймер с периодом getPeriod()
25 | if (dim.tickZero()) Timer2.setPeriod(dim.getPeriod());
26 | else Timer2.restart();
27 | // иначе перезапустить со старым
28 | }
29 |
30 | // прерывание таймера
31 | ISR(TIMER2_A) {
32 | dim.tickTimer(); // вызвать tickTimer()
33 | Timer2.stop(); // останавливаем таймер
34 | }
35 |
36 | void loop() {
37 | dim.write(analogRead(A0) / 4); // принимает 0-255
38 | delay(100);
39 | }
40 |
--------------------------------------------------------------------------------
/examples/dimTestSoft/dimTestSoft.ino:
--------------------------------------------------------------------------------
1 | // тест одноканального диммера
2 | // библиотека универсальная, поэтому требуется свой таймер
3 | // в этом примере делаем на микросе!
4 |
5 | class TimerUs {
6 | public:
7 | bool ready() {
8 | if (state && micros() - tmr >= prd) {
9 | tmr = micros();
10 | return true;
11 | }
12 | return false;
13 | }
14 | void stop() {
15 | state = false;
16 | }
17 | void restart() {
18 | tmr = micros();
19 | state = true;
20 | }
21 | void setPeriod(uint32_t period) {
22 | restart();
23 | prd = period;
24 | if (prd == 0) prd++;
25 | }
26 |
27 | private:
28 | bool state = 0;
29 | uint32_t tmr = 0, prd = 0;
30 | };
31 | TimerUs timer;
32 |
33 | // zero cross на D2
34 |
35 | #include
36 | Dimmer dim; // указать пин диммера
37 | //Dimmer dim(60); // можно указать 60 Гц (умолч 50)
38 |
39 | void setup() {
40 | // завести прерывание на детектор нуля
41 | attachInterrupt(0, isr, RISING); // D2 == 0
42 | }
43 |
44 | void isr() {
45 | // вызывать в прерывании детектора нуля
46 | // если tickZero() - true - нужно перезапустить таймер с периодом getPeriod()
47 | if (dim.tickZero()) timer.setPeriod(dim.getPeriod());
48 | else timer.restart();
49 | // иначе перезапустить со старым
50 | }
51 |
52 | void loop() {
53 | // в "прерывании" таймера
54 | if (timer.ready()) {
55 | dim.tickTimer(); // вызвать tickTimer()
56 | timer.stop(); // остановить таймер
57 | }
58 | dim.write(analogRead(A0) / 4); // принимает 0-255
59 | }
60 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For GyverDimmer
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | GyverDimmer KEYWORD1
10 | DimmerBres KEYWORD1
11 | DimmerBresMulti KEYWORD1
12 | Dimmer KEYWORD1
13 | DimmerMulti KEYWORD1
14 |
15 | #######################################
16 | # Methods and Functions (KEYWORD2)
17 | #######################################
18 |
19 | attach KEYWORD2
20 | write KEYWORD2
21 | tickZero KEYWORD2
22 | tickTimer KEYWORD2
23 | tick KEYWORD2
24 | getPeriod KEYWORD2
25 |
26 | #######################################
27 | # Constants (LITERAL1)
28 | #######################################
29 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GyverDimmer
2 | version=1.2.1
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Phase and Bresenham algorithm for AC triac dimmer
6 | paragraph=Phase and Bresenham algorithm for AC triac dimmer
7 | category=Device Control
8 | url=https://github.com/GyverLibs/GyverDimmer
9 | architectures=*
10 | depends=GyverIO
--------------------------------------------------------------------------------
/src/GyverDimmer.h:
--------------------------------------------------------------------------------
1 | /*
2 | Библиотека для управления симисторным диммером с Arduino
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/GyverDimmer
5 | Возможности:
6 | - Одноканальный и многоканальный диммер по алгоритму Брезенхема
7 | - Одноканальный и многоканальный фазовый диммер
8 |
9 | AlexGyver, alex@alexgyver.ru
10 | https://alexgyver.ru/
11 | MIT License
12 |
13 | Версии:
14 | v1.0 - релиз
15 | v1.1 - переделан FastIO
16 | v1.1.1 - убран FastIO
17 | v1.2 - исправил баг в DimmerBres и DimmerBresMulti
18 | */
19 |
20 | #ifndef GyverDimmer_h
21 | #define GyverDimmer_h
22 | #include
23 | #include
24 |
25 | // брезенхем одноканальный
26 | template
27 | class DimmerBres {
28 | public:
29 | DimmerBres() {
30 | gio::init(_D_PIN, OUTPUT);
31 | gio::write(_D_PIN, LOW);
32 | }
33 |
34 | void write(uint8_t dim) {
35 | dimmer = dim;
36 | }
37 |
38 | void tick() {
39 | uint16_t val = ((uint16_t)++count * dimmer) >> 8;
40 | if (lastVal != (val != last)) gio::write(_D_PIN, val != last);
41 | lastVal = (val != last);
42 | last = val;
43 | }
44 |
45 | private:
46 | uint8_t count = 0, last = 0, lastVal = 0, dimmer = 0;
47 | };
48 |
49 | // брезенхем многоканальный
50 | template
51 | class DimmerBresMulti {
52 | public:
53 | void attach(uint8_t num, uint8_t pin) {
54 | dimPins[num] = pin;
55 | gio::init(pin, OUTPUT);
56 | }
57 |
58 | void write(uint8_t ch, uint8_t dim) {
59 | dimmer[ch] = dim;
60 | }
61 |
62 | void tick() {
63 | count++;
64 | for (uint8_t i = 0; i < _D_AMOUNT; i++) {
65 | uint16_t val = ((uint16_t)count * dimmer[i]) >> 8;
66 | if (lastState[i] != (val != last[i])) gio::write(dimPins[i], val != last[i]);
67 | lastState[i] = (val != last[i]);
68 | last[i] = val;
69 | }
70 | }
71 |
72 | private:
73 | uint8_t count, last[_D_AMOUNT], lastState[_D_AMOUNT], dimmer[_D_AMOUNT], dimPins[_D_AMOUNT];
74 | };
75 |
76 | // плавный диммер одноканальный
77 | template
78 | class Dimmer {
79 | public:
80 | Dimmer(uint8_t freq = 50) {
81 | gio::init(_D_PIN, OUTPUT);
82 | gio::write(_D_PIN, LOW);
83 | maxVal = (freq == 50) ? 9300 : 7600;
84 | }
85 |
86 | void write(uint8_t dim) {
87 | dimmer = map(dim, 0, 255, maxVal, 500);
88 | }
89 |
90 | bool tickZero() {
91 | gio::write(_D_PIN, LOW);
92 | if (lastDim != dimmer) {
93 | lastDim = dimmer;
94 | return true;
95 | }
96 | return false;
97 | }
98 |
99 | void tickTimer() {
100 | gio::write(_D_PIN, HIGH);
101 | }
102 |
103 | uint16_t getPeriod() {
104 | return dimmer;
105 | }
106 |
107 | private:
108 | uint16_t dimmer = 0, lastDim = 0, maxVal = 0;
109 | };
110 |
111 | // плавный диммер многоканальный
112 | template
113 | class DimmerMulti {
114 | public:
115 | DimmerMulti(uint8_t freq = 50) {
116 | maxVal = (freq == 50) ? 9300 : 7600;
117 | }
118 |
119 | void attach(uint8_t num, uint8_t pin) {
120 | gio::init(pin, OUTPUT);
121 | dimPins[num] = pin;
122 | }
123 |
124 | void write(uint8_t ch, uint8_t dim) {
125 | dimmer[ch] = dim;
126 | }
127 |
128 | void tickZero() {
129 | counter = 255;
130 | }
131 |
132 | void tickTimer() {
133 | for (uint8_t i = 0; i < _D_AMOUNT; i++) {
134 | if (counter == dimmer[i]) gio::write(dimPins[i], 1); // на текущем тике включаем
135 | else if (counter == dimmer[i] - 1) gio::write(dimPins[i], 0); // на следующем выключаем
136 | }
137 | counter--;
138 | }
139 |
140 | uint16_t getPeriod() {
141 | return (maxVal == 9300) ? 37 : 31; // us
142 | }
143 |
144 | private:
145 | uint8_t dimmer[_D_AMOUNT], dimPins[_D_AMOUNT];
146 | uint16_t maxVal = 0;
147 | volatile uint16_t counter = 0;
148 | };
149 |
150 | #endif
151 |
--------------------------------------------------------------------------------