БИБЛИОТЕКА GYVERHACKS

Библиотека с некоторыми удобными хаками для Arduino UNO/NANO/MINI (atmega328):

  • Быстрые аналоги стандартных функций чтения/записи
    • digitalRead
    • digitalWrite
    • analogRead
    • analogWrite
  • Изменение частоты ШИМ пинов (3, 5, 6, 9, 10, 11)
  • Установка ШИМ на пинах 9 и 10 в режим 10 бит (analogWrite 0-1023)
  • Генерация ШИМ на ЛЮБОМ пине (частота ~150 Гц)
  • Измерение напряжения питания + калибровка константы
  • Перевод напряжения питания в проценты по графику разряда для разных типов АКБ
  • Измерение температуры ядра

Поддерживаемые платформы: только платы на ATmega328/168

ДОКУМЕНТАЦИЯ


// ********************************************* Хаки с ШИМ *********************************************
void setPWMmode(byte pin, byte mode);   // установка режима ШИМ на пине 
// пины 3, 5, 6, 9, 10, 11
// режимы: 0 - FastPWM, 1 - Phase-correct PWM
void setPWMprescaler(uint8_t pin, uint16_t mode);
// установка частоты ШИМ на пине. Смотри таблицу частот в GyverHacks.h или примере PWMfreq!
void set8bitPWM();                 // установка ШИМ на пинах 9 и 10 в режим 8 бит (analogWrite 0-255) (по умолчанию)
void set10bitPWM();                // установка ШИМ на пинах 9 и 10 в режим 10 бит (analogWrite 0-1023)
void delayFix(uint32_t delayTime);                  // аналог delay для корректной работы с изменённой частотой ШИМ пинов 5 и 6
void delayMicrosecondsFix(uint32_t delayTime);      // аналог delayMicroseconds для корректной работы с изменённой частотой ШИМ пинов 5 и 6
uint32_t millisFix();                               // аналог millis для корректной работы с изменённой частотой ШИМ пинов 5 и 6
uint32_t microsFix();                               // аналог micros для корректной работы с изменённой частотой ШИМ пинов 5 и 6
void anyPWMinit(byte prescaler);
// инициализация ШИМ на любом пине
// prescaler: 4 - 311 Гц, 5 - 244 Гц, 6 - 122 Гц, 7 - 30 Гц
// если пинов много - понижайте частоту (20 пинов работают отлично на 6 режиме)													
void anyPWMpin(uint8_t pin);       // настроить ЛЮБОЙ пин для генерации ШИМ
void anyPWM(byte pin, byte duty);  // включить ШИМ на ЛЮБОМ пине (настроенном выше)
// ********************************************* Ускоряем функции *********************************************
void setPWM(uint8_t pin, uint8_t duty);      // быстрый аналог analogWrite (в 7 раз быстрее)
void setPin(uint8_t pin, uint8_t x);         // быстрый аналог digitalWrite (в 10 раз быстрее)
boolean readPin(uint8_t pin);                // быстрый аналог digitalRead (в 11 раз быстрее)
void setADCrate(byte mode);
// установка скорости работы АЦП (analogRead)
// mode 1: 3.04 мкс (частота оцифровки 329 000 кГц)
// mode 2: 4.72 мкс (частота оцифровки 210 000 кГц)
// mode 3: 8.04 мкс (частота оцифровки 125 000 кГц)
// mode 4: 15.12 мкс (частота оцифровки 66 100 кГц)
// mode 5: 28.04 мкс (частота оцифровки 35 600 кГц)
// mode 6: 56.04 мкс (частота оцифровки 17 800 кГц)													
// mode 7: 112 мкс (частота оцифровки 8 900 Гц)
// ********************************************* Точный вольтметр *********************************************
int getVCC();                      // возвращает опорное напряжение (напряжение питания)
// константа по умолчанию равна 1100, нужно калибровать!
void constantWizard();             // помошник калибровки константы (смотри пример)
void restoreConstant(int adr);     // восстановить константу из памяти
void setConst(int new_const);      // установить константу вручную (по умолч. 1100)
int getConst();                    // вывести текущую константу
int getVoltage(uint8_t pin);       // измерить напряжение на пине с учётом опорного
// функции получения процента заряда из напряжения, линеаризованы вручную по графикам разряда АКБ
// использовать вот так: lithiumPercent(getVCC()); - ардуина питается от лития
byte lithiumPercent(int volts);    // возвращает процент заряда Li-ion аккумулятора (4,2-2,8 В)
byte alkaline3Percent(int volts);  // возвращает процент заряда 3х алкалиновых батареек (4,6-3,3 В)
byte nickel3Percent(int volts);    // возвращает процент заряда 3х Ni-Cd аккумуляторов (4.2-3.0 В)
byte nickel4Percent(int volts);    // возвращает процент заряда 4х Ni-Cd аккумуляторов (5.6-4.0В)
// функция для расчёта заряда батареи в процентах
// принимает напряжение в милливолльтах (volts), а также напряжения, при которых заряд равен 100, 80... 0%
byte mVtoPercent(int volts, int volt100, int volt80, int volt60, int volt40, int volt20, int volt0);
// ********************************************* Прочее *********************************************
float getTemp();		// получить примерную температуру ядра процессора (температура окружающей среды или температура внутри корпуса)

ПРИМЕРЫ


// пример работы с генерацией ШИМ для ЛЮБОГО пина. Хоть все 20 (atmega328)
// не забудьте включить параметр в GyverHacks.h (почти в самом начале)
#include "GyverHacks.h"
void setup() {
anyPWMinit(6);	// инициализация системы, в скобках режим (частота)
// 4 - 311 Гц, 5 - 244 Гц, 6 - 122 Гц, 7 - 30 Гц
// если пинов много - понижайте частоту (20 пинов работают отлично на 6 режиме, 10 на 5ом режиме)
// делаем все пины как anyPWM
for (byte i = 0; i < 20; i++) {
anyPWMpin(i);	// настройка пина
}
}
void loop() {
// и поочереди плавно включаем и выключаем все пины
// сама функция - anyPWM(pin, duty) - пин и величина 0-255
for (byte i = 0; i < 20; i++) {
for (byte j = 0; j < 255; j++) { anyPWM(i, j); delay(2); } for (int j = 255; j > 0; j--) {
anyPWM(i, j);
delay(2);
}
}
}
/*
digitalWrite() - 3.2 мкс
setPin() - 0.32 мкс (в 10 раз быстрее)
digitalRead() - 3.08 мкс
readPin() - 0.28 мкс (в 11 раз быстрее)
analogWrite() - 3.87 мкс
setPWM() - 0.53 мкс (в 7 раз быстрее)
analogRead() стандартный - 113 мкс
setADCrate(1) - установка максимальной скорости АЦП (по умолч. 7 - минимум)
analogRead() на макс. скорости - 3.04 мкс (в 38 раз быстрее)
*/
#include "GyverHacks.h"
void setup() {
Serial.begin(9600);
setADCrate(1);
/*
// мигаем всеми пинами
for (byte i = 0; i < 20; i++) {
pinMode(i, OUTPUT);
}
for (byte i = 0; i < 20; i++) {
setPin(i, 1);
delay(400);
setPin(i, 0);
delay(200);
}
*/
}
void loop() {
}
// при изменении ШИМ у таймера 0 функции времени начинают работать 
// некорректно: быстрее или медленнее
// проблему решаем при помощи fixed функций, где учтён предделитель таймера
// delayFix()
// delayMicrosecondsFix()
// millisFix()
// microsFix()
#include "GyverHacks.h"
void setup() {
Serial.begin(9600);
setPWMprescaler(5, 2);  // пин 5 частота 7,8 кГц
}
void loop() {
Serial.println("millis: " + String(millis()) + ", millisFix: " + String(millisFix()));
delayFix(1000);
}
// пример 10 битного шима на 9 и 10 пинах
#include "GyverHacks.h"
void setup() {
set10bitPWM();			// установить ШИМ на 9 и 10 пине в режим 10 бит
//set8bitPWM();			// по умолчанию 8 бит, можно вернуть
analogWrite(9, 666);		// запустить ШИМ на 9 пине, диапазон 0-1023
// также можно изменить частоту ШИМ
setPWMprescaler(9, 1);	// установить режим (ШИМ пин, режим). Сейчас поставили 9 и 10 пин на 15.6 кГц. Круто!
}
void loop() {
}
// пример изменения частоты ШИМ на ШИМ пинах atmega328
// при изменении ШИМ у таймера 0 функции времени начинают работать некорректно
// в библиотеке есть fixed функции, смотри пример fixedTime
/*
Timer 0 (пины 5 и 6) (ВЛИЯЕТ НА РАБОТУ millis() и delay())
Timer 1 (пины 9 и 10) (ВЛИЯЕТ НА РАБОТУ servo)
Timer 2 (пины 3 и 11) (ВЛИЯЕТ НА РАБОТУ tone())
*/
/*
____________________________________________________________________________________________
| Timer 0 (пины 5 и 6)		| Timer 1 (пины 9 и 10) 		| Timer 2 (пины 3 и 11)		| 
| Timer 1 (пины 9 и 10)		| в режиме 10 bit				|							| 
____|___________________________|_______________________________|___________________________|
mode| Phase-correct	| Fast PWM	| Phase-correct		| Fast PWM	| Phase-correct	| Fast PWM	|
____|_______________|___________|___________________|___________|_______________|___________|
1	| 31.4 kHz		| 62.5 kHz	| 7.8 kHz			| 15.6 kHz	| 31.4 kHz		| 62.5 kHz	| 
2	| 4 kHz			| 7.8 kHz	| 977 Hz			| 2 kHz		| 4 kHz			| 8 kHz		| 
3	| 490 Hz		| 976 Hz	| 122 Hz			| 244 Hz	| 980 Hz		| 2 kHz		| 
4	| 122 Hz		| 244 Hz	| 30 Hz				| 61 Hz		| 490 Hz		| 980 Hz	| 
5	| 30 Hz			| 61 Hz		| 7.6 Hz			| 15 Hz		| 245 Hz		| 490 Hz	| 
6	| -				| -			| -					| -			| 122 Hz		| 244 Hz	| 
7	| -				| -			| -					| -			| 30 Hz			| 60 Hz		| 
____|_______________|___________|___________________|___________|_______________|___________|
*/
#include "GyverHacks.h"
void setup() {  
setPWMprescaler(5, 2);	// установить режим (ШИМ пин, режим) в этом случае на пин 5 частота 7,8 кГц 
pinMode(5, OUTPUT);
setPWM(5, 125);			    // запустить ШИМ
}
void loop() {
}
/*
Пример настройки точного вольтметра на внутреннем опорном напряжении.
Константа вольтметра (по умолчанию 1100) зависит от температуры и отличается в МК из разных партий.
Удобно настроить константу можно через constantWizard:
- Вызываем функцию constantWizard()
- Отправляем ей реальное напряжение питания в милливольтах (измерить между GND и 5V)
- Будет посчитана константа и предложено записать её в EEPROM (Y - согласиться, N - отказаться)
- При согласии будет предложено выбрать адрес ячейки, отправляем (0 - 1022) константа займёт 2 ячейки!
- Удаляем или комментируем функцию constantWizard(), она больше не нужна
- Для автоматического восстановления константы вызываем restoreConstant(address) при запуске скетча
- address должен быть таким же, какой вы выбрали в constantWizard =)
- Всё, теперь функция getVCC() возвращает точное опорное напряжение!
Для большей точности можно делать среднее по 50 измерениям или фильтровать
- Константу можно менять вручную, это переменная vcc_const. Например пишем в сетапе vcc_const = 1080
*/
#include "GyverHacks.h"
void setup() {
Serial.begin(9600);
constantWizard();           // помошник по калибровке константы
//restoreConstant(1000);    // восстановить из памяти
Serial.println(getVCC());
}
void loop() {
}

ОСТАЛЬНЫЕ БИБЛИОТЕКИ

У меня есть ещё очень много всего интересного! Смотрите полный список библиотек вот здесь.