Организация многозадачности: циклы и мр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. Молодежь меня, конечно, за это закидает тапками, но мне пофиг, потому как мое устройство исправно поливало грядку в прошлом сезоне...