Организация многозадачности: циклы и мр3 плеер с ИК управлением
- Войдите на сайт для отправки комментариев
Чт, 22/03/2018 - 14:29
Есть LED кубик, в котором поочередно крутится несколько циклов с эффектами. Есть свободные ноги на которые хочется повесить Мп3 плеер с управлением от ИК пульта.
Сразу прошу не закидывать тапками, а дать совет престарелому чайнику, ибо програмировал последний раз лет эдак 25 назад на Basic в институте).
Поломал все остатки мозгов видимо от недостаточности знаний дьявольского С++. Как организовать (гуру, подскажите хотя бы алгоритм) чтобы циклы крутились в рабочем режиме сами по себе, а ИК пульт был всегда готов принять и отработать команду типа переключить трек или изменить громкость... Спасайте...
З.Ы. - кусок кода с циклами (для примера)
void loop() { randomTimer++; loading = true; timer = 0; renderCube(); loading = true; planeBoing(); rain(); sendVoxels(); woopWoop(); cubeJump(); glow(); text("0123456789", 10); lit(); } void renderCube() { for (uint8_t i = 0; i < 8; i++) { digitalWrite(SS, LOW); SPI.transfer(0x01 << i); for (uint8_t j = 0; j < 8; j++) { SPI.transfer(cube[i][j]); } digitalWrite(SS, HIGH); } } void rain() { if (loading) { clearCube(); loading = false; } timer++; if (timer > RAIN_TIME) { timer = 0; shift(NEG_Y); uint8_t numDrops = random(0, 5); for (uint8_t i = 0; i < numDrops; i++) { setVoxel(random(0, 8), 7, random(0, 8)); } } } uint8_t planePosition = 0; uint8_t planeDirection = 0; bool looped = false; void planeBoing() { if (loading) { clearCube(); uint8_t axis = random(0, 3); planePosition = random(0, 2) * 7; setPlane(axis, planePosition); if (axis == XAXIS) { if (planePosition == 0) { planeDirection = POS_X; } else { planeDirection = NEG_X; } } else if (axis == YAXIS) { if (planePosition == 0) { planeDirection = POS_Y; } else { planeDirection = NEG_Y; } } else if (axis == ZAXIS) { if (planePosition == 0) { planeDirection = POS_Z; } else { planeDirection = NEG_Z; } } timer = 0; looped = false; loading = false; } timer++; if (timer > PLANE_BOING_TIME) { timer = 0; shift(planeDirection); if (planeDirection % 2 == 0) { planePosition++; if (planePosition == 7) { if (looped) { loading = true; } else { planeDirection++; looped = true; } } } else { planePosition--; if (planePosition == 0) { if (looped) { loading = true; } else { planeDirection--; looped = true; } } } } }
и т.д.
Спасибо за советы
Я сам престарелый чайник, сам подсел на ардуино 1 год назад, только в те далекие времена я программировал не на Бейсике, а на Си.
Чтобы циклы крутились в рабочем режиме сами по себе- это называется "кооперативная многозадачность", и на эту тему имеется достаточно много библиотек для ардуино. Но мы все любим идти своим путем... :)
Чтобы не ограничивать свободу творчества, даю несколько "наводок" на тему алгоритма
1. В стандартном ардуино IDE откройте Файл->Примеры->Digital->BlinkWithoutDelay
2. Поймите как там мигает светодиод и почему
3. Представьте, что вместо digitalWrite(ledPin, ledState) в примере вызывается одна из ваших функций
4. Организуйте таблицу, в каждой строке которой хранятся: времена последнего вызова данной функции, периодичность ее вызова, и собственно указатель на функцию, которую нужно вызывать
5. Можно добавить другие поля для расширения функционала ( например, флажки типа вызывать или не вызывать эту функцию на данном шаге алгоритма). Например, после того, как ваша функция отработала, она может сама себя "запретить" для вызова, а разрешить, например, другую, которая сработает, скажем, через 2 минуты, потом сама себя "запретит", а "разрешит", еще какую-то
6. Запихайте проверку очередной строки этой таблицы внуть loop(). Там проверяйте пора или не пора эту функцию вызвать, и если пора- вызывайте ее по указателю...
7. Все у вас будет крутиться в рабочем режиме самостоятельно, с нужной периодичностью вызываться. Можете проверять наличие сигнала от ИК пульта, например 1 раз в 500 мс ( я так делал- нажатия на пульт не терялись)
8. Логику работы устройства полезно нарисовать сначала хотя бы укрупненно в виде графа, где каждый узел -- состояние "конечного автомата" - легче будет программировать переходы- какие функции "запрещать", какие "разрешать"
Вот такие общие вам рекомендации.
Будет сложно -- опубликую фрагменты кода. Никакого C++, классический C от K&R. Молодежь меня, конечно, за это закидает тапками, но мне пофиг, потому как мое устройство исправно поливало грядку в прошлом сезоне...