├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
├── GyverPower_example
│ └── GyverPower_example.ino
├── WDT_calibration
│ └── WDT_calibration.ino
├── customSleepMillis
│ └── customSleepMillis.ino
├── hardwareControl
│ └── hardwareControl.ino
├── interruptWakeSleep
│ └── interruptWakeSleep.ino
├── interruptWakeSleepDelay
│ └── interruptWakeSleepDelay.ino
├── lowClock
│ └── lowClock.ino
├── lowClockTimeCorrect
│ └── lowClockTimeCorrect.ino
├── power_mode
│ └── power_mode.ino
├── powersaveMillis
│ ├── powersaveMillis.ino
│ └── uptime2.h
├── simpleWakePeriodic
│ └── simpleWakePeriodic.ino
├── sleepDelayMillis
│ └── sleepDelayMillis.ino
├── sleepDelayTest
│ └── sleepDelayTest.ino
├── sleepMillis
│ └── sleepMillis.ino
└── sleeptime
│ └── sleeptime.ino
├── keywords.txt
├── library.properties
└── src
├── GyverPower.cpp
├── GyverPower.h
└── powerConstants.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 | [](#versions)
2 | [](https://alexgyver.ru/)
3 | [](https://alexgyver.ru/support_alex/)
4 |
5 | [](https://github-com.translate.goog/GyverLibs/GyverPower?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | # GyverPower
8 | GyverPower - библиотека для управления энергопотреблением МК AVR
9 | - Управление системным клоком
10 | - Включение/выключение периферии:
11 | - BOD
12 | - Таймеры
13 | - I2C/UART/SPI
14 | - USB
15 | - ADC
16 | - Сон в разных режимах (список ниже)
17 | - Сон на любой период
18 | - Калибровка таймера для точного времени сна
19 | - Корректировка millis()
20 |
21 | ### Совместимость
22 | - Atmega2560/32u4/328
23 | - Attiny85/84/167
24 |
25 | ### Документация
26 | К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverPower/)
27 |
28 | ## Содержание
29 | - [Использование](#usage)
30 | - [Пример](#example)
31 | - [Установка](#install)
32 | - [Версии](#versions)
33 | - [Баги и обратная связь](#feedback)
34 |
35 |
36 |
37 | ## Использование
38 | ```cpp
39 | void hardwareEnable(uint16_t data); // включение указанной периферии (см. ниже "Константы периферии")
40 | void hardwareDisable(uint16_t data); // выключение указанной периферии (см. ниже "Константы периферии")
41 | void setSystemPrescaler(prescalers_t prescaler); // установка делителя системной частоты
42 | void adjustInternalClock(int8_t adj); // подстройка частоты внутреннего генератора (число -120...+120)
43 | void bodInSleep(bool en); // Brown-out detector в режиме сна (true вкл - false выкл) [умолч. false]
44 |
45 | void setSleepMode(sleepmodes_t mode); // установка текущего режима сна [умолч. POWERDOWN_SLEEP]
46 | void sleep(sleepprds_t period); // сон на стандартный период
47 | bool inSleep(); // вернёт true, если МК спит для проверки в прерывании
48 |
49 | uint16_t sleepDelay(uint32_t ms); // сон на произвольный период в миллисекундах, возвращает остаток времени для коррекции таймеров
50 | uint16_t sleepDelay(uint32_t ms, uint32_t sec, uint16_t min = 0, uint16_t hour = 0, uint16_t day = 0);
51 | void setSleepResolution(sleepprds_t period); // установить разрешение сна sleepDelay() [умолч. SLEEP_128MS]
52 | void correctMillis(bool state); // корректировать миллис на время сна sleepDelay() [умолч. true]
53 | void calibrate(); // автоматическая калибровка таймера сна sleepDelay(), выполняется 16 мс
54 | void wakeUp(); // помогает выйти из sleepDelay() прерыванием (вызывать в будящем прерывании)
55 | ```
56 |
57 | ```cpp
58 | ===== РЕЖИМЫ СНА для setSleepMode() =====
59 | IDLE_SLEEP - Легкий сон, отключается только клок CPU и Flash, просыпается мгновенно от любых прерываний
60 | ADC_SLEEP - Легкий сон, отключается CPU и system clock, АЦП начинает преобразование при уходе в сон (см. пример ADCinSleep)
61 | EXTSTANDBY_SLEEP - Глубокий сон, идентичен POWERSAVE_SLEEP + system clock активен
62 | STANDBY_SLEEP - Глубокий сон, идентичен POWERDOWN_SLEEP + system clock активен
63 | POWERSAVE_SLEEP - Глубокий сон, идентичен POWERDOWN_SLEEP + timer 2 активен (+ можно проснуться от его прерываний), можно использовать для счета времени (см. пример powersaveMillis)
64 | POWERDOWN_SLEEP - Наиболее глубокий сон, отключается всё кроме WDT и внешних прерываний, просыпается от аппаратных (обычных + PCINT) или WDT
65 |
66 | ===== ПЕРИОДЫ СНА для sleep() и setSleepResolution() =====
67 | SLEEP_16MS
68 | SLEEP_32MS
69 | SLEEP_64MS
70 | SLEEP_128MS
71 | SLEEP_256MS
72 | SLEEP_512MS
73 | SLEEP_1024MS
74 | SLEEP_2048MS
75 | SLEEP_4096MS
76 | SLEEP_8192MS
77 | SLEEP_FOREVER - вечный сон
78 |
79 | ===== КОНСТАНТЫ ДЕЛИТЕЛЯ для setSystemPrescaler() =====
80 | PRESCALER_1
81 | PRESCALER_2
82 | PRESCALER_4
83 | PRESCALER_8
84 | PRESCALER_16
85 | PRESCALER_32
86 | PRESCALER_64
87 | PRESCALER_128
88 | PRESCALER_256
89 |
90 | ===== КОНСТАНТЫ ПЕРИФЕРИИ для hardwareDisable() и hardwareEnable() =====
91 | PWR_ALL - всё железо
92 | PWR_ADC - АЦП и компаратор
93 | PWR_TIMER1 - Таймер 0
94 | PWR_TIMER0 - Таймер 1
95 | PWR_TIMER2 - Таймер 2
96 | PWR_TIMER3 - Таймер 3
97 | PWR_TIMER4 - Таймер 4
98 | PWR_TIMER5 - Таймер 5
99 | PWR_UART0 - Serial 0
100 | PWR_UART1 - Serial 1
101 | PWR_UART2 - Serial 2
102 | PWR_UART3 - Serial 3
103 | PWR_I2C - Wire
104 | PWR_SPI - SPI
105 | PWR_USB - USB
106 | PWR_USI - Wire + Spi (ATtinyXX)
107 | PWR_LIN - USART LIN (ATtinyXX)
108 | ```
109 |
110 | ### Простой сон
111 | - Режим сна настраивается в `power.setSleepMode()`, по умолчанию активен `POWERDOWN_SLEEP` (остальные см. выше).
112 | - Чтобы уснуть - вызываем `power.sleep()` с указанием одного из стандартных периодов (см. выше).
113 | - Реальное время сна будет слегка отличаться, так как "таймер сна" не очень точный.
114 |
115 | ### Сон на любой период
116 | - Режим сна настраивается в `power.setSleepMode()`, по умолчанию активен `POWERDOWN_SLEEP` (остальные см. выше).
117 | - Чтобы уснуть - вызываем `power.sleepDelay()` с указанием периода в миллисекундах (`uint32_t`, до ~50 суток).
118 | *Как это работает? Просто цикл со стандартными периодами сна внутри этой функции.*
119 | - По умолчанию данная функция "спит" периодами по 128 миллисекунд. Время бодрствования между периодами сна составляет около 2.2 мкс (при 16 Мгц),
120 | что составляет 0.0017% от времени сна. Соответственно точность времени сна кратна одному периоду сна. Этот период можно настроить в
121 | `power.setSleepResolution()`, которая принимает те же константы, что и `sleep()`. Если нужен более точный сон - можно поставить 16 мс (`SLEEP_16MS`),
122 | если максимальное энергосбережение - 8 секунд (`SLEEP_8192MS`).
123 | - Для преждевременного пробуждения по прерыванию нужно обязательно вызвать `power.wakeUp()` внутри обработчика прерывания.
124 | - Сон `sleepDelay()` имеет две очень полезные возможности:
125 | - Сон на очень точный период при откалиброванном таймере (см. ниже)
126 | - Сохранение счёта времени `millis()` на время сна (см. пример sleeptime)
127 |
128 | ### Калибровка таймера
129 | В версии 2.0 библиотеки калибровка была упрощена: достаточно вызвать `power.autoCalibrate()` при запуске микроконтроллера. Функция выполняется ~16 мс.
130 | **Внимание! power.setSleepResolution() нужно вызывать после калибровки таймера.**
131 |
132 |
133 |
134 | ## Пример
135 | Остальные примеры смотри в **examples**!
136 | ```cpp
137 | // демо возможностей библиотеки
138 | #include
139 |
140 | void setup() {
141 | pinMode(13, OUTPUT); // настраиваем вывод со светодиодом на выход
142 | Serial.begin(9600);
143 |
144 | power.autoCalibrate(); // автоматическая калибровка
145 |
146 | // отключение ненужной периферии
147 | power.hardwareDisable(PWR_ADC | PWR_TIMER1); // см раздел константы в GyverPower.h, разделяющий знак " | "
148 |
149 | // управление системной частотой
150 | power.setSystemPrescaler(PRESCALER_2); // см константы в GyverPower.h
151 |
152 | // настройка параметров сна
153 | power.setSleepMode(STANDBY_SLEEP); // если нужен другой режим сна, см константы в GyverPower.h (по умолчанию POWERDOWN_SLEEP)
154 | //power.bodInSleep(false); // рекомендуется выключить bod во сне для сохранения энергии (по умолчанию false - уже выключен!!)
155 |
156 | // пример однократного ухода в сон
157 | Serial.println("go to sleep");
158 | delay(100); // даем время на отправку
159 |
160 | power.sleep(SLEEP_2048MS); // спим ~ 2 секунды
161 |
162 | Serial.println("wake up!");
163 | delay(100); // даем время на отправку
164 | }
165 |
166 | void loop() {
167 | // пример циклического сна
168 | power.sleepDelay(1500); // спим 1.5 секунды
169 | digitalWrite(13, !digitalRead(13)); // инвертируем состояние на пине
170 | }
171 | ```
172 |
173 |
174 |
175 | ## Установка
176 | - Библиотеку можно найти по названию **GyverPower** и установить через менеджер библиотек в:
177 | - Arduino IDE
178 | - Arduino IDE v2
179 | - PlatformIO
180 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverPower/archive/refs/heads/main.zip) .zip архивом для ручной установки:
181 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
182 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
183 | - Распаковать и положить в *Документы/Arduino/libraries/*
184 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
185 | - Читай более подробную инструкцию по установке библиотек [здесь](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)
186 |
187 |
188 |
189 | ## Версии
190 | - v1.2 - фикс калибровки
191 | - v1.3 - фикс для 32U4
192 | - v1.4 - добавлен adjustInternalClock
193 | - v1.5 - совместимость с аттини
194 | - v1.6 - ещё совместимость с аттини
195 | - v1.7 - оптимизация, совместимость с ATtiny13
196 | - v1.8 - совместимость с ATmega32U4
197 | - v2.0 - оптимизация памяти, переделан sleepDelay, можно точно узнать фактическое время сна
198 | - v2.0.1 - fix compiler warnings
199 | - v2.0.2 - исправлена ошибка компиляции ATtiny85
200 | - v2.1 - добавлена bool inSleep(), для проверки спит ли МК
201 | - v2.2 - улучшена стабильность
202 |
203 |
204 | ## Баги и обратная связь
205 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
206 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
207 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Gyverpower
4 | Gyverpower - Library for Energy Executive Management MK AVR
5 | - System shock management
6 | - Turning on/off the periphery:
7 | - Bod
8 | - Tiemers
9 | - i2c/uart/spi
10 | - USB
11 | - ADC
12 | - sleep in different modes (list below)
13 | - sleep for any period
14 | - Tiemer calibration for the exact time of sleep
15 | - adjustment Millis ()
16 |
17 | ## compatibility
18 | - Atmega2560/32U4/328
19 | - Attiny85/84/167
20 |
21 | ### Documentation
22 | There is [expanded documentation] to the library (https://alexgyver.ru/gyverpower/)
23 |
24 | ## Content
25 | - [installation] (# Install)
26 | - [initialization] (#init)
27 | - [use] (#usage)
28 | - [Example] (# Example)
29 | - [versions] (#varsions)
30 | - [bugs and feedback] (#fedback)
31 |
32 |
33 | ## Installation
34 | - The library can be found by the name ** gyverpower ** and installed through the library manager in:
35 | - Arduino ide
36 | - Arduino ide v2
37 | - Platformio
38 | - [download the library] (https://github.com/gyverlibs/gyverpower/archive/refs/heads/main.zip) .Zip archive for manual installation:
39 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
40 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
41 | - unpack and put in *documents/arduino/libraries/ *
42 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
43 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
44 | ### Update
45 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
46 | - through the IDE library manager: find the library how to install and click "update"
47 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
48 |
49 |
50 |
51 | ## initialization
52 | No
53 |
54 |
55 | ## Usage
56 | `` `CPP
57 | VOID Hardwareenable (Uint16_T DATA);// inclusion of the specified periphery (see below the "peripheral constants")
58 | VOID HardwareDisable (Uint16_T DATA);// Turning off the specified periphery (see below the "Constant of the Periphery")
59 | VOID SetSystemprescaler (Prescalers_t PressCaler); // Installation of a system frequency divider (see below "Delichela Constant)
60 | VOID Adjustinternalclock (Int8_T Adj);// adjustment of the frequency of the internal generator (number -120 ...+120)
61 |
62 | VOID BODINSLEP (BOOL EN);// Brown -out Detector in sleep mode (True vkl - False cap) by the silence.Disconnected!
63 | VOID setsleepmode (Sleepmodes_t Mode);// Installation of the current sleep regime (see below "Sleep modes")
64 | VOID setsleepResolution (Uint8_t Period);// Set a resolution of sleep (see below the "periods of sleep")
65 |
66 | VOID autocalibrate (VOID);// Automatic calibration of sleep timer, 16 ms is performed
67 | VOID Sleep (Uint8_t Period);// sleep for a fixed period (see below "periods of sleep")
68 | Uint8_t SleepDelay (Uint32_T MS);// Sleep to arbitrary peRiodes in milliseconds (up to 52 days), returns the rest of the time to correct timers
69 | VOID Correctmillis (Bool State);// Correct millis for sleep time SleepDelay () (by default on)
70 | VOID Wakeup (VOID);// Helps to leave SleepDelay an interruption (call in a waking interruption)
71 | Bool Insleep (Void);// will return True if MK sleeps (for verification in interruption)
72 | `` `
73 |
74 | `` `CPP
75 | ===== Sleep modes for setsleepmode () =======
76 | Idle_sleep - light sleep, only a CPU and Flash clock is turned off, it wakes up instantly from any interruption
77 | ADC_SLEP is a light dream, CPU and System Clock are disconnected, ADC begins to transform it when leaving (see Adcinsleep example)
78 | Extstandby_sleep - deep sleep, identical to PowerSave_Sleep + System Clock is active
79 | Standby_sleep - deep sleep, identical to PowerDown_Sleep + System Clock is active
80 | PowerSave_Sleep - deep sleep, identical to powerdown_sleep + timer 2 is active ( + you can wake up from its interruptions), you can use time (see example of powerSavemillis)
81 | PowerDown_Sleep - the deepest sleep, everything is turned off except WDT and external interruptions, wakes up from hardware (ordinary + PCINT) or WDT
82 |
83 | ===== Sleep periods for Sleep () and setsleepresolution () ===========
84 | Sleep_16ms
85 | Sleep_32MS
86 | Sleep_64ms
87 | Sleep_128MS
88 | Sleep_256MS
89 | Sleep_512MS
90 | Sleep_1024ms
91 | Sleep_2048MS
92 | Sleep_4096ms
93 | Sleep_8192MS
94 | Sleep_Forever - Eternal Dream
95 |
96 | ===== The divider constant for setsyStemprescaler () ===========
97 | PressCaler_1
98 | PressCaler_2
99 | PressCaler_4
100 | PressCaler_8
101 | PressCaler_16
102 | PressCaler_32
103 | PressCaler_64
104 | PressCaler_128
105 | PressCaler_256
106 |
107 | ===== The periphery constants for Hardwareedisable () and Hardwareenable () ==========
108 | Pwr_all - all iron
109 | PWR_ADC - ACP and comparator
110 | PWR_Timer1 - timer 0
111 | PWR_Timer0 - TIMER 1
112 | PWR_Timer2 - TIMER 2
113 | PWR_Timer3 - TIMER 3
114 | PWR_Timer4 - TIMER 4
115 | PWR_Timer5 - TIMER 5
116 | PWR_UART0 - Serial 0
117 | PWR_UART1 - Serial 1
118 | PWR_UART2 - Serial 2
119 | PWR_UART3 - Serial 3
120 | PWR_I2C - Wire
121 | PWR_SPI - SPI
122 | PWR_USB - USB
123 | PWR_USI - Wire + SPI (Attinyxx)
124 | PWR_LIN - USART LIN (Attinyxx)
125 | `` `
126 |
127 | ### simple sleep
128 | - Sleep mode is tuned in `Power.setsleepmode ()`, by default, `PowerDown_Sleep` is active (the rest see above).
129 | - To fall asleep, we call `Power.sleep ()` with one of the standard periods (see above).
130 | - The real time of sleep will be slightly different, since the "sleep timer" is not very accurate.
131 |
132 | ### sleep for any period
133 | - Sleep mode is tuned in `Power.setsleepmode ()`, by default, `PowerDown_Sleep` is active (the rest see above).
134 | - To fall asleep, we call `Power.sleepDelay ()` with a period in milliseconds (`uint32_t`, up to ~ 50 days).
135 | *How it works?Just a cycle with standard periods of sleep inside this function.*
136 | - By default, this function “sleeps” with periods of 128 milliseconds.The wakefulness between the periods of sleep is about 2.2 μs (at 16 MHz),
137 | which is 0.0017% of the time of sleep.Accordingly, the accuracy of the time of sleep is multiple of one period of sleep.This period can be configured in
138 | `Power.SetSleepResolution ()`, which accepts the same constants as `Sleep ()`.If you need a more accurate dream, you can put 16 ms (`Sleep_16MS`),
139 | If the maximum energy conservation is 8 seconds (`Sleep_8192MS`).
140 | - For premature awakening for interruption, it is necessary to call `Power.wakeup ()` inside the interruption processor.
141 | - Sleep `SleepDelay ()` has two very useful opportunities:
142 | - sleep for a very accurate period with a calibrated timer (see below)
143 | - Preservation of the time account `millis ()` during sleep (see example of Sleeptime)
144 |
145 | ### Tymer Calibration
146 | In version 2.0 of the library, the calibration was simplified: it is enough to call `Power.autocalibrate ()` when the microcontroller is launched.The function is performed ~ 16 ms.
147 | **Attention!Power.SetsleepResolution () should be called after calibration of the timer. **
148 |
149 |
150 | ## Example
151 | The rest of the examples look at ** Examples **!
152 | `` `CPP
153 | // Demo of the library capabilities
154 | #include
155 |
156 | VOID setup () {
157 | Pinmode (13, output);// set up inCranberries with LED output
158 | Serial.Begin (9600);
159 |
160 | Power.autocalibrate ();// Automatic calibration
161 |
162 | // Disconnecting unnecessary periphery
163 | Power.hardwardedisable (pwr_adc | pwr_timer1);// see Constant section in gyverpower.h, separating the sign "|
164 |
165 | // System frequency management
166 | Power.SetSySteMprescaler (Prescaler_2);// cm constants in gyverpower.h
167 |
168 | // Sleep settings
169 | Power.Setsleepmode (Standby_Sleep);// If you need another sleep mode, cm constants in gyverpower.h (by default PowerDown_Sleep)
170 | //power.BodinSleep (False);// It is recommended to turn off BOD in a dream to preserve energy (by default FALSE - already turned off !!)
171 |
172 | // Example of single care of sleep
173 | Serial.println ("Go to Sleep");
174 | DELAY (100);// Give the time to send
175 |
176 | Power.sleep (Sleep_2048MS);// Sleep ~ 2 seconds
177 |
178 | Serial.println ("Wake Up!");
179 | DELAY (100);// Give the time to send
180 | }
181 |
182 | VOID loop () {
183 | // example of cyclic sleep
184 | Power.SleepDelay (1500);// Sleep 1.5 seconds
185 | DigitalWrite (13,! DigitalRead (13));// Inverting the condition on the pin
186 | }
187 | `` `
188 |
189 |
190 | ## versions
191 | - V1.2 - Calibration Fix
192 | - V1.3 - Fix for 32U4
193 | - v1.4 - Adjustinternalclock added
194 | - V1.5 - compatibility with Attini
195 | - V1.6 - more compatibility with Attini
196 | - V1.7 - optimization, compatibility with Attiny13
197 | - V1.8 - Compatibility with atmega32u4
198 | - V2.0 - memory optimization, redepdlavia remoded, you can definitely find out the actual sleep time
199 | - V2.0.1 - FIX Compiler Warnings
200 | - v2.0.2 - Fixed compilation error attiny85
201 | - V2.1 - Added Bool Insleep (), whether MK sleeps for verification
202 | - V2.2 - Improved stability
203 |
204 |
205 | ## bugs and feedback
206 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
207 | The library is open for refinement and your ** pull Request ** 'ow!
208 |
209 |
210 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
211 | - The version of the library
212 | - What is MK used
213 | - SDK version (for ESP)
214 | - version of Arduino ide
215 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
216 | - what code has been loaded, what work was expected from it and how it works in reality
217 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/GyverPower_example/GyverPower_example.ino:
--------------------------------------------------------------------------------
1 | // демо возможностей библиотеки
2 | #include
3 |
4 | void setup() {
5 | pinMode(13, OUTPUT); // настраиваем вывод со светодиодом на выход
6 | Serial.begin(9600);
7 |
8 | power.autoCalibrate(); // автоматическая калибровка
9 |
10 | // отключение ненужной периферии
11 | power.hardwareDisable(PWR_ADC | PWR_TIMER1); // см раздел константы в GyverPower.h, разделяющий знак " | "
12 |
13 | // управление системной частотой
14 | power.setSystemPrescaler(PRESCALER_2); // см константы в GyverPower.h
15 |
16 | // настройка параметров сна
17 | power.setSleepMode(STANDBY_SLEEP); // если нужен другой режим сна, см константы в GyverPower.h (по умолчанию POWERDOWN_SLEEP)
18 | //power.bodInSleep(false); // рекомендуется выключить bod во сне для сохранения энергии (по умолчанию false - уже выключен!!)
19 |
20 | // пример однократного ухода в сон
21 | Serial.println("go to sleep");
22 | delay(100); // даем время на отправку
23 |
24 | power.sleep(SLEEP_2048MS); // спим ~ 2 секунды
25 |
26 | Serial.println("wake up!");
27 | delay(100); // даем время на отправку
28 | }
29 |
30 | void loop() {
31 | // пример циклического сна
32 | power.sleepDelay(1500); // спим 1.5 секунды
33 | digitalWrite(13, !digitalRead(13)); // инвертируем состояние на пине
34 | }
--------------------------------------------------------------------------------
/examples/WDT_calibration/WDT_calibration.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void setup() {
4 | Serial.begin(9600);
5 | pinMode(13, OUTPUT); // шоб мигать
6 |
7 | // WDT будит МК ото сна, его таймер не очень точный (с завода) и нуждается в калибровке
8 | power.autoCalibrate(); // автоматическая калибровка, выполняется ~16 миллисекунд
9 | }
10 |
11 | void loop() {
12 | // пример циклического сна
13 | power.sleepDelay(1500); // спим ровно 1.5 секунды (мы откалиброваны!)
14 | digitalWrite(13, !digitalRead(13)); // инвертируем состояние на пине
15 | }
--------------------------------------------------------------------------------
/examples/customSleepMillis/customSleepMillis.ino:
--------------------------------------------------------------------------------
1 | // Делаем свой счётчик времени сна
2 | // допустим таймер 0 у нас используется для других целей, но нам
3 | // нужно хотя бы приблизительно считать время и выполнять по нему действия
4 |
5 | #include
6 |
7 | uint32_t myMillis = 0; // наш миллис
8 |
9 | void setup() {
10 | power.autoCalibrate(); // автоматическая калибровка
11 | }
12 |
13 | void loop() {
14 | static uint32_t tmr1, tmr2;
15 |
16 | // "таймер" на 2 секунды
17 | if (myMillis - tmr1 > 2000) {
18 | tmr1 += 2000;
19 | // действие 1
20 | }
21 |
22 | // "таймер" на 10 секунд
23 | if (myMillis - tmr2 > 10000) {
24 | tmr2 += 10000;
25 | // действие 2
26 | }
27 |
28 | // спим 1 секунду (1000 мс)
29 | // sleepDelay возвращает остаток сна в мс, если он есть
30 | byte left = power.sleepDelay(1000);
31 |
32 | // прибавляем и корректируем наш миллис
33 | myMillis += 1000 - left;
34 | }
35 |
--------------------------------------------------------------------------------
/examples/hardwareControl/hardwareControl.ino:
--------------------------------------------------------------------------------
1 | // управление периферией МК
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 | // можно выборочно включать-выключать периферийные блоки МК, разделитель - |
7 | // список констант смотри в GyverPower.h / Константы периферии
8 |
9 | // отключили АЦП, таймеры 1 и 0
10 | power.hardwareDisable(PWR_ADC | PWR_TIMER1 | PWR_TIMER0);
11 |
12 | // включили ADC обратно
13 | power.hardwareEnable(PWR_ADC);
14 | }
15 |
16 | void loop() {
17 | Serial.println(millis());
18 | // отключили таймер 0 - миллис не тикает...
19 | }
20 |
--------------------------------------------------------------------------------
/examples/interruptWakeSleep/interruptWakeSleep.ino:
--------------------------------------------------------------------------------
1 | // просыпаемся по аппаратному прерыванию из sleep
2 | #include
3 |
4 | void setup() {
5 | Serial.begin(9600);
6 |
7 | // кнопка подключена к GND и D3
8 | pinMode(3, INPUT_PULLUP);
9 |
10 | // подключаем прерывание на пин D3 (Arduino NANO)
11 | attachInterrupt(1, isr, FALLING);
12 |
13 | // глубокий сон
14 | power.setSleepMode(POWERDOWN_SLEEP);
15 | }
16 |
17 | // обработчик аппаратного прерывания
18 | void isr() {
19 | // в отличие от sleepDelay, ничего вызывать не нужно!
20 | }
21 |
22 | void loop() {
23 | Serial.println("go sleep");
24 | delay(300);
25 |
26 | // правильно будет вот тут включать прерывание
27 | // attachInterrupt(1, isr, FALLING);
28 |
29 | // спим ~8 секунд, но можем проснуться по кнопке
30 | power.sleep(SLEEP_8192MS);
31 | // тут проснулись, по кнопке или через указанный период
32 |
33 | // а вот тут сразу отключать
34 | // detachInterrupt(1);
35 |
36 | Serial.println("wake up!");
37 | delay(300);
38 | }
39 |
--------------------------------------------------------------------------------
/examples/interruptWakeSleepDelay/interruptWakeSleepDelay.ino:
--------------------------------------------------------------------------------
1 | // просыпаемся по аппаратному прерыванию из sleepDelay
2 |
3 | #include
4 |
5 | // sleepDelay состоит из нескольких sleep, и команда wakeUp()
6 | // позволяет окончательно проснуться по прерыванию.
7 | // Без неё мы будем "досыпать" некоторое время
8 |
9 | void setup() {
10 | Serial.begin(9600);
11 |
12 | // кнопка подключена к GND и D3
13 | pinMode(3, INPUT_PULLUP);
14 |
15 | // подключаем прерывание на пин D3 (Arduino NANO)
16 | attachInterrupt(1, isr, FALLING);
17 |
18 | // глубокий сон
19 | power.setSleepMode(POWERDOWN_SLEEP);
20 | }
21 |
22 | // обработчик аппаратного прерывания
23 | void isr() {
24 | // дёргаем за функцию "проснуться"
25 | // без неё проснёмся чуть позже (через 0-8 секунд)
26 | power.wakeUp();
27 | }
28 |
29 | void loop() {
30 | Serial.println("go sleep");
31 | delay(300);
32 |
33 | // правильно будет вот тут включать прерывание
34 | // attachInterrupt(1, isr, FALLING);
35 |
36 | // спим 12 секунд, но можем проснуться по кнопке
37 | power.sleepDelay(12000);
38 | // тут проснулись по кнопке или через указанный период
39 |
40 | // а вот тут сразу отключать
41 | // detachInterrupt(1);
42 |
43 | Serial.println("wake up!");
44 | delay(300);
45 | }
46 |
--------------------------------------------------------------------------------
/examples/lowClock/lowClock.ino:
--------------------------------------------------------------------------------
1 | // пример управления системной частотой
2 | // мы можем только уменьшить (разделить) системную частоту (на платах ардуино 16 МГц)
3 | // Пониженная частота позволяет чуть снизить потребление или питать МК от пониженного напряжения!
4 |
5 | #include
6 |
7 | void setup() {
8 | power.setSystemPrescaler(PRESCALER_16); // замедляем в 16 раз
9 |
10 | // с понижением системной частоты "уйдут" все завязанные на частоте блоки периферии!
11 | // чтобы сериал завёлся (если нужен), умножаем скорость на замедление
12 | // иначе не заведётся на указанной скорости
13 | Serial.begin(9600 * 16L);
14 |
15 | Serial.println("serial test");
16 | }
17 |
18 | void loop() {
19 | }
20 |
--------------------------------------------------------------------------------
/examples/lowClockTimeCorrect/lowClockTimeCorrect.ino:
--------------------------------------------------------------------------------
1 | // пример управления системной частотой
2 | // мы можем только уменьшить (разделить) системную частоту (на платах ардуино 16 МГц)
3 | // Пониженная частота позволяет чуть снизить потребление или питать МК от пониженного напряжения!
4 | #include
5 |
6 | // с понижением частоты "уйдут" функции времени
7 | // для их коррекции можно сделать так:
8 | #define millis() (millis() << (CLKPR & 0xF))
9 | #define micros() (micros() << (CLKPR & 0xF))
10 | #define delay(x) delay((x) >> (CLKPR & 0xf))
11 | #define delayMicroseconds(x) delayMicroseconds((x) >> (CLKPR & 0xf))
12 |
13 | // данные дефайны нужно прописать ПЕРЕД подключением остальных библиотек.
14 | // Таким образом дефайн сможет "проникнуть" в библиотеку и скорректировать
15 | // работу используемых там функций времени
16 |
17 | void setup() {
18 | power.setSystemPrescaler(PRESCALER_16); // замедляем в 16 раз
19 | pinMode(13, OUTPUT);
20 | }
21 |
22 | void loop() {
23 | digitalWrite(13, !digitalRead(13)); // мигаем
24 | delay(1000); // держит 1 секунду, несмотря на пониженный клок!
25 | }
26 |
--------------------------------------------------------------------------------
/examples/power_mode/power_mode.ino:
--------------------------------------------------------------------------------
1 | // пример настроек сна
2 | #include
3 |
4 | void setup() {
5 | pinMode(13, OUTPUT); // шоб мигать
6 |
7 | // отключение ненужной периферии
8 | power.hardwareDisable(PWR_ADC | PWR_TIMER1); // см. константы, разделяющий знак " | "
9 | // можно отключить всё
10 | // hardwareDisable(PWR_ALL);
11 |
12 | power.setSleepMode(STANDBY_SLEEP); // режим сна (по умолчанию POWERDOWN_SLEEP)
13 | //bodInSleep(false); // отключение BOD (по у молчанию и так выключен) - экономит энергию
14 | }
15 |
16 | void loop() {
17 | power.sleep(SLEEP_2048MS); // спим ~ 2 секунды (некалиброванный таймаут. Смотри пример с калибрвокой!)
18 | digitalWrite(13, !digitalRead(13)); // инвертируем состояние на пине
19 | }
20 |
--------------------------------------------------------------------------------
/examples/powersaveMillis/powersaveMillis.ino:
--------------------------------------------------------------------------------
1 | // спим в EXTSTANDBY_SLEEP, считаем время таймером 2
2 | // используется uptime2.h (лежит в папке с примером)
3 | // НЕ РЕКОМЕНДУЕТСЯ К ИСПОЛЬЗОВАНИЮ, смотрите пример sleepDelayMillis
4 |
5 | #include "uptime2.h"
6 | #include
7 |
8 | void setup() {
9 | Serial.begin(9600);
10 | uptime2Init(); // запуск миллиса на 2 таймере
11 | power.setSleepMode(EXTSTANDBY_SLEEP);
12 |
13 | // ВНИМАНИЕ!
14 | // миллис2 сделан на прерываниях таймера 2
15 | // прерывания настроены на частоту ~976.56 Гц
16 | // с этой частотой МК будет просыпаться вне зависимости от указанного периода сна!!
17 | // можно даже SLEEP_FOREVER поставить
18 | }
19 |
20 | void loop() {
21 | static uint32_t tmr;
22 | // наш таймер на миллис2
23 | if (millis2() - tmr >= 1000) {
24 | tmr += 1000;
25 | Serial.print("time: ");
26 | Serial.println(millis2());
27 | delay2(50);
28 | }
29 |
30 | // спим
31 | power.sleep(SLEEP_FOREVER);
32 | // тут проснулись в любом случае по прерыванию и код продолжает выполняться
33 | }
34 |
--------------------------------------------------------------------------------
/examples/powersaveMillis/uptime2.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #define MICROSECONDS_PER_TIMER2_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
3 | #define MILLIS2_INC (MICROSECONDS_PER_TIMER2_OVERFLOW / 1000)
4 | #define FRACT2_INC ((MICROSECONDS_PER_TIMER2_OVERFLOW % 1000) >> 3)
5 | #define FRACT2_MAX (1000 >> 3)
6 | #define MICROS2_MULT (64 / clockCyclesPerMicrosecond())
7 |
8 | void uptime2Init();
9 | unsigned long millis2();
10 | unsigned long micros2();
11 | void delay2(unsigned long ms);
12 | void delayMicroseconds2(unsigned int us);
13 |
14 | volatile unsigned long timer2_overflow_count = 0;
15 | volatile unsigned long timer2_millis = 0;
16 | static unsigned char timer2_fract = 0;
17 |
18 | void uptime2Init() {
19 | sei();
20 | TCCR2A = (1 << WGM20) | (1 << WGM21);
21 | TCCR2B = 1 << CS22;
22 | TIMSK2 = 1 << TOIE2;
23 | }
24 |
25 | ISR(TIMER2_OVF_vect) {
26 | timer2_millis += MILLIS2_INC;
27 | timer2_fract += FRACT2_INC;
28 | if (timer2_fract >= FRACT2_MAX) {
29 | timer2_fract -= FRACT2_MAX;
30 | timer2_millis++;
31 | }
32 | timer2_overflow_count++;
33 | }
34 |
35 | unsigned long millis2() {
36 | uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
37 | cli(); // выключаем прерывания
38 | unsigned long m = timer2_millis; // перехватить значение
39 | SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот
40 | return m; // вернуть миллисекунды
41 | }
42 |
43 | unsigned long micros2() {
44 | uint8_t oldSREG = SREG; // запомнинаем были ли включены прерывания
45 | cli(); // выключаем прерывания
46 | unsigned long m = timer2_overflow_count; // счет переполнений
47 | uint8_t t = TCNT2; // считать содержимое счетного регистра
48 | if ((TIFR2 & _BV(TOV2)) && (t < 255)) // инкремент по переполнению
49 | m++;
50 | SREG = oldSREG; // если прерывания не были включены - не включаем и наоборот
51 | return (long)(((m << 8) + t) * MICROS2_MULT); // вернуть микросекунды
52 | }
53 |
54 | void delay2(unsigned long ms) {
55 | uint32_t start = micros();
56 | while (ms > 0) { // ведем отсчет
57 | while ( ms > 0 && (micros() - start) >= 1000) {
58 | ms--;
59 | start += 1000;
60 | }
61 | }
62 | }
63 |
64 | void delayMicroseconds2(unsigned int us) {
65 | #if F_CPU >= 24000000L
66 | us *= 6; // x6 us, = 7 cycles
67 | us -= 5; //=2 cycles
68 |
69 | #elif F_CPU >= 20000000L
70 | __asm__ __volatile__ (
71 | "nop" "\n\t"
72 | "nop" "\n\t"
73 | "nop" "\n\t"
74 | "nop"); //just waiting 4 cycles
75 | if (us <= 1) return; // = 3 cycles, (4 when true)
76 | us = (us << 2) + us; // x5 us, = 7 cycles
77 | us -= 7; // 2 cycles
78 |
79 | #elif F_CPU >= 16000000L
80 | if (us <= 1) return; // = 3 cycles, (4 when true)
81 | us <<= 2; // x4 us, = 4 cycles
82 | us -= 5; // = 2 cycles,
83 |
84 | #elif F_CPU >= 12000000L
85 | if (us <= 1) return; // = 3 cycles, (4 when true)
86 | us = (us << 1) + us; // x3 us, = 5 cycles
87 | us -= 5; //2 cycles
88 |
89 | #elif F_CPU >= 8000000L
90 | if (us <= 2) return; // = 3 cycles, (4 when true)
91 | us <<= 1; //x2 us, = 2 cycles
92 | us -= 4; // = 2 cycles
93 |
94 | #else
95 | if (us <= 16) return; //= 3 cycles, (4 when true)
96 | if (us <= 25) return; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22)
97 | us -= 22; // = 2 cycles
98 | us >>= 2; // us div 4, = 4 cycles
99 |
100 | #endif
101 | __asm__ __volatile__ (
102 | "1: sbiw %0,1" "\n\t" // 2 cycles
103 | "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
104 | );
105 | }
106 |
--------------------------------------------------------------------------------
/examples/simpleWakePeriodic/simpleWakePeriodic.ino:
--------------------------------------------------------------------------------
1 | // самый простой пример, для слабонервных =)
2 | #include
3 |
4 | void setup() {
5 | //Serial.begin(9600);
6 | // сериал для демонстрации!
7 | // по умолчанию стоит самый экономный режим сна POWER DOWN
8 | }
9 |
10 | void loop() {
11 | // опрашиваем датчики, мигаем светодиодами, etc
12 | // ...
13 | // ...
14 |
15 | //Serial.println("go sleep");
16 | //delay(300);
17 |
18 | // спим 5 секунд (5000 мс)
19 | // в POWER DOWN вся периферия отключается, по умолчанию также отключается BOD и ADC
20 | power.sleepDelay(5000);
21 | // тут проснулись и код продолжает выполняться
22 |
23 | //Serial.println("wake up!");
24 | //delay(300);
25 | }
26 |
--------------------------------------------------------------------------------
/examples/sleepDelayMillis/sleepDelayMillis.ino:
--------------------------------------------------------------------------------
1 | // помогаем миллису сохранить свой счёт на время сна sleepDelay
2 | #include
3 |
4 | // На время сна в большинстве режимов millis() останавливается,
5 | // но сон при помощи функции sleepDelay автоматически корректирует millis()!
6 |
7 | void setup() {
8 | Serial.begin(9600);
9 | power.calibrate(); // автоматическая калибровка таймера сна
10 |
11 | // по умолчанию стоит самый экономный режим сна POWER DOWN
12 | // power.correctMillis(false); // можно отключить коррекцию миллис (по умолч. включена)
13 | }
14 |
15 | void loop() {
16 | // опрашиваем датчики, мигаем светодиодами, etc
17 | // таймер на миллис на 3 секунды для теста
18 | static uint32_t tmr;
19 | if (millis() - tmr >= 3000) {
20 | tmr += 3000;
21 | Serial.println("kek");
22 | delay(50);
23 | }
24 |
25 | // спим 1.5 секунды (1500 мс)
26 | power.sleepDelay(1500);
27 | // проснулись
28 | // миллис корректируется автоматически!
29 | }
30 |
--------------------------------------------------------------------------------
/examples/sleepDelayTest/sleepDelayTest.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void setup() {
4 | Serial.begin(115200);
5 | Serial.println("hello");
6 | delay(10);
7 |
8 | power.calibrate();
9 | }
10 |
11 | void loop() {
12 | power.sleepDelay(300000);
13 |
14 | delay(10);
15 | Serial.begin(115200);
16 | Serial.println("hello");
17 | delay(10);
18 | }
--------------------------------------------------------------------------------
/examples/sleepMillis/sleepMillis.ino:
--------------------------------------------------------------------------------
1 | // помогаем миллису сохранить свой счёт на время сна sleep
2 | #include
3 |
4 | // КОРРЕКЦИЯ МИЛЛИС РЕАЛИЗОВАНА В САМОЙ БИБЛИОТЕКЕ, ЭТО ПРОСТО ПРИМЕР ДЛЯ ДРУГИХ ПЛАТФОРМ
5 | // На время сна в большинстве режимов millis() останавливается, скорректировать можно вручную.
6 | // Функция sleep спит не ровно указанное время, так как WDT таймер имеет заводскую неточность.
7 | // Данный пример показан чисто для примера, не рекомендуется его использовать.
8 | // Для точных периодов сна используйте sleedDelay и калибровку WDT
9 | // см. пример sleepDelayMillis
10 |
11 | // "вытягиваем" переменную, отвечающую за счётчик миллис
12 | extern volatile unsigned long timer0_millis;
13 |
14 | void setup() {
15 | Serial.begin(9600);
16 | // по умолчанию стоит самый экономный режим сна POWER DOWN
17 | }
18 |
19 | void loop() {
20 | // опрашиваем датчики, мигаем светодиодами, etc
21 | // таймер на миллис на 3 секунды для теста
22 | static uint32_t tmr;
23 | if (millis() - tmr >= 3000) {
24 | tmr += 3000;
25 | Serial.println("kek");
26 | delay(50);
27 | }
28 |
29 | // спим ~512 мс
30 | power.sleep(SLEEP_512MS);
31 |
32 | // скорректировали миллис: прибавили время сна к счётчику миллис
33 | timer0_millis += 512;
34 | }
35 |
--------------------------------------------------------------------------------
/examples/sleeptime/sleeptime.ino:
--------------------------------------------------------------------------------
1 | // измеряем время, проведённое во сне
2 | // кнопка на D3 и GND
3 | #include
4 |
5 | // здесь просыпаемся
6 | void wake() {
7 | power.wakeUp();
8 | }
9 |
10 | void setup() {
11 | Serial.begin(9600);
12 | power.autoCalibrate(); // калибруем таймер сна
13 | // можно установить разрешение
14 | //power.setSleepResolution(SLEEP_1024MS);
15 |
16 | pinMode(3, INPUT_PULLUP);
17 | // будильник по кнопке
18 | attachInterrupt(1, wake, FALLING);
19 | }
20 |
21 | uint32_t tmr;
22 | void loop() {
23 | tmr = millis();
24 | power.sleepDelay(50000);
25 |
26 | // выводим время сна
27 | Serial.println(millis() - tmr);
28 | delay(300);
29 | }
30 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For GyverPower
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 | power KEYWORD1
9 | GyverPower KEYWORD1
10 |
11 | #######################################
12 | # Methods and Functions (KEYWORD2)
13 | #######################################
14 | hardwareEnable KEYWORD2
15 | hardwareDisable KEYWORD2
16 | setSystemPrescaler KEYWORD2
17 | adjustInternalClock KEYWORD2
18 |
19 | bodInSleep KEYWORD2
20 | setSleepMode KEYWORD2
21 | setSleepResolution KEYWORD2
22 | autoCalibrate KEYWORD2
23 | correctMillis KEYWORD2
24 |
25 | sleep KEYWORD2
26 | sleepDelay KEYWORD2
27 | wakeUp KEYWORD2
28 | inSleep KEYWORD2
29 |
30 | getMaxTimeout KEYWORD2
31 | calibrate KEYWORD2
32 |
33 | #######################################
34 | # Constants (LITERAL1)
35 | #######################################
36 | PRESCALER_1 LITERAL1
37 | PRESCALER_2 LITERAL1
38 | PRESCALER_4 LITERAL1
39 | PRESCALER_8 LITERAL1
40 | PRESCALER_16 LITERAL1
41 | PRESCALER_32 LITERAL1
42 | PRESCALER_64 LITERAL1
43 | PRESCALER_128 LITERAL1
44 | PRESCALER_256 LITERAL1
45 |
46 | PWR_ALL LITERAL1
47 | PWR_USB LITERAL1
48 | PWR_TIMER5 LITERAL1
49 | PWR_TIMER4 LITERAL1
50 | PWR_TIMER3 LITERAL1
51 | PWR_UART3 LITERAL1
52 | PWR_UART2 LITERAL1
53 | PWR_UART1 LITERAL1
54 | PWR_I2C LITERAL1
55 | PWR_TIMER2 LITERAL1
56 | PWR_TIMER0 LITERAL1
57 | PWR_TIMER1 LITERAL1
58 | PWR_SPI LITERAL1
59 | PWR_UART0 LITERAL1
60 | PWR_ADC LITERAL1
61 | PWR_USI LITERAL1
62 | PWR_LIN LITERAL1
63 |
64 | SLEEP_16MS LITERAL1
65 | SLEEP_32MS LITERAL1
66 | SLEEP_64MS LITERAL1
67 | SLEEP_128MS LITERAL1
68 | SLEEP_256MS LITERAL1
69 | SLEEP_512MS LITERAL1
70 | SLEEP_1024MS LITERAL1
71 | SLEEP_2048MS LITERAL1
72 | SLEEP_4096MS LITERAL1
73 | SLEEP_8192MS LITERAL1
74 | SLEEP_FOREVER LITERAL1
75 |
76 | IDLE_SLEEP LITERAL1
77 | ADC_SLEEP LITERAL1
78 | POWERDOWN_SLEEP LITERAL1
79 | POWERSAVE_SLEEP LITERAL1
80 | EXTSTANDBY_SLEEP LITERAL1
81 | STANDBY_SLEEP LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GyverPower
2 | version=2.2.1
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Library for power management of AVR
6 | paragraph=Library for power management of AVR
7 | category=Other
8 | url=https://github.com/GyverLibs/GyverPower
9 | architectures=avr
--------------------------------------------------------------------------------
/src/GyverPower.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #ifdef MILLIS_CORRECT_IS_SUPPURT
4 | extern volatile unsigned long timer0_millis;
5 | #endif
6 | static volatile bool _wdtFlag = false;
7 |
8 | // ===================== ЖЕЛЕЗО =====================
9 | void GyverPower::hardwareEnable(uint16_t data) {
10 | #if defined(PRR1)
11 | PRR1 &= ~highByte(data); // загрузили данные в регистр
12 | PRR0 &= ~lowByte(data);
13 | #else
14 | PRR &= ~lowByte(data);
15 | #endif
16 | if (data & PWR_ADC) { // если что то сказали про ацп
17 | ADCSRA |= (1 << ADEN); // вкл ацп
18 | ACSR &= ~(1 << ACD); // вкл компаратор
19 | }
20 | }
21 |
22 | void GyverPower::hardwareDisable(uint16_t data) {
23 | if (data & PWR_ADC) { // если что то сказали про ацп
24 | ADCSRA &= ~(1 << ADEN); // выкл ацп
25 | ACSR |= (1 << ACD); // выкл компаратор
26 | }
27 | #if defined(PRR1)
28 | PRR1 |= highByte(data); // загрузили данные в регистр
29 | PRR0 |= lowByte(data);
30 | #else
31 | PRR |= lowByte(data);
32 | #endif
33 | }
34 |
35 | // ===================== КЛОК =====================
36 | void GyverPower::setSystemPrescaler(prescalers_t prescaler) {
37 | CLKPR = (1 << CLKPCE); // разрешили менять делитель
38 | CLKPR = prescaler; // загрузили новый
39 | }
40 |
41 | void GyverPower::adjustInternalClock(int8_t adj) {
42 | static uint8_t currentCal;
43 | static bool startup = false;
44 | if (!startup) {
45 | startup = true;
46 | currentCal = OSCCAL;
47 | }
48 | uint8_t oldSreg = SREG;
49 | currentCal = constrain(currentCal + adj, 0, 255);
50 | cli();
51 | OSCCAL = currentCal;
52 | SREG = oldSreg;
53 | }
54 |
55 | // ===================== НАСТРОЙКИ СНА =====================
56 | void GyverPower::bodInSleep(bool state) {
57 | _bodEnable = state;
58 | }
59 |
60 | void GyverPower::setSleepMode(sleepmodes_t mode) {
61 | _sleepMode = mode;
62 | }
63 |
64 | void GyverPower::correctMillis(bool state) {
65 | _correctF = state;
66 | }
67 |
68 | // ===================== КАЛИБРОВКА =====================
69 | void GyverPower::calibrate() {
70 | _wdtFlag = false;
71 | uint32_t us = micros();
72 | _wdt_start(SLEEP_16MS);
73 | while (!_wdtFlag);
74 | wdt_disable();
75 | _us16 = micros() - us;
76 | setSleepResolution(_delayPrd);
77 | }
78 |
79 | // ===================== СОН =====================
80 | void GyverPower::sleep(sleepprds_t prd) {
81 | _prepare();
82 | _sleep(prd);
83 | _finish();
84 | }
85 |
86 | void GyverPower::setSleepResolution(sleepprds_t prd) {
87 | uint32_t stepUs = (uint32_t)_us16 * (1 << prd);
88 | _step = stepUs / 1000ul;
89 | _fstep = (stepUs % 1000ul) >> 3;
90 | _delayPrd = prd;
91 | }
92 |
93 | uint16_t GyverPower::sleepDelay(uint32_t ms, uint32_t sec, uint16_t min, uint16_t hour, uint16_t day) {
94 | if (sec) ms += sec * 1000ul;
95 | if (min) ms += min * 60 * 1000ul;
96 | if (hour) ms += hour * 60 * 60 * 1000ul;
97 | if (day) ms += day * 24 * 60 * 60 * 1000ul;
98 | return sleepDelay(ms);
99 | }
100 |
101 | uint16_t GyverPower::sleepDelay(uint32_t ms) {
102 | #ifdef MILLIS_CORRECT_IS_SUPPURT
103 | uint32_t saveMs = ms;
104 | #endif
105 | uint8_t fcount = 0;
106 | _wakeF = false;
107 | _prepare();
108 | while (ms > _step) {
109 | _sleep(_delayPrd);
110 | ms -= _step;
111 | fcount += _fstep;
112 | if (fcount >= (1000 >> 3)) {
113 | --ms;
114 | fcount -= (1000 >> 3);
115 | }
116 | if (_wakeF) {
117 | #ifdef MILLIS_CORRECT_IS_SUPPURT
118 | if (_correctF) {
119 | uint8_t oldSREG = SREG;
120 | cli();
121 | timer0_millis += saveMs - ms;
122 | SREG = oldSREG;
123 | }
124 | #endif
125 | _finish();
126 | return ms;
127 | }
128 | }
129 | #ifdef MILLIS_CORRECT_IS_SUPPURT
130 | if (_correctF) {
131 | uint8_t oldSREG = SREG;
132 | cli();
133 | timer0_millis += saveMs - ms;
134 | SREG = oldSREG;
135 | }
136 | #endif
137 | _finish();
138 | return ms; // вернуть остаток времени
139 | }
140 |
141 | void GyverPower::wakeUp() {
142 | _wakeF = true;
143 | }
144 |
145 | bool GyverPower::inSleep() {
146 | return _sleepF;
147 | }
148 |
149 | // ===================== PRIVATE =====================
150 | void GyverPower::_prepare() {
151 | _sleepF = 1;
152 | // принудительно выкл АЦП и компаратор
153 | switch (_sleepMode) {
154 | case IDLE_SLEEP:
155 | case ADC_SLEEP:
156 | break;
157 | default:
158 | ADCSRA &= ~(1 << ADEN); // Выкл ацп
159 | ACSR |= (1 << ACD); // Выкл аналог компаратор
160 | }
161 |
162 | #if defined(__AVR_ATtiny85__)
163 | // Принудительное отключение PLL
164 | _pllCopy = PLLCSR; // Запомнили настройки
165 | PLLCSR &= ~(1 << PLLE); // Выключили
166 | #endif
167 | }
168 |
169 | void GyverPower::_sleep(sleepprds_t period) {
170 | if (period != SLEEP_FOREVER) _wdt_start(period);
171 | set_sleep_mode(_sleepMode); // Настраиваем нужный режим сна
172 | sleep_enable(); // Разрешаем сон
173 | if (_bodEnable) interrupts(); // для БОД, если он включен
174 | #if defined(sleep_bod_disable)
175 | else {
176 | noInterrupts(); // Запрет прерываний
177 | sleep_bod_disable(); // Выключаем BOD
178 | interrupts(); // Разрешаем прерывания
179 | }
180 | #endif
181 | sleep_cpu(); // <<< точка ухода в сон
182 | wdt_disable(); // выкл пса
183 | wdt_reset(); // сброс пса
184 | sleep_disable(); // Запрещаем сон
185 | }
186 |
187 | void GyverPower::_finish() {
188 | // Восстановление настроек АЦП
189 | #if defined(PRR0)
190 | if (!(PRR0 & (1 << PRADC))) { // если ацп не выключен принудительно
191 | ADCSRA |= (1 << ADEN); // вкл после сна
192 | ACSR &= ~(1 << ACD);
193 | }
194 | #else
195 | if (!(PRR & (1 << PRADC))) { // если ацп не выключен принудительно
196 | ADCSRA |= (1 << ADEN); // вкл после сна
197 | ACSR &= ~(1 << ACD);
198 | }
199 | #endif
200 |
201 | // Восстановление настроек PLL (для тини85)
202 | #if defined(__AVR_ATtiny85__)
203 | PLLCSR = _pllCopy;
204 | #endif
205 | _sleepF = 0;
206 | }
207 |
208 | void GyverPower::_wdt_start(uint8_t timeout) {
209 | wdt_enable(timeout);
210 | WDTCSR |= 1 << WDIE; // Режим ISR+RST
211 | wdt_reset(); // Сброс WDT
212 | }
213 |
214 | ISR(WDT_vect) { // просыпаемся тут
215 | _wdtFlag = true; // для калибровки
216 | }
217 |
218 | GyverPower power = GyverPower();
219 |
220 | //////////////////////
221 | uint16_t GyverPower::getMaxTimeout() { return 8000; }
222 | void GyverPower::calibrate(uint16_t ms) { calibrate(); }
223 | void GyverPower::autoCalibrate() { calibrate(); }
--------------------------------------------------------------------------------
/src/GyverPower.h:
--------------------------------------------------------------------------------
1 | #ifndef _GyverPower_h
2 | #define _GyverPower_h
3 | #include
4 | #include
5 | #include
6 |
7 | #include "powerConstants.h"
8 |
9 | // =============== ФУНКЦИИ ===============
10 | class GyverPower {
11 | public:
12 | void hardwareEnable(uint16_t data); // включение указанной периферии (см. ниже "Константы периферии")
13 | void hardwareDisable(uint16_t data); // выключение указанной периферии (см. ниже "Константы периферии")
14 | void setSystemPrescaler(prescalers_t prescaler); // установка делителя системной частоты
15 | void adjustInternalClock(int8_t adj); // подстройка частоты внутреннего генератора (число -120...+120)
16 | void bodInSleep(bool en); // Brown-out detector в режиме сна (true вкл - false выкл) [умолч. false]
17 | void setSleepMode(sleepmodes_t mode); // установка текущего режима сна [умолч. POWERDOWN_SLEEP]
18 | void sleep(sleepprds_t period); // сон на стандартный период
19 | bool inSleep(); // вернёт true, если МК спит для проверки в прерывании
20 |
21 | uint16_t sleepDelay(uint32_t ms); // сон на произвольный период в миллисекундах, возвращает остаток времени для коррекции таймеров
22 | uint16_t sleepDelay(uint32_t ms, uint32_t sec, uint16_t min = 0, uint16_t hour = 0, uint16_t day = 0);
23 | void setSleepResolution(sleepprds_t period); // установить разрешение сна sleepDelay() [умолч. SLEEP_128MS]
24 | void correctMillis(bool state); // корректировать миллис на время сна sleepDelay() [умолч. true]
25 | void calibrate(); // автоматическая калибровка таймера сна sleepDelay(), выполняется 16 мс
26 | void wakeUp(); // помогает выйти из sleepDelay() прерыванием (вызывать в будящем прерывании)
27 |
28 | // устарело
29 | void autoCalibrate(); // автоматическая калибровка таймера сна, выполняется 16 мс
30 | void calibrate(uint16_t ms); // ручная калибровка тайм-аутов watchdog для sleepDelay (ввести макс период из getMaxTimeout)
31 | uint16_t getMaxTimeout(); // возвращает реальный период "8 секунд", выполняется ~8 секунд
32 |
33 | private:
34 | void _prepare();
35 | void _sleep(sleepprds_t period);
36 | void _finish();
37 | void _wdt_start(uint8_t timeout);
38 |
39 | uint16_t _step = 1 << (SLEEP_128MS + 4);
40 | uint16_t _us16 = 16000;
41 | uint8_t _fstep = 0;
42 | sleepprds_t _delayPrd = SLEEP_128MS;
43 | sleepmodes_t _sleepMode = POWERDOWN_SLEEP;
44 |
45 | volatile bool _wakeF = false;
46 | volatile bool _sleepF = 0;
47 | bool _correctF = true;
48 | bool _bodEnable = false;
49 |
50 | #if defined(__AVR_ATtiny85__)
51 | uint8_t _pllCopy = 0;
52 | #endif
53 | };
54 |
55 | extern GyverPower power;
56 |
57 | // =============== КОНСТАНТЫ ===============
58 | /*
59 | ===== РЕЖИМЫ СНА для setSleepMode() =====
60 | IDLE_SLEEP - Легкий сон, отключается только клок CPU и Flash, просыпается мгновенно от любых прерываний
61 | ADC_SLEEP - Легкий сон, отключается CPU и system clock, АЦП начинает преобразование при уходе в сон (см. пример ADCinSleep)
62 | EXTSTANDBY_SLEEP - Глубокий сон, идентичен POWERSAVE_SLEEP + system clock активен
63 | STANDBY_SLEEP - Глубокий сон, идентичен POWERDOWN_SLEEP + system clock активен
64 | POWERSAVE_SLEEP - Глубокий сон, идентичен POWERDOWN_SLEEP + timer 2 активен (+ можно проснуться от его прерываний), можно использовать для счета времени (см. пример powersaveMillis)
65 | POWERDOWN_SLEEP - Наиболее глубокий сон, отключается всё кроме WDT и внешних прерываний, просыпается от аппаратных (обычных + PCINT) или WDT
66 |
67 | ===== ПЕРИОДЫ СНА для sleep() и setSleepResolution() =====
68 | SLEEP_16MS
69 | SLEEP_32MS
70 | SLEEP_64MS
71 | SLEEP_128MS
72 | SLEEP_256MS
73 | SLEEP_512MS
74 | SLEEP_1024MS
75 | SLEEP_2048MS
76 | SLEEP_4096MS
77 | SLEEP_8192MS
78 | SLEEP_FOREVER - вечный сон
79 |
80 | ===== КОНСТАНТЫ ДЕЛИТЕЛЯ для setSystemPrescaler() =====
81 | PRESCALER_1
82 | PRESCALER_2
83 | PRESCALER_4
84 | PRESCALER_8
85 | PRESCALER_16
86 | PRESCALER_32
87 | PRESCALER_64
88 | PRESCALER_128
89 | PRESCALER_256
90 |
91 | ===== КОНСТАНТЫ ПЕРИФЕРИИ для hardwareDisable() и hardwareEnable() =====
92 | PWR_ALL - всё железо
93 | PWR_ADC - АЦП и компаратор
94 | PWR_TIMER1 - Таймер 0
95 | PWR_TIMER0 - Таймер 1
96 | PWR_TIMER2 - Таймер 2
97 | PWR_TIMER3 - Таймер 3
98 | PWR_TIMER4 - Таймер 4
99 | PWR_TIMER5 - Таймер 5
100 | PWR_UART0 - Serial 0
101 | PWR_UART1 - Serial 1
102 | PWR_UART2 - Serial 2
103 | PWR_UART3 - Serial 3
104 | PWR_I2C - Wire
105 | PWR_SPI - SPI
106 | PWR_USB - USB
107 | PWR_USI - Wire + Spi (ATtinyXX)
108 | PWR_LIN - USART LIN (ATtinyXX)
109 | */
110 | #endif
--------------------------------------------------------------------------------
/src/powerConstants.h:
--------------------------------------------------------------------------------
1 | #ifndef powerConstants_h
2 | #define powerConstants_h
3 |
4 | /* --- system prescaler --- */
5 | enum prescalers_t : uint8_t {
6 | PRESCALER_1,
7 | PRESCALER_2,
8 | PRESCALER_4,
9 | PRESCALER_8,
10 | PRESCALER_16,
11 | PRESCALER_32,
12 | PRESCALER_64,
13 | PRESCALER_128,
14 | PRESCALER_256,
15 | };
16 |
17 | /* --- sleep periods --- */
18 | enum sleepprds_t : uint8_t {
19 | SLEEP_16MS,
20 | SLEEP_32MS,
21 | SLEEP_64MS,
22 | SLEEP_128MS,
23 | SLEEP_256MS,
24 | SLEEP_512MS,
25 | SLEEP_1024MS,
26 | SLEEP_2048MS,
27 | SLEEP_4096MS,
28 | SLEEP_8192MS,
29 | SLEEP_FOREVER,
30 | };
31 |
32 | /* --- sleep modes --- */
33 | enum sleepmodes_t : uint8_t {
34 | IDLE_SLEEP = SLEEP_MODE_IDLE,
35 | ADC_SLEEP = SLEEP_MODE_ADC,
36 | POWERDOWN_SLEEP = SLEEP_MODE_PWR_DOWN,
37 | #if defined(SLEEP_MODE_EXT_STANDBY)
38 | EXTSTANDBY_SLEEP = SLEEP_MODE_EXT_STANDBY,
39 | #endif
40 | #if defined(SLEEP_MODE_PWR_SAVE)
41 | POWERSAVE_SLEEP = SLEEP_MODE_PWR_SAVE,
42 | #endif
43 | #if defined(SLEEP_MODE_STANDBY)
44 | STANDBY_SLEEP = SLEEP_MODE_STANDBY
45 | #endif
46 | };
47 |
48 | /* --- periphery disable / enable --- */
49 | #if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny84__)
50 | #define PWR_ALL 0xFFFF
51 | #define PWR_LIN _BV(5)
52 | #define PWR_SPI _BV(4)
53 | #define PWR_TIMER1 _BV(3)
54 | #define PWR_TIMER0 _BV(2)
55 | #define PWR_USI _BV(1)
56 | #define PWR_ADC _BV(0)
57 | #else
58 | #define PWR_ALL 0xFFFF
59 | #define PWR_USB _BV(15)
60 | #define PWR_TIMER5 _BV(13)
61 | #define PWR_TIMER4 _BV(12)
62 | #define PWR_TIMER3 _BV(11)
63 | #define PWR_UART3 _BV(10)
64 | #define PWR_UART2 _BV(9)
65 | #define PWR_UART1 _BV(8)
66 | #define PWR_I2C _BV(7)
67 | #define PWR_TIMER2 _BV(6)
68 | #define PWR_TIMER0 _BV(5)
69 | #define PWR_TIMER1 _BV(3)
70 | #define PWR_SPI _BV(2)
71 | #define PWR_UART0 _BV(1)
72 | #define PWR_ADC _BV(0)
73 | #endif
74 |
75 | /* Спец. переопределения */
76 | #if defined(WDTIE)
77 | #define WDIE WDTIE
78 | #endif
79 |
80 | #if defined(WDTCR)
81 | #define WDTCSR WDTCR
82 | #endif
83 |
84 | /* Поддержка millis-correct */
85 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
86 | #define MILLIS_CORRECT_IS_SUPPURT
87 | #endif
88 |
89 | #endif
--------------------------------------------------------------------------------