Несколько интересных и полезных библиотек
- Войдите на сайт для отправки комментариев
Всем привет, решил поделиться своими библиотеками, написанными для разных проектов. Библиотеки в целом заменяют часто используемые стандартные конструкции, упрощая и ускоряя написание кода. Сразу хочу предупредить, что написаны они человеком-ардуинщиком-самоучкой, т.е. никаких ассемблеров, сплошь стандартные костыли и функции. Но всё работает, и работает отлично для моих целей и целей типичного "новичка". Актуальные версии и краткое описание методов всегда находится здесь https://github.com/AlexGyver/GyverLibs . Описание продублировано из файла .h, к каждой библиотеке идёт пачка примеров. Никаких релизов не делал, качайте всей папкой...
Что внутри:
GyverButton v2.6
Библиотека для многофункциональной отработки нажатия кнопок с Arduino. Возможности:
- Работа с нормально замкнутыми и нормально разомкнутыми кнопками
- Работа с подключением PULL_UP и PULL_DOWN
- Опрос кнопки с программным антидребезгом контактов
- Настраиваемое время антидребезга
- Отработка нажатия, удерживания, отпускания, клика по кнопке
- Настраиваемый таймаут удержания
- Отработка одиночного, двойного и тройного нажатия (вынесено отдельно)
- Отработка любого количества нажатий кнопки (функция возвращает количество нажатий)
- Настраиваемый таймаут повторного нажатия/удержания
- Функция изменения значения переменной с заданным шагом и заданным интервалом по времени
- Возможность опрашивать не кнопку, а напрямую давать величину (все возможности библиотеки для матричных и резистивных клавиатур)
GyverEncoder v2.5
Библиотека для отработки энкодера с Arduino. Возможности:
- Отработка поворота с антидребезгом
- Отработка нажатия кнопки с антидребезгом
- Отработка нажатия и удержания кнопки
- Отработка "нажатого поворота"
- Работа с двумя типами экнодеров
GyverFilters v1.3
Библиотека с некоторыми удобными фильтрами для Arduino:
- GFilterRA - компактная альтернатива фильтра экспоненциальное бегущее среднее (Running Average)
- GMedian3 - быстрый медианный фильтр 3-го порядка (отсекает выбросы)
- GMedian - медианный фильтр N-го порядка. Порядок настраивается в GyverFilters.h - MEDIAN_FILTER_SIZE
- GABfilter - альфа-бета фильтр (разновидность Калмана для одномерного случая)
- GKalman - упрощённый Калман для одномерного случая (на мой взгляд лучший из фильтров)
GyverTimer v1.2
Компактная альтернатива конструкции таймера с millis() / micros(), обеспечивающая удобную мультизадачность на Arduino
- Вся работа с таймером заменяется одной функцией
- Миллисекундный и микросекундный таймер
- Автоматический и ручной режим работы
GyverHacks v2.0
Библиотека с некоторыми удобными хаками для Arduino UNO/NANO/MINI (atmega328):
- Быстрые аналоги стандартных функций чтения/записи
- Изменение частоты ШИМ пинов (3, 5, 6, 9, 10, 11)
- Установка ШИМ на пинах 9 и 10 в режим 10 бит (abalogWrite 0-1023)
- Генерация ШИМ на ЛЮБОМ пине (частота ~150 Гц)
- Измерение напряжения питания + калибровка константы
- Перевод напряжения питания в проценты по графику разряда для разных типов АКБ
- Измерение температуры ядра
GyverMotor v1.0
Библиотека для удобного управления моторчиками через драйвер полного моста для Arduino
- Контроль скорости и направления вращения
- Встроенный инструмент для настройки частоты ШИМ
- Работа с 10 битным ШИМом
GyverRGB v1.6
Библиотека для удобного управления RGB светодиодами и лентами для Arduino
- Работа в пространстве RGB
- Работа в пространстве HSV
- Установка цвета в формате HEX
-
16 предустановленных цветов Доступные цвета для setHEX
- WHITE - белый
- SILVER - серебро
- GRAY - серый
- BLACK - чёрный
- RED - красный
- MAROON - бордовый
- YELLOW - жёлтый
- OLIVE - олива
- LIME - лайм
- GREEN - зелёный
- AQUA - аква
- TEAL - цвет головы утки чирка https://odesign.ru/teal-color/
- BLUE - голубой
- NAVY - тёмно-синий
- PINK - розовый
- PURPLE - пурпурный
- Настройка полярности ШИМ
- Функция плавной смены цвета
- Возможность управления 6-ю RGB диодами/лентами с одной Arduino (встроенный генератор ШИМ на ВСЕХ 20 пинах atmega328)
GyverTM1637 v1.1
Бибилотека для 7 сегментного дисплея на чипе TM1637 с кучей приколюх
- Вывод цифр массивом или прицельно
- Вывод букв из списка доступных (листай ниже) массивом или прицельно
- Отдельная функция вывода часов и минут (часы без нуля слева, минуты с нулём) 3 разных эффекта
- Вывод числа от -999 до 9999 с учётом знака
- Готовая функция бегущей строки
- Функции смены яркости и состояния двоеточия автоматически обновляют дисплей
- Функция обновления значения с эффектом вертикальной прокрутки
- Функция обновления значения с эффектом скручивания (лучше один раз увидеть)
GyverPID v1.0
Библиотека классического PID регулятора для Arduino
- Время одного расчёта около 90 мкс
- Режим работы по величине или по её изменению (для интегрирующих процессов)
- Возвращает результат по встроенному таймеру или в ручном режиме
GyverRelay v1.0
Библиотека классического релейного регулятора для Arduino
- Обратная связь по скорости изменения величины
- Настройка гистерезиса, коэффициента усиления ОС, направления регулирования
- Возвращает результат по встроенному таймеру или в ручном режиме
GyverRTOS v1.0
Система реального времени для Arduino: максимальное энергосбережение и мультизадачность
- Во время сна функция millis() не работает, вместо неё используется переменная mainTimer, которая автоматически увеличивается при каждом пробуждении на время сна (SLEEP_PERIOD) В ХОЛОСТОМ РЕЖИМЕ
- Выполнение функций занимает время, поэтому ЕСЛИ ВЫПОЛНЯЕТСЯ ЗАДАЧА, время выполнения тоже автоматически суммируется в mainTimer
- МЫ создаём несколько функций с разным периодом выполнения (задачи)
- Настраиваем период пробуждения системы (минимально 15 мс) Далее всё автоматически:
- Рассчитывается время до выполнения самой "ближней" задачи
- Система периодически просыпается и считает таймеры
-
При наступлении времени выполнения ближайшей задачи, она выполняется. После этого снова выполняется расчёт времени до новой ближайшей задачи
Как итог: Ардуино спит (в зависимости от периодов) 99.999% времени, просыпаясь только для проверки флага и расчёта таймера СМОТРИ ПРИМЕР
Абалдеть! Ну, спасибо :)))
Спасибо!
Попытка скомпилировать пример в IDE 1.8.5 дала следующее
Gbutton_example:5:13: error: expected ',' or '...' before numeric constant #define PIN 3 // РєРЅРѕРїРєР° подключена СЃСЋРґР° (PIN --- РљРќРћРџРљРђ --- GND) ^ sketch\GyverButton.h:27:18: note: in expansion of macro 'PIN' GButton(uint8_t PIN, boolean type, boolean dir); // класс РєРЅРѕРїРєРё, принимает PIN РїРёРЅ, тип type (HIGH_PULL / LOW_PULL) Рё направление dir (NORM_OPEN / NORM_CLOSE) ^ In file included from C:\Temp\GyverLibs-master\GyverButton\examples\Gbutton_example\Gbutton_example.ino:7:0: sketch\GyverButton.h:27:2: error: 'GButton::GButton(uint8_t)' cannot be overloaded GButton(uint8_t PIN, boolean type, boolean dir); // класс РєРЅРѕРїРєРё, принимает PIN РїРёРЅ, тип type (HIGH_PULL / LOW_PULL) Рё направление dir (NORM_OPEN / NORM_CLOSE) ^ sketch\GyverButton.h:25:5: error: with 'GButton::GButton(uint8_t)' GButton(uint8_t pin); // класс РєРЅРѕРїРєРё, принимает РїРёРЅ ^ sketch\GyverButton.cpp: In constructor 'GButton::GButton(uint8_t, boolean, boolean)': sketch\GyverButton.cpp:13:22: warning: cannot call constructor 'GButton::GButton' directly [-fpermissive] GButton::GButton(PIN); ^ sketch\GyverButton.cpp:13:22: note: for a function-style cast, remove the redundant '::GButton' exit status 1 expected ',' or '...' before numeric constantЗаменил PIN на _PIN_ - скомпилировалось
при этом пустой скетч компилируется
Не многовато ли для кнопки-то?
Попробовал пример с RTOS. Результат
In file included from C:\Temp\\GyverLibs-master\GyverRTOS\examples\multitaskNew\multitaskNew.ino:1:0: sketch\GyverRTOS.h:110:28: warning: unused parameter 'buf' [-Wunused-parameter] void GRTOS::wake(uint32_t* buf, uint32_t* mainTimer) { ^ sketch\GyverRTOS.h: In member function 'uint32_t Gtask::tick(uint32_t*, uint32_t*)': sketch\GyverRTOS.h:169:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ Скетч использует 2598 байт (8%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 268 байт (13%) динамической памяти, оставляя 1780 байт для локальных переменных. Максимум: 2048 байт.Попробовал пример с таймером. Компиляция
sketch\GyverTimer.cpp: In member function 'boolean GTimer_ms::isReady()': sketch\GyverTimer.cpp:19:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if ((long)millis() > _timer) {Предположил, что для больших интервалов это не работает. Полез в код - всё ещё хуже, таймер не работает для интервалов больших, чем 65535 миллисекунд, т.к. тип переменной, задающей интервал - uint16_t.
Посмотрел код внимательнее - всё даже ещё хуже.
Во-первых, таймер всегда врёт на миллисекунду, т.к. сравнение идёт на ">", а не на ">=". Пример:
#include "GyverTimer.h" GTimer_ms myTimer1(100); void setup() { Serial.begin(57600); } void loop() { if (myTimer1.isReady()) { Serial.print(millis()); Serial.println(" - 100 ms elapsed"); } } ///////////////// результат // 101 - 100 ms elapsed // 202 - 100 ms elapsed // 303 - 100 ms elapsed // 404 - 100 ms elapsed // 505 - 100 ms elapsed // 606 - 100 ms elapsed // 707 - 100 ms elapsed // 808 - 100 ms elapsed // 909 - 100 ms elapsed // 1010 - 100 ms elapsed // 1111 - 100 ms elapsed // 1212 - 100 ms elapsed // 1313 - 100 ms elapsed // 1414 - 100 ms elapsed // 1515 - 100 ms elapsed // 1616 - 100 ms elapsed // 1717 - 100 ms elapsed // 1818 - 100 ms elapsed // 1920 - 100 ms elapsed // 2021 - 100 ms elapsed // 2122 - 100 ms elapsed // 2223 - 100 ms elapsed // 2324 - 100 ms elapsed // 2425 - 100 ms elapsed // 2526 - 100 ms elapsed // 2627 - 100 ms elapsed // 2728 - 100 ms elapsed // 2829 - 100 ms elapsedНо, это ещё не всё. Переменная _mode нигде и никак не инициализируется, а значит, если создавать экземпляр класса не статически, а динамически (на стеке или в куче), то поведение попросту непредсказуемо. Пример.
#include "GyverTimer.h" void setup() { Serial.begin(57600); } void myFunc() { char * s1 = (char *) "Stupid msg 1"; char * s2 = (char *) "Stupid msg 2"; String s = s1; s += s2; Serial.println(s); } void loop() { myFunc(); GTimer_ms * myTimer1 = new GTimer_ms(100); while (true) { if (myTimer1->isReady()) { Serial.print(millis()); Serial.println(" - 100 ms elapsed"); } } } ////////// результат // Stupid msg 1Stupid msg 2 //Stupid msg 1Stupid msg 2 //101 - 100 ms elapsed //101 - 100 ms elapsed //101 - 100 ms elapsed //101 - 100 ms elapsed //104 - 100 ms elapsed //108 - 100 ms elapsed //112 - 100 ms elapsed //115 - 100 ms elapsed //119 - 100 ms elapsed //123 - 100 ms elapsed //126 - 100 ms elapsed //131 - 100 ms elapsed //135 - 100 ms elapsed //138 - 100 ms elapsed //142 - 100 ms elapsed //146 - 100 ms elapsed //149 - 100 ms elapsed //153 - 100 ms elapsed //157 - 100 ms elapsed //160 - 100 ms elapsed //164 - 100 ms elapsed //168 - 100 ms elapsed //172 - 100 ms elapsed //176 - 100 ms elapsed //180 - 100 ms elapsed //183 - 100 ms elapsed //187 - 100 ms elapsed //190 - 100 ms elapsed //194 - 100 ms elapsed //198 - 100 ms elapsed //201 - 100 ms elapsed //205 - 100 ms elapsed //209 - 100 ms elapsed //212 - 100 ms elapsed //217 - 100 ms elapsed //221 - 100 ms elapsed //224 - 100 ms elapsed //228 - 100 ms elapsed //232 - 100 ms elapsed //235 - 100 ms elapsed //239 - 100 ms elapsed //243 - 100 ms elapsed //246 - 100 ms elapsed //250 - 100 ms elapsed //254 - 100 ms elapsed //258 - 100 ms elapsed //262 - 100 ms elapsed //266 - 100 ms elapsed //269 - 100 ms elapsed //273 - 100 ms elapsed //276 - 100 ms elapsed //280 - 100 ms elapsed //284 - 100 ms elapsed //287 - 100 ms elapsed //291 - 100 ms elapsed //295 - 100 ms elapsed //299 - 100 ms elapsed //303 - 100 ms elapsed //307 - 100 ms elapsed //310 - 100 ms elapsed //314 - 100 ms elapsed //318 - 100 ms elapsed //321 - 100 ms elapsed //325 - 100 ms elapsed //329 - 100 ms elapsed //332 - 100 ms elapsed //336 - 100 ms elapsed //340 - 100 ms elapsed //344 - 100 ms elapsed //348 - 100 ms elapsed //352 - 100 ms elapsed //355 - 100 ms elapsed //359 - 100 ms elapsed //362 - 100 ms elapsed //366 - 100 ms elapsed //370 - 100 ms elapsed //373 - 100 ms elapsed //377 - 100 ms elapsed //381 - 100 ms elapsed //385 - 100 ms elapsed //389 - 100 ms elapsed //393 - 100 ms elapsed //396 - 100 ms elapsed //400 - 100 ms elapsed //404 - 100 ms elapsed //407 - 100 ms elapsed //411 - 100 ms elapsed //415 - 100 ms elapsed //418 - 100 ms elapsed //422 - 100 ms elapsed //427 - 100 ms elapsed //430 - 100 ms elapsed //434 - 100 ms elapsed //438 - 100 ms elapsed //441 - 100 ms elapsed //445 - 100 ms elapsed //448 - 100 ms elapsed //452 - 100 ms elapsed //456 - 100 ms elapsed //459 - 100 ms elapsed //463 - 100 ms elapsed //467 - 100 ms elapsed //471 - 100 ms elapsed //475 - 100 ms elapsed //479 - 100 ms elapsed //482 - 100 ms elapsed //486 - 100 ms elapsed //490 - 100 ms elapsedСтоит здесь закомментировать строку 17 - всё работает нормально (врёт на 1 мс как обычно, но работает), а вот с той строкой наблюдаем бред, который я привёл.
В общем, работа проделана большая, но, к сожалению, качество - как у большинства "суперлиб" - "Хотели, как лучше, а получилось ..."
Вот же не ленивый!
А ТС-то критики не просил. Я уже давно избегаю критиковать, когда явно не просят.
Спасибо, поправим. Это не суперлиба, писалось для личного удобства
Во всех примерах автоматом подключается Serial, которая и жрёт. В кнопке одна переменная uint_32, остальные булин флаги
//Библиотека для многофункциональной отработки нажатия кнопок с Arduino.
Хороше хоть Калапуций на форуме не дожил. ;)
В общем, работа проделана большая, но, к сожалению, качество - как у большинства "суперлиб" - "Хотели, как лучше, а получилось ..."
Почему то желание писать библиотеки и делится ими возникает в основном у тех, кому еще рано это делать. А когда люди дорастают до нужного уровня - желание писать библиотеки для новичков почему-то пропадает :)
Если чё, то остальные я не смотрел. Внимательно только по таймеру прошёлся. Боюсь, что в остальных тоже хватает :(
Это не суперлиба, писалось для личного удобства
Да нет, без дураков и безо всякого стёба - масштаб проделанной работы реально впечатляет и вызывает уважение.
Инициализировал все пустые булины, инициализацию тоже поправил где с дефайном совпасть может. На конструктивную критику не рассчитывал, но опыт рождается в исправлении своих же косяков =) так что буду рад узнать о других
AlexGyver - а можно кратенько обрисовать ваш опыт в программировании вообще на Си и для МК в частности?
так что буду рад узнать о других
как говорил наш зам декана - каждая последняя ошибка в программе является предпоследней
Кратенько:
- Сайт https://alexgyver.ru/ там в разделе "проекты"
- Все мои проекты (включая то чего нет на сайте) также есть тут https://github.com/AlexGyver
- Ну и в формате видосов тут https://www.youtube.com/channel/UCgtAOyEQdAyjvm9ATCi_Aig
- + Этот пакет библиотек, написанных "потому что интересно и хочется упростить себе жизнь"
Алекс, приветствую! Буду краток: сам виноват, держись ;) В том смысле - что у нас тут специфическая и открытая атмосфера, на чины и регалии - внимания ноль, всё по делу и жёстко ;)
Кратенько:
- Сайт https://alexgyver.ru/ там в разделе "проекты"
- Все мои проекты (включая то чего нет на сайте) также есть тут https://github.com/AlexGyver
Алекс, я же немного не об этом спрашивал. Проекты - это хорошо, но чтобы оценить их уровень, их надо серьезно разобрать. Сами по себе проекты ничего не доказывают... вон у известного ардуинщика Осипова сколько проектов на Ютубе, но все в основном либо элементарные. а как что посложнее - так косяк на косяке.
просто при всем уважении к работе, то, что Ворота вытащил из библиотеки Таймер - это полное непонимание основ работы МК, с таким уровнем библиотеки выкладывать стыдно.
Нормально все. Поменьшей мере автор библиотеки научился чему нибудь. И да некоторые ходы похожи на мои, хотя я не их первоткрыватель. И при чем тут понимание МК. Главное понимать как можно строить большие проекты на Си в среде Ардуино.
С каких пор >= и > это основы работы МК? Даже если и так, то я ардуинщик, вообще не программист и не микроконтроллерщик, мне не стыдно
горорил наш зам декана - каждая последняя ошибка в программе является предпоследней
Это он цитировал фундаментальный закон - "every last bug you found is actually the penultimate".
Авторство формулировки приписывают многим (например, Дейкстре), но Кнут вроде говорил, что он точно знает, что оригинальный автор - Фредерик Брукс.
какого фига вы тогда беретесь писать библиотеки, если вы не программист?
Дайте угадаю - потому что в свое время вы с огромным трудом разобрались, как же различить одинарное и двойное нажатие кнопки - и потому решили осчастливить новичков. чтоб они так не мучались? Увы и ах - эти мучения новичкам необходимы, без них они вряд ли освоят то, что освоили вы. А не новичкам ваши библиотеки тем более не нужны, потому что в силу того, что "вы не программист" - написаны они криво, содержат кучу как мелких, так и грубых ошибок (таких как переменная типа int для миллис). занимают кучу места и требуют много лишней памяти.
Догадки неверны, как и трактовка замечания про таймер. С кнопкой я без проблем сам разобрался и давно использую свои наработки. Переменная таймера была изначально uint32_t, как ей и нужно быть. Типом int была переменная, отвечающая за период работы таймера. И это был не косяк, а фича. Далее, не сказал бы, что библиотеки занимают много места (опять же, из того же комментария про таймер), в примере подключена Serial для отладки, которая и жрёт всё место, в самой библиотеке есть пачка булинов и один uint32_t, больше ничего. Вывод: не стоит делать выводы на основе комментариев, таки дела.
Алекс, не стоит, поверь. Вижу, что комментарии вполне по делу - тебя начинают задевать. Это значит - что ты не готов к критике, а она будет, поверь. Я тоже вот - заинтересовался, пойду, пожалуй, погляжу, что там в коде творится ;) Ведь ты берёшь на себя некоторую долю ответственности, выкладывая библиотеки, хочется тебе того, или нет.
ну понятно, очередная мега-библиотека, выложенная в сеть исключительно ради поднятия ЧСВ автора...
Сколько их таких уже на гитхабе, забытых через неделю после первого релиза
Я хотел критики, но конструктивной, как у человека с ником Ворота. А не кривого пересказа его комментария с полной потерей сути
Алекс, ты берёшь на себя некоторую долю ответственности, выкладывая библиотеки, хочется тебе того, или нет.
+100
Для себя можно писать как угодно. Но когда выкладываешь - дело другое. Не надо людей подставлять. Беря библиотеку, они рассчитвают получить полезный, детально проработанный грамотный код, а не наспех слепленную кучу глюков, на которую только убьешь время.
это был не косяк, а фича.
Ой, не надо! У нас тут уже есть два специалиста, у которых, что ни баг, то фича. Хватит с нас.
То, что у тебя в одних местах millis преобразуется к long, а в других таких же - нет, тоже фича? Больше похоже на поиск работающего варианта методом тыка.
Кстати, ты там окончание интервала сложением определяешь, так что, если бы ты не сделал "фичу" с шестнадцитибитным интервалом, то налетел бы на другую "фичу" - переполнение миллис. Ты в курсе что это такое?
Ты, парень убрал бы гонор, слушал бы и учился бы. Пользы больше.
Первый косяк, библиотека GyverPID:
pidTimer при этом объявлен норм:
Конструкции вида
говорят о том, что всё смешалось в доме Облонских - не надо так вольно смешивать типы переменных, иначе зачем pidTimer объявлена как uint32_t ????
Второй косяк - библиотека GyverRGВ:
Многие юзают ту же UTFT, где определены подобные дефайны, даже с такими же именами. В результате - можно получить кучу головняков в коде. Выход - есть, естественно ;)
Там же:
при этом deltaMax - объявлена как byte. Это - классическое "comparing signed and unsigned values", неаккуратненько ;)
GyverRelay - везде проходит, чего же здесь не пройти, да:
Там же:
int8_t sign(float value) { if (value > 0) return 1; else if (value == 0) return 0; else if (value < 0) return -1; }Второй
НИКОГДА не будет истиной, ибо - float и его представление: никогда он ТОЧНО не равен нулю.
Дальше продолжать, или не надо? Достаточно конструктивно?
В лонг преобразуем при арифметических вычислениях, работает и работало без этого. Конец интервала знаю, через 50 суток собьётся на несколько миллисекунд. Сделано во благо избавления от одного вычисления при вызове функции, раньше конец считался как в классе с микрос. Не согласен, что мой гонор не по делу
Во, вот это конструктив, спасибо
Во, вот это конструктив, спасибо
Ок. Класс GyverButton - Алекс, 27 (!), двадцать семь, Карл! байт переменных на один экземпляр класса кнопки - извини, но такое - категорически неприемлемо и не рекомендуется к применению, от слова "совсем". Это - само по себе, по факту двадцати семи байт, из которых большая часть в одном байте содержит только битовый флаг - очень плохо, очень.
Почитай про битовые поля, и создай вместо:
простую структурку, раз с битами не хочешь возиться:
#pragma pack(push,1) typedef struct { bool isHolded_f: 1; bool isRelease_f: 1; bool isPress_f: 1; bool step_flag: 1; bool oneClick_f: 1; bool isOne_f: 1; // тут другие битовые поля, там дохрена мусора ещё, который можно вынести сюда } GyverButtonFlags; #pragma pack(pop)Потом в классе вместо кучи переменных пишешь:
ну и где надо - проверяешь:
if(flags.isHolded_f) {...}В лонг преобразуем при арифметических вычислениях, работает и работало без этого. Конец интервала знаю, через 50 суток собьётся на несколько миллисекунд. Сделано во благо избавления от одного вычисления при вызове функции, раньше конец считался как в классе с микрос. Не согласен, что мой гонор не по делу
Понятно.
Ну, на "не согласен", и суда нет.
DIYMan, у нас кажется новый архат растёт? Вроде всё также - любой косяк - фича, готов убить программу ради экономии одного вычитания. Или мне показалось?
В лонг преобразуем при арифметических вычислениях, работает и работало без этого. Конец интервала знаю, через 50 суток собьётся на несколько миллисекунд. Сделано во благо избавления от одного вычисления при вызове функции, раньше конец считался как в классе с микрос. Не согласен, что мой гонор не по делу
Не надо там ничего преобразовывать, более того - то, что ты делаешь, в корне неверно. Просто надо почитать про беззнаковую арифметику и начать измерять прошедшие интервалы правильно - и волосы будут мягкими и шелковистыми. Вот так - неправильно:
uint16_t interval = 12000; uint32_t start = millis(); .... if( millis() >= (start + interval)) {...}А вот так - правильно:
uint16_t interval = 12000; uint32_t start = millis(); if(millis() - start >= interval) {...}Как видишь - ни одного кастования в long, с потерей половины размерности в диапазоне положительных чисел ;)
Кончайте травить пацана. Вон сколько всего перелопатил, старается. Лучше шефство возьмите, потычьте носом в стол, да научите чему-нибудь.
DIYMan, у нас кажется новый архат растёт? Вроде всё также - любой косяк - фича, готов убить программу ради экономии одного вычитания. Или мне показалось?
Да не, Алекс вроде норм парень, во всяком случае - заочно: горит, интересуется, видосы пилит. Тут главное, с его стороны - не упорствовать, а просто попытаться прислушаться. И его желание поделиться накопленным - тоже понятно, и даже где-то близко. Просто у нас тут атмосфера такая - критическая, о чём я Алекса предупреждал ;)
Вот такая работа с интервалом была изначально. Но. С пути меня сбил какой то умник, сказал что тут "лишнее вычитание". Таки дела!
Кончайте травить пацана. Вон сколько всего перелопатил, старается. Лучше шефство возьмите, потычьте носом в стол, да научите чему-нибудь.
Так вроде как раз стараюсь не травить - а показать тонкие места, которые в серьёзном проекте могут вылезти боком и попить немало крови. ЧЯДНТ?
Реально Ворота всё по делу сказал и указал. Остальные начали обсуждать личность "библиотекаря", что ему стОит делать, а чего не стОит.
Я в критических атмосферах с кучей хейта и десятками писем на мыло вращаюсь очень много, для нашего интернета это обычное дело.
Так ТС же объяснил, что он как раз вот это вычитание экономил!
if(millis() - start >= interval) {...}Так ТС же объяснил, что он как раз вот это вычитание экономил!
if(millis() - start >= interval) {...}Меня науськали более опытные. Но это не точно (про опытность)
потычьте носом в стол, да научите чему-нибудь.
А мы чо делаем? :)
Так оно и видно :)
Вот такая работа с интервалом была изначально. Но. С пути меня сбил какой то умник, сказал что тут "лишнее вычитание". Таки дела!
Алекс, умников тоже надо слушать с оглядкой. Я тебе не зря пишу "почитай про беззнаковую арифметику" ;) Тогда сам поймёшь, что проблемы переполнения, заворачивания через пуп земли, необходимости кастовать в другой тип - у беззнаковых типов нет, от слова "вообще": просто надо понимать, как арифметические операции работают с беззнаковыми переменными и какой результат при этом получается. И пусть тебя не смущает тот факт, что беззнаковая переменная может достичь своего максимального значения и начаться, грубо говоря, с нуля - с правильно применёнными арифметическими операциями - всё будет ок. Проще говоря: отнимая одну беззнаковую переменную от другой (при этом неважно, какая из них какой больше) - на выходе мы получим ПРАВИЛЬНОЕ беззнаковое число, содержащее разницу двух значений. А будешь прибавлять к беззнаковому интервал - рискуешь попасть на переполнение, со всеми вытекающими - а зачем насильственный секс там, где без него можно обойтись, правда?
Реально Ворота всё по делу сказал и указал. Остальные начали обсуждать личность "библиотекаря", что ему стОит делать, а чего не стОит.
И я - тоже? Ткни пальцем, где я личность обсуждал? Чисто ради справедливости.
Меня науськали более опытные. Но это не точно (про опытность)
Вы не там ищете эффективность.
Экономия на одном сложении иногда, крайне редко, бывает нужна и оправдана, напрмер, при работев прерыванияхи или при точном тайминге, но это реально редко. В большинстве же реальных программ гораздо большую экономию можно получить за счёт грамотной организации и проектирования. Вы постулат Вульфа знаете?
Про переполнение таймера я экспериментировал с искусственной функцией миллис, все косяки вроде прощупал вручную. По теории ничего не знаю, так как не было на неё времени. Только практика!
Про переполнение таймера я экспериментировал с искусственной функцией миллис,
Гораздо логичнее экпериментировать с реальной, просто начальным значением ей задать не 0, а что-нибудь близкое к переполнению.
А про теорию - это зря.
Но постулат Вульфа - не теория - это жизненное наблюдение. Вот здесь он у меня эпиграфом взят, почитайте.
Спасибо, изучу. Не думал, что можно функции миллис что то задать! Arduino reference такому не учит.
С булинами сделал как показали, давно искал удобный аналог ручной компановке битов в один булин... а оно и не нужно оказалось
Не думал, что можно функции миллис что то задать!
Ну, а чего нельзя-то? Вот здесь у меня эта техника используется. смотрите.
Проделана большая работа, но достаточно грязно. Впрочем, Вам тут уже указали на некоторые несуразности. Пересмотрите весь остальной код на подобные моменты. А в ,целом, мой совет: не принимайте близко к сердцу местные советы и тем более "наезды" и переходы на личность. Большая часть (практически все кто тут отметился) из них, ничего не писали тут самостоятельно! Поищите поиском, ничего кроме стеба толком и не найдете.
В Wiring принят достаточно сомнительный способ сквозной целочисленной нумерации пинов. Сомнительный потому что микроконтроллер (каждый!) это несколько специализированное устройство и каждый его вывод имеет свои "спец. функции", у некоторых что-то, куда-то можно "переназначить", но и только. Такой подход позволяет реализовывать "эмуляции" спец.функций ногодрыгами с превращением камня в нечто непотребное (ибо эмуляция), для каких-то задач это прокатывает, но только для "каких-то". А поскольку Ардуино как проект исключительно для обучения, то эти задачи тут составляют 80%. Проблема в том, что достаточно много людей пытаются применять "это" в практической работе МК.
Попробуйте, во-первых, представить "пин" как 2 байта: "порт" и "смещение". Это несколько увеличивает занимаемую память, но как показал мой опыт МЕНЬШЕ чем таблицы преобразования от Wiring в типовых (моих) применениях, но зато существенно улучшает реализацию большинства типовых функций базовой библиотеки, в т.ч. написание разных реализаций для "спец. функций" выводов.
Во-вторых, учитывая что порты 8-и битные (смещение занимает 3 бита) и портов меньше 16 (4бита) даже у Меги 2560 попробуйте реализовать однобайтовую нумерацию .. оно окажется несколько медленнее, но зато потребует меньшего места в ОЗУ под нумерацию пинов.
И ещё: такие вещи как билиотека Serial должно выкидывать и замещать своей, взяв за основу релиз из того же Cyberlib для УНО. Расписать остальные функции согласно даташиту - не проблема, в т.ч. и под "упрощенный RTOS" или "Автоматное, событийное" программирование. Также как и релиз остальных аппаратных интерфейсов I2C, SPI .. ничего супер сложного в них нет.
Дерзайте! :)
P.S. и меньше оглядывайтесь на "типовые библиотеки". Они по большей части (%90 не меньше) писаны такими вот дилетантами-советчиками и подлежат выбросу "не глядя". :)
Ну и ещё: http://easyelectronics.ru/rabota-s-portami-vvoda-vyvoda-mikrokontrollero... и гитхаб автора https://github.com/KonstantinChizhov/AvrProjects думаю будет полезно ознакомиться в плане иных вариантов реализаций..