Виж темите без отговор | Виж активните теми
Дата и час: Съб Апр 20, 2024 6:33 pm
Автор |
Съобщение |
tolstolob
Ранг: Ориентиран
Регистриран на: Вто Фев 06, 2007 1:45 am Мнения: 260
|
Re: Stop Loop
Защо са ни стейтове, като може да се изпълни с просто следене на фазите на бутона + таймери Накратко: пазим старата стойност на бутона в нечетен бит, а новата - в четен, и ги четем по двойки (анд-ването с 3 в макросите GetPhaseButtonХ() по-долу). Така имаме общо 4 възможни фази, като 2 от тях се случват еднократно (PRESSED and RELEASED) за един цикъл натискане-отпускане; съответно те са и най-интересни. Таймерите са 3-стейтни и винаги броят надолу. Удобни са, когато трябва да се реализира еднократно събитие (в случая 3 секунди импулс и 1 сек дилей). Четенето на бутоните може да се извади извън периодичното изпълнение (if ((timeNow - Status.timers.lastCallTime) >= TASK_CALL_PERIOD_MS)...) за по-бърза реакция. | | | | Код: #define Button_Up 8 #define Button_Down 9 #define Relay_Up 2 #define Relay_Compr 3 #define Relay_Down 4 #define TASK_CALL_PERIOD_MS 2
enum BtnPhase_t { PHASE_LOW = 0, PHASE_PRESSED = 1, PHASE_HIGH = 3, PHASE_RELEASED = 2 }
struct Status_t { uint8_t buttonPhases; struct { uint16_t relayUpPulse; uint16_t relayDownDelay; uint32_t lastCallTime; } timers; };
static struct Status_t Status;
uint8_t RefreshButtonPhases(void) { Status.buttonPhases = (Status.buttonPhases << 1) & ~((1 << 0) | (1 << 2)); Status.buttonPhases |= (digitalRead(Button_Up) << 0); Status.buttonPhases |= (digitalRead(Button_Down) << 2); return Status.buttonPhases; }
#define GetPhaseButtonUp(phase) ((phase) & 3) #define GetPhaseButtonDown(phase) (((phase) >> 2) & 3)
void setup() { pinMode(Button_Up, INPUT); pinMode(Button_Down, INPUT); pinMode(Relay_Up, OUTPUT); pinMode(Relay_Compr, OUTPUT); pinMode(Relay_Down, OUTPUT);
digitalWrite(Relay_Up, LOW); digitalWrite(Relay_Compr, LOW); digitalWrite(Relay_Down, LOW); Status.timers.lastCallTime = 0; }
void loop() { uint32_t timeNow = millis(); if ((timeNow - Status.timers.lastCallTime) >= TASK_CALL_PERIOD_MS) { uint8_t btnPhases = RefreshButtonPhases(); uint8_t phaseBtnUp = GetPhaseButtonUp(btnPhases); uint8_t phaseBtnDown = GetPhaseButtonDown(btnPhases); Status.timers.lastCallTime = timeNow; switch (phaseBtnUp) { case PHASE_PRESSED: digitalWrite(Relay_Up, HIGH); break; case PHASE_HIGH: break; case PHASE_RELEASED: digitalWrite(Relay_Up, LOW); digitalWrite(Relay_Down, LOW); digitalWrite(Relay_Compr, LOW); break; default: { switch (phaseBtnDown) { case PHASE_PRESSED: Status.timers.relayUpPulse = (3000 / TASK_CALL_PERIOD_MS) + 1; digitalWrite(Relay_Up, HIGH); break; case PHASE_RELEASED: // Stop all timers Status.timers.relayUpPulse = 0; Status.timers.relayDownDelay = 0; // All relays off digitalWrite(Relay_Up, LOW); digitalWrite(Relay_Down, LOW); digitalWrite(Relay_Compr, LOW); break; default: break; } break; } } switch (Status.timers.relayUpPulse) { case 0: break; case 1: { Status.timers.relayUpPulse = 0; Status.timers.relayDownDelay = (1000 / TASK_CALL_PERIOD_MS) + 1; digitalWrite(Relay_Up, LOW); digitalWrite(Relay_Compr, HIGH); break; } default: Status.timers.relayUpPulse--; break; } switch (Status.timers.relayDownDelay) { case 0: break; case 1: { Status.timers.relayDownDelay = 0; digitalWrite(Relay_Down, HIGH); break; } default: Status.timers.relayDownDelay--; break; } } } | | | | |
|
Пон Авг 17, 2020 10:39 am |
|
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 8:21 pm Мнения: 27998 Местоположение: София
|
Re: Stop Loop
Е това което си дал какво е че не са стейтове А използването на таймери в един момент започва да става не рационално, като трябва да инкрементваш или декрементваш по един куп таймери .... иначе е по-производително, или може да бъде по-производително.
|
Пон Авг 17, 2020 10:30 pm |
|
|
panchev68
Ранг: Минаващ
Регистриран на: Сря Сеп 28, 2011 9:04 am Мнения: 38
|
Re: Stop Loop
Защото до колкото разбрах от koko76bj Ардуино няма многозадачност. Или трябва да напишеш програма тип черва (абсолютно непрепоръчително), или да капсулираш всяко нещо в отделни модули като викаш определена loopback функция от модула при всеки loop. Това обаче означава, че не е добре да имаш забавяне в тези функции. За това ти е стейт машината и избягване на използването на delay(x) в тялото на тези функции. Аз нищо не разбирам от Ардуино (почти толкова и от C), просто се опитах да помогна на колегата да си свърши работа но не зная за какви макроси говориш. До колкото видях Ардуино използва C++ а там се съм чувал за такова понятие (или поне исках да не съм чувал) . Какво имам в предвид Това е сиснтаксис на C, не че не работи и в C++ но е много грозно като синтаксис при наличие на static inline функции това направо си изглежда кофти (недай си боже за някаква по-сложна функция). има и една по-готина алтернатива като се нарича lambdaдето си пишеш "МАКРОСИ" директо в тялото на функцията ,но не зная до кой диалект на C++ поддържа адруино. Но мисля ,че е поне C++11 което поддържа такива "МАКРОСИ". ако ти е интересно виж това https://en.cppreference.com/w/cpp/language/lambdaЕдин съвет: За да спестиш 1 байт RAM правиш "сериозни" врътки да съхраниш стейта на бутоните. Това наистина не е оправдано! Много ми хареса ми подхода на Jack - софруерна имплемнтация на базата на хардуерна логика Готино
_________________ Оставете човек в самолет и той ще летне за един ден. Хвърлете човек от самолета и той лети до края на живота си.
|
Пон Авг 17, 2020 11:23 pm |
|
|
tolstolob
Ранг: Ориентиран
Регистриран на: Вто Фев 06, 2007 1:45 am Мнения: 260
|
Re: Stop Loop
Е, в крайна сметка е така, то какво иначе да бъде Аз тригерирах по-скоро заради понятията: 'таймер' и 'фаза на бутон' са максимално близо до текста на заданието. Щото, 'state1' и т.н. до 'stateN' не ми е никак лесно за мапване към заданието. @panchev68, критиките към твоето решение са (заради което беше и моя пост): - Да ползваш FreeRTOS за такава задача, е като да трепеш мухи с лазерно оръдие. Съответно кода, който съм дал ще върви директно и на въшлив PIC10, но РТОС - едва ли. - Ако квалифицираш побитови операции като 'врътки', може би трябва да знаеш, че такива инструкции има дори и в цитирания по-горе пик, използването им е добре за 'пърформанса'. Веднага личи, че основната ти дейност не са контролерите. - Не знам как е по-елегантно да ползваш отделен хвърчащ байт за стария стейт на бутона, вместо целия ти стейт да стои само в един, но вкусове всякакви. Това е и любимия подход на индийците - предпочитат да има максимално много хвърчащи променливи със загадъчни имена и дълги черва от рода на
|
Вто Авг 18, 2020 10:25 am |
|
|
panchev68
Ранг: Минаващ
Регистриран на: Сря Сеп 28, 2011 9:04 am Мнения: 38
|
Re: Stop Loop
| | | | tolstolob написа: @panchev68, критиките към твоето решение са (заради което беше и моя пост): - Да ползваш FreeRTOS за такава задача, е като да трепеш мухи с лазерно оръдие. Съответно кода, който съм дал ще върви директно и на въшлив PIC10, но РТОС - едва ли. - Ако квалифицираш побитови операции като 'врътки', може би трябва да знаеш, че такива инструкции има дори и в цитирания по-горе пик, използването им е добре за 'пърформанса'. Веднага личи, че основната ти дейност не са контролерите. - Не знам как е по-елегантно да ползваш отделен хвърчащ байт за стария стейт на бутона, вместо целия ти стейт да стои само в един, но вкусове всякакви. Това е и любимия подход на индийците - предпочитат да има максимално много хвърчащи променливи със загадъчни имена и дълги черва от рода на | | | | |
Да със сигурност аруино не ми е интересно. Ако това визираш за среда за разработка на фирмуер за контролери ми е много тъжно за теб. На ATmega328P - 32К flash и 2 K RAM / на 20 MHz 8-битов процесор - не зная какви контролери правиш - дано ти се получава. Ако правиш управления за детски играчки или да мигат полседователно 2 светодиода това е OK . Все още не мога да разбера идеята ти да кодираш стейтовите в 1 общ стейт и на следващият ред да ги декодираш. Като толкова държих да са в 1 стейт защо не използваш union - пърформанса ще ти е в пъти. с цената на +1 байт в RAM-a. Както каза всеки има право да няма вкус. Не зная какво е pic10 и ptoc и "хвърчащ байт" , Това което си пуснал като пример си е жива стейт машина която по някой път се налага , все пак не всеки обича switch/case няма никаква връзка с капсулиране за което говорих. За FreeRTOS: 1-во никога няма да се хвана с подобна задача, 2. Не ми се занимаваще да търся командите на ардуино за да помогна на koko76bj и му пратих това с което ме е най-познато и му писах къде да търси. Поздрави.
_________________ Оставете човек в самолет и той ще летне за един ден. Хвърлете човек от самолета и той лети до края на живота си.
|
Вто Авг 18, 2020 11:58 am |
|
|
tolstolob
Ранг: Ориентиран
Регистриран на: Вто Фев 06, 2007 1:45 am Мнения: 260
|
Re: Stop Loop
Нямах намерение да пиша повече, но няма да оставя ad hominem подмятанията без отговор. Като вземем предвид следните бисери: - Пише " Аз нищо не разбирам от Ардуино (почти толкова и от C)" и "не зная за какви макроси говориш". Мисли, че макросите идват чак в С++11... - Бърка callback с loopback... - Бърка юниън с битфийлд... Ми и битфийлд да беше, нямаше да е "в пъти по-бърз" от маскиране и шифтване (конкретно 8-битови атмеги/пикове), щото отдолу генерирания асемблер е същия... Сега, че е по-четливо с бит фийлд, съгласен съм. - още не може да разбере идеята да "кодираш стейтовите в 1 общ стейт и на следващият ред да ги декодираш". Жокер: имаш едновременно ефективност (малка консумация РАМ, в един байт можеш да обработваш до 4 бутона и по-малко генерирани бранч инструкции, заради по-простите сравнения) + четливост. Може и вместо switch конструкции, да ползваш if-else черва, печалбата е 0. - Нарича Ардуино API-то "команди" - Прави грешни предположения за уменията/качествата на съфорумци, единствено защото му критикуват кода. Предвид изброеното по-горе, аз лично бих бил много скептичен към съветите на такъв 'специалист'. Айде със здраве.
|
Вто Авг 18, 2020 3:08 pm |
|
|
panchev68
Ранг: Минаващ
Регистриран на: Сря Сеп 28, 2011 9:04 am Мнения: 38
|
Re: Stop Loop
офф отвори си учебника за 1-ви клас по C "колегата" бърка lambda с неговите макроси - Мисли, че макросите идват чак в С++11... хаха по голяма тъпотия не бях чувал !!! "битфийлд" пак не зная какво е това ако имаш в предвид "Bit Fields" не е опция !!! има много по темата има си стандартен клас в C++ std::vector<bool> хаха а за уменията не коментирам нищо. Само ми е мъчно Поздрави
_________________ Оставете човек в самолет и той ще летне за един ден. Хвърлете човек от самолета и той лети до края на живота си.
|
Вто Авг 18, 2020 3:51 pm |
|
|
tolstolob
Ранг: Ориентиран
Регистриран на: Вто Фев 06, 2007 1:45 am Мнения: 260
|
Re: Stop Loop
Keep them coming Кажи сега за loopback-а, дето се вика циклично на всеки loop Трябва с Карадев да направите стартъп - той ще прави multidrop RS-232, ти ще плющиш луупбеци, unicorn най-много до месец https://en.wikipedia.org/wiki/Unicorn_(finance)
|
Вто Авг 18, 2020 4:24 pm |
|
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 10:22 pm Мнения: 3074
|
Re: Stop Loop
Момчета, сипете си по една бира, ако трябва - разделете си я....жегаво много. Ако може простичко да ми обясните какво е "ламбда", в кои диалекти го има. Това auto example()->void как се разшифрова? Гледам, че ви се пише,пък аз съм любопитко
|
Вто Авг 18, 2020 5:45 pm |
|
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 9:16 am Мнения: 1705
|
Re: Stop Loop
| | | | stefan63 написа: Момчета, сипете си по една бира, ако трябва - разделете си я....жегаво много. Ако може простичко да ми обясните какво е "ламбда", в кои диалекти го има. Това auto example()->void как се разшифрова? Гледам, че ви се пише,пък аз съм любопитко | | | | |
Ламбдата е анонимна функция. В примера по-горе е използвана тотално не на място и затова може би не ти е станало ясно. А за другият ти въпрос - като Ако няма причина да описвам типа на резултата по този начин (със стрелкичката), не бих го ползвал.
|
Сря Авг 19, 2020 8:16 am |
|
|
RGB
Ранг: Минаващ
Регистриран на: Чет Авг 20, 2020 7:17 am Мнения: 7 Местоположение: Пловдив
|
Re: Stop Loop
| | | | stefan63 написа: Момчета, сипете си по една бира, ако трябва - разделете си я....жегаво много. Ако може простичко да ми обясните какво е "ламбда", в кои диалекти го има. Това auto example()->void как се разшифрова? Гледам, че ви се пише,пък аз съм любопитко | | | | |
Lambda (closures) е функция, която можете да я напишете инлайн във вашия изходен код на функция (функция в функцията) auto example()->void при писане на c++ , когато в header(.hpp) файла имаш даден клас , много по-удобно е използването на този синтаксис в .cpp файла. panchev68 е в грешка Function-like мacros не заменят static inline и lambda function-like macros заместватват директо кода , докато другите 2 имат физическо изражение (тоест можеш да вземеш указател или референция към тях). static inline function е по-рационалният подход пред function-like macros от гледна точка на оптимизация . Другото предимство е че може да се изпълняваш стъпка по-стъпка в debug. Аз поне никога няма да използвам сложни function-like макроси. Това е предпоставка за трудно откриваеми грешки.
|
Чет Авг 20, 2020 8:00 am |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 5 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|