Несколько интересных и полезных библиотек
- Войдите на сайт для отправки комментариев
Всем привет, решил поделиться своими библиотеками, написанными для разных проектов. Библиотеки в целом заменяют часто используемые стандартные конструкции, упрощая и ускоряя написание кода. Сразу хочу предупредить, что написаны они человеком-ардуинщиком-самоучкой, т.е. никаких ассемблеров, сплошь стандартные костыли и функции. Но всё работает, и работает отлично для моих целей и целей типичного "новичка". Актуальные версии и краткое описание методов всегда находится здесь 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 дала следующее
01
Gbutton_example:5:13: error: expected
','
or
'...'
before numeric constant
02
03
#define PIN 3 // кнопка подключена сюда (PIN --- КНОПКА --- GND)
04
05
^
06
07
sketch\GyverButton.h:27:18: note:
in
expansion of macro
'PIN'
08
09
GButton(uint8_t PIN, boolean type, boolean dir);
// класс кнопки, принимает PIN пин, тип type (HIGH_PULL / LOW_PULL) и направление dir (NORM_OPEN / NORM_CLOSE)
10
11
^
12
13
In file included from C:\Temp\GyverLibs-master\GyverButton\examples\Gbutton_example\Gbutton_example.ino:7:0:
14
15
sketch\GyverButton.h:27:2: error:
'GButton::GButton(uint8_t)'
cannot be overloaded
16
17
GButton(uint8_t PIN, boolean type, boolean dir);
// класс кнопки, принимает PIN пин, тип type (HIGH_PULL / LOW_PULL) и направление dir (NORM_OPEN / NORM_CLOSE)
18
19
^
20
21
sketch\GyverButton.h:25:5: error: with
'GButton::GButton(uint8_t)'
22
23
GButton(uint8_t pin);
// класс кнопки, принимает пин
24
25
^
26
27
sketch\GyverButton.cpp: In constructor
'GButton::GButton(uint8_t, boolean, boolean)'
:
28
29
sketch\GyverButton.cpp:13:22: warning: cannot call constructor
'GButton::GButton'
directly [-fpermissive]
30
31
GButton::GButton(PIN);
32
33
^
34
35
sketch\GyverButton.cpp:13:22: note:
for
a function-style cast, remove the redundant
'::GButton'
36
37
exit status 1
38
expected
','
or
'...'
before numeric constant
Заменил PIN на _PIN_ - скомпилировалось
при этом пустой скетч компилируется
Не многовато ли для кнопки-то?
Попробовал пример с RTOS. Результат
01
In file included from C:\Temp\\GyverLibs-master\GyverRTOS\examples\multitaskNew\multitaskNew.ino:1:0:
02
03
sketch\GyverRTOS.h:110:28: warning: unused parameter
'buf'
[-Wunused-parameter]
04
05
void
GRTOS::wake(uint32_t* buf, uint32_t* mainTimer) {
06
07
^
08
09
sketch\GyverRTOS.h: In member function
'uint32_t Gtask::tick(uint32_t*, uint32_t*)'
:
10
11
sketch\GyverRTOS.h:169:1: warning: no
return
statement
in
function returning non-
void
[-Wreturn-type]
12
13
}
14
15
^
16
17
Скетч использует 2598 байт (8%) памяти устройства. Всего доступно 32256 байт.
18
Глобальные переменные используют 268 байт (13%) динамической памяти, оставляя 1780 байт для локальных переменных. Максимум: 2048 байт.
Попробовал пример с таймером. Компиляция
1
sketch\GyverTimer.cpp: In member function
'boolean GTimer_ms::isReady()'
:
2
3
sketch\GyverTimer.cpp:19:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
4
5
if
((
long
)millis() > _timer) {
Предположил, что для больших интервалов это не работает. Полез в код - всё ещё хуже, таймер не работает для интервалов больших, чем 65535 миллисекунд, т.к. тип переменной, задающей интервал - uint16_t.
Посмотрел код внимательнее - всё даже ещё хуже.
Во-первых, таймер всегда врёт на миллисекунду, т.к. сравнение идёт на ">", а не на ">=". Пример:
01
#include "GyverTimer.h"
02
03
GTimer_ms myTimer1(100);
04
05
void
setup
() {
06
Serial
.begin(57600);
07
}
08
09
void
loop
() {
10
if
(myTimer1.isReady()) {
11
Serial
.print(millis());
12
Serial
.println(
" - 100 ms elapsed"
);
13
}
14
}
15
16
///////////////// результат
17
// 101 - 100 ms elapsed
18
// 202 - 100 ms elapsed
19
// 303 - 100 ms elapsed
20
// 404 - 100 ms elapsed
21
// 505 - 100 ms elapsed
22
// 606 - 100 ms elapsed
23
// 707 - 100 ms elapsed
24
// 808 - 100 ms elapsed
25
// 909 - 100 ms elapsed
26
// 1010 - 100 ms elapsed
27
// 1111 - 100 ms elapsed
28
// 1212 - 100 ms elapsed
29
// 1313 - 100 ms elapsed
30
// 1414 - 100 ms elapsed
31
// 1515 - 100 ms elapsed
32
// 1616 - 100 ms elapsed
33
// 1717 - 100 ms elapsed
34
// 1818 - 100 ms elapsed
35
// 1920 - 100 ms elapsed
36
// 2021 - 100 ms elapsed
37
// 2122 - 100 ms elapsed
38
// 2223 - 100 ms elapsed
39
// 2324 - 100 ms elapsed
40
// 2425 - 100 ms elapsed
41
// 2526 - 100 ms elapsed
42
// 2627 - 100 ms elapsed
43
// 2728 - 100 ms elapsed
44
// 2829 - 100 ms elapsed
Но, это ещё не всё. Переменная _mode нигде и никак не инициализируется, а значит, если создавать экземпляр класса не статически, а динамически (на стеке или в куче), то поведение попросту непредсказуемо. Пример.
001
#include "GyverTimer.h"
002
003
void
setup
() {
004
Serial
.begin(57600);
005
}
006
007
void
myFunc() {
008
char
* s1 = (
char
*)
"Stupid msg 1"
;
009
char
* s2 = (
char
*)
"Stupid msg 2"
;
010
String s = s1;
011
s += s2;
012
Serial
.println(s);
013
}
014
015
016
void
loop
() {
017
myFunc();
018
GTimer_ms * myTimer1 =
new
GTimer_ms(100);
019
while
(
true
) {
020
if
(myTimer1->isReady()) {
021
Serial
.print(millis());
022
Serial
.println(
" - 100 ms elapsed"
);
023
}
024
}
025
}
026
027
////////// результат
028
// Stupid msg 1Stupid msg 2
029
//Stupid msg 1Stupid msg 2
030
//101 - 100 ms elapsed
031
//101 - 100 ms elapsed
032
//101 - 100 ms elapsed
033
//101 - 100 ms elapsed
034
//104 - 100 ms elapsed
035
//108 - 100 ms elapsed
036
//112 - 100 ms elapsed
037
//115 - 100 ms elapsed
038
//119 - 100 ms elapsed
039
//123 - 100 ms elapsed
040
//126 - 100 ms elapsed
041
//131 - 100 ms elapsed
042
//135 - 100 ms elapsed
043
//138 - 100 ms elapsed
044
//142 - 100 ms elapsed
045
//146 - 100 ms elapsed
046
//149 - 100 ms elapsed
047
//153 - 100 ms elapsed
048
//157 - 100 ms elapsed
049
//160 - 100 ms elapsed
050
//164 - 100 ms elapsed
051
//168 - 100 ms elapsed
052
//172 - 100 ms elapsed
053
//176 - 100 ms elapsed
054
//180 - 100 ms elapsed
055
//183 - 100 ms elapsed
056
//187 - 100 ms elapsed
057
//190 - 100 ms elapsed
058
//194 - 100 ms elapsed
059
//198 - 100 ms elapsed
060
//201 - 100 ms elapsed
061
//205 - 100 ms elapsed
062
//209 - 100 ms elapsed
063
//212 - 100 ms elapsed
064
//217 - 100 ms elapsed
065
//221 - 100 ms elapsed
066
//224 - 100 ms elapsed
067
//228 - 100 ms elapsed
068
//232 - 100 ms elapsed
069
//235 - 100 ms elapsed
070
//239 - 100 ms elapsed
071
//243 - 100 ms elapsed
072
//246 - 100 ms elapsed
073
//250 - 100 ms elapsed
074
//254 - 100 ms elapsed
075
//258 - 100 ms elapsed
076
//262 - 100 ms elapsed
077
//266 - 100 ms elapsed
078
//269 - 100 ms elapsed
079
//273 - 100 ms elapsed
080
//276 - 100 ms elapsed
081
//280 - 100 ms elapsed
082
//284 - 100 ms elapsed
083
//287 - 100 ms elapsed
084
//291 - 100 ms elapsed
085
//295 - 100 ms elapsed
086
//299 - 100 ms elapsed
087
//303 - 100 ms elapsed
088
//307 - 100 ms elapsed
089
//310 - 100 ms elapsed
090
//314 - 100 ms elapsed
091
//318 - 100 ms elapsed
092
//321 - 100 ms elapsed
093
//325 - 100 ms elapsed
094
//329 - 100 ms elapsed
095
//332 - 100 ms elapsed
096
//336 - 100 ms elapsed
097
//340 - 100 ms elapsed
098
//344 - 100 ms elapsed
099
//348 - 100 ms elapsed
100
//352 - 100 ms elapsed
101
//355 - 100 ms elapsed
102
//359 - 100 ms elapsed
103
//362 - 100 ms elapsed
104
//366 - 100 ms elapsed
105
//370 - 100 ms elapsed
106
//373 - 100 ms elapsed
107
//377 - 100 ms elapsed
108
//381 - 100 ms elapsed
109
//385 - 100 ms elapsed
110
//389 - 100 ms elapsed
111
//393 - 100 ms elapsed
112
//396 - 100 ms elapsed
113
//400 - 100 ms elapsed
114
//404 - 100 ms elapsed
115
//407 - 100 ms elapsed
116
//411 - 100 ms elapsed
117
//415 - 100 ms elapsed
118
//418 - 100 ms elapsed
119
//422 - 100 ms elapsed
120
//427 - 100 ms elapsed
121
//430 - 100 ms elapsed
122
//434 - 100 ms elapsed
123
//438 - 100 ms elapsed
124
//441 - 100 ms elapsed
125
//445 - 100 ms elapsed
126
//448 - 100 ms elapsed
127
//452 - 100 ms elapsed
128
//456 - 100 ms elapsed
129
//459 - 100 ms elapsed
130
//463 - 100 ms elapsed
131
//467 - 100 ms elapsed
132
//471 - 100 ms elapsed
133
//475 - 100 ms elapsed
134
//479 - 100 ms elapsed
135
//482 - 100 ms elapsed
136
//486 - 100 ms elapsed
137
//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:
1
pidTimer = (
long
)millis() + dt;
pidTimer при этом объявлен норм:
1
uint32_t pidTimer
Конструкции вида
1
if
((
long
)millis() > pidTimer)
говорят о том, что всё смешалось в доме Облонских - не надо так вольно смешивать типы переменных, иначе зачем pidTimer объявлена как uint32_t ????
Второй косяк - библиотека GyverRGВ:
01
#define WHITE 0xFFFFFF // белый
02
#define SILVER 0xC0C0C0 // серебро
03
#define GRAY 0x808080 // серый
04
#define BLACK 0x000000 // чёрный
05
#define RED 0xFF0000 // красный
06
#define MAROON 0x800000 // бордовый
07
#define YELLOW 0xFFFF00 // жёлтый
08
#define OLIVE 0x808000 // олива
09
#define LIME 0x00FF00 // лайм
10
#define GREEN 0x008000 // зелёный
11
#define AQUA 0x00FFFF // аква
12
#define TEAL 0x008080 // цвет головы утки чирка <a href="https://odesign.ru/teal-color/" rel="nofollow">https://odesign.ru/teal-color/</a>
13
#define BLUE 0x0000FF // голубой
14
#define NAVY 0x000080 // тёмно-синий
15
#define PINK 0xFF00FF // розовый
16
#define PURPLE 0x800080 // пурпурный
Многие юзают ту же UTFT, где определены подобные дефайны, даже с такими же именами. В результате - можно получить кучу головняков в коде. Выход - есть, естественно ;)
Там же:
1
for
(
int
i = 0; i < deltaMax; i++)
при этом deltaMax - объявлена как byte. Это - классическое "comparing signed and unsigned values", неаккуратненько ;)
GyverRelay - везде проходит, чего же здесь не пройти, да:
1
if
((
long
)millis() > prevTime)
Там же:
1
int8_t sign(
float
value) {
2
if
(value > 0)
return
1;
3
else
if
(value == 0)
return
0;
4
else
if
(value < 0)
return
-1;
5
}
Второй
1
else
if
(value == 0)
return
0;
НИКОГДА не будет истиной, ибо - float и его представление: никогда он ТОЧНО не равен нулю.
Дальше продолжать, или не надо? Достаточно конструктивно?
В лонг преобразуем при арифметических вычислениях, работает и работало без этого. Конец интервала знаю, через 50 суток собьётся на несколько миллисекунд. Сделано во благо избавления от одного вычисления при вызове функции, раньше конец считался как в классе с микрос. Не согласен, что мой гонор не по делу
Во, вот это конструктив, спасибо
Во, вот это конструктив, спасибо
Ок. Класс GyverButton - Алекс, 27 (!), двадцать семь, Карл! байт переменных на один экземпляр класса кнопки - извини, но такое - категорически неприемлемо и не рекомендуется к применению, от слова "совсем". Это - само по себе, по факту двадцати семи байт, из которых большая часть в одном байте содержит только битовый флаг - очень плохо, очень.
Почитай про битовые поля, и создай вместо:
1
boolean isHolded_f =
false
, isRelease_f =
false
, isPress_f =
false
, step_flag =
false
, oneClick_f =
false
, isOne_f =
false
;
простую структурку, раз с битами не хочешь возиться:
01
#pragma pack(push,1)
02
typedef
struct
03
{
04
bool
isHolded_f: 1;
05
bool
isRelease_f: 1;
06
bool
isPress_f: 1;
07
bool
step_flag: 1;
08
bool
oneClick_f: 1;
09
bool
isOne_f: 1;
10
// тут другие битовые поля, там дохрена мусора ещё, который можно вынести сюда
11
12
} GyverButtonFlags;
13
#pragma pack(pop)
Потом в классе вместо кучи переменных пишешь:
1
GyverButtonFlags flags;
ну и где надо - проверяешь:
1
if
(flags.isHolded_f) {...}
В лонг преобразуем при арифметических вычислениях, работает и работало без этого. Конец интервала знаю, через 50 суток собьётся на несколько миллисекунд. Сделано во благо избавления от одного вычисления при вызове функции, раньше конец считался как в классе с микрос. Не согласен, что мой гонор не по делу
Понятно.
Ну, на "не согласен", и суда нет.
DIYMan, у нас кажется новый архат растёт? Вроде всё также - любой косяк - фича, готов убить программу ради экономии одного вычитания. Или мне показалось?
В лонг преобразуем при арифметических вычислениях, работает и работало без этого. Конец интервала знаю, через 50 суток собьётся на несколько миллисекунд. Сделано во благо избавления от одного вычисления при вызове функции, раньше конец считался как в классе с микрос. Не согласен, что мой гонор не по делу
Не надо там ничего преобразовывать, более того - то, что ты делаешь, в корне неверно. Просто надо почитать про беззнаковую арифметику и начать измерять прошедшие интервалы правильно - и волосы будут мягкими и шелковистыми. Вот так - неправильно:
1
uint16_t interval = 12000;
2
3
uint32_t start = millis();
4
5
....
6
7
if
( millis() >= (start + interval)) {...}
А вот так - правильно:
1
uint16_t interval = 12000;
2
3
uint32_t start = millis();
4
5
if
(millis() - start >= interval) {...}
Как видишь - ни одного кастования в long, с потерей половины размерности в диапазоне положительных чисел ;)
Кончайте травить пацана. Вон сколько всего перелопатил, старается. Лучше шефство возьмите, потычьте носом в стол, да научите чему-нибудь.
DIYMan, у нас кажется новый архат растёт? Вроде всё также - любой косяк - фича, готов убить программу ради экономии одного вычитания. Или мне показалось?
Да не, Алекс вроде норм парень, во всяком случае - заочно: горит, интересуется, видосы пилит. Тут главное, с его стороны - не упорствовать, а просто попытаться прислушаться. И его желание поделиться накопленным - тоже понятно, и даже где-то близко. Просто у нас тут атмосфера такая - критическая, о чём я Алекса предупреждал ;)
Вот такая работа с интервалом была изначально. Но. С пути меня сбил какой то умник, сказал что тут "лишнее вычитание". Таки дела!
Кончайте травить пацана. Вон сколько всего перелопатил, старается. Лучше шефство возьмите, потычьте носом в стол, да научите чему-нибудь.
Так вроде как раз стараюсь не травить - а показать тонкие места, которые в серьёзном проекте могут вылезти боком и попить немало крови. ЧЯДНТ?
Реально Ворота всё по делу сказал и указал. Остальные начали обсуждать личность "библиотекаря", что ему стОит делать, а чего не стОит.
Я в критических атмосферах с кучей хейта и десятками писем на мыло вращаюсь очень много, для нашего интернета это обычное дело.
Так ТС же объяснил, что он как раз вот это вычитание экономил!
1
if
(millis() - start >= interval) {...}
Так ТС же объяснил, что он как раз вот это вычитание экономил!
1
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 думаю будет полезно ознакомиться в плане иных вариантов реализаций..