БИБЛИОТЕКА GYVERHACKS
GyverHacks v2.10

Библиотека с некоторыми удобными хаками для 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() { }
ОСТАЛЬНЫЕ БИБЛИОТЕКИ

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