Включить светодиоды из массива
У меня есть проект по созданию робота для моей школы. Он будет записывать нажатия кнопок, а затем перемещаться в соответствии с этой записью.
До того, как мы запустим двигатели, я пытаюсь сделать это с помощью светодиодов.
Благодаря сообщениям из этого сообщества, мне удалось записать нажатия кнопок в массиве.
Теперь я пытаюсь зажечь светодиоды в соответствии с этим массивом. У меня есть 4 кнопки с 4 светодиодами и одна кнопка для запуска записи, когда она будет готова.
Я застрял в освещении светодиодов, когда нажимаю кнопку play_button.
Я надеюсь, что кто-нибудь сможет мне помочь...
Вот мой сценарий :
int arr[10];
boolean previous = LOW;
unsigned long time1 = 0;
int debounce = 200;
unsigned long time2 = 0;
int index_state = 0;
int play_button = 13; //define pin # for play button
int button[4] = {2,4,6,8}; //store button pins in an array
int leds[4] = {3,5,7,9}; //store led pins in an array
void setup()
{
for(int n=0;n<10;n++) arr[n] = 0;//initialisition
Serial.begin(9600);
}
void loop(){
boolean mode = digitalRead(2) || digitalRead(4) || digitalRead(6) || digitalRead (8);
while(mode == LOW) mode = digitalRead(2) || digitalRead(4) || digitalRead(6) || digitalRead (8);//wait here till one of the pushbutton goes high;
//Serial.println("value");
if( mode == HIGH && previous == LOW && millis() - time1 > debounce) {
//find out which one is high and store that value in array;
if(digitalRead(2)) arr[index_state] = 2;
else if(digitalRead(4)) arr[index_state] = 4;
else if(digitalRead(6)) arr[index_state] = 6;
else if(digitalRead(8)) arr[index_state] = 8;
else ;
//print the value and the index;
Serial.print(arr[index_state]);
Serial.print(" Stored in index: ");
Serial.println(index_state);
index_state = (index_state + 1) % 10;
//update value of time1 for button debouncing
time1 = millis();
}
//update the value of previous button state
previous = digitalRead(2) || digitalRead(4) || digitalRead(6) || digitalRead(8);
}
Спасибо
@Jerome, 👍-1
1 ответ
У вас возникли проблемы с включением дополнительной функциональности (воспроизведение), поскольку ваша функция loop()
написана исключительно для обеспечения первой части функциональности (записи). Вам нужна общая структура, которая будет выполнять правильную функциональность в правильное время/в правильном логическом порядке.
Для этого лучше всего использовать Конечный автомат (FSM). Это поможет вам структурировать свой код и логику. Это важный принцип, который нужно усвоить.
Сначала вам придется разделить логику вашей программы на различные состояния и переходы между ними (на данный момент не смотрите слишком пристально на фактический код, но с более высокой абстракцией). В настоящее время я вижу 2 состояния в вашем проекте: состояние, в котором вы записываете нажатия кнопок в массив, как вы уже делали. И состояние, в котором массив используется для воспроизведения. Переход из первого состояния во второе происходит при нажатии кнопки воспроизведения. Обратный переход происходит, когда воспроизведение завершено. Это помогает нарисовать график для этого, визуализировать состояния и их переходы. В своем ответе на этот вопрос я объяснил это далее, включая пример такого графика.
Когда вы закончите создавать состояния и переходы, вы сможете создать необходимую структуру кода. Самый простой способ для новичка - использовать простую переменную состояния (просто целое число или - если вы хотите использовать имена состояний-перечисление) в операторе switch ()
- case. Вы также можете увидеть это в связанном ответе. Затем ваш код переходит в операторы case. Оператор switch будет выполнять код только для текущего состояния. Чтобы выполнить переход в другое состояние, вы просто меняете переменную состояния. Таким образом, в оператор case первого состояния вы вводите код, который у вас уже есть для чтения кнопок, и оператор if, который проверяет кнопку воспроизведения. Если кнопка воспроизведения была нажата, измените переменную состояния на второе состояние.
Вы также могли бы решить эту проблему без FSM, но структура будет не такой хорошей и ее будет легко расширить. Также вы можете получить некоторые дополнительные баллы за внедрение FSM :D
В настоящее время ваш код блокируется. Это означает, что он будет блокировать любую дальнейшую операцию до тех пор, пока что-то не произойдет, в данном случае, если будет нажата одна из 4 кнопок. Часто это является лишь помехой при добавлении функциональных возможностей. Лучше использовать do-возможно
, код, означает код, который будет что-то делать, только если будет выполнено какое-то условие (например, время). Вы уже делаете это в операторе if
if( mode == HIGH && previous == LOW && millis() - time1 > debounce) {
(это запускает запись новой кнопки только в том случае, если кнопка была нажата и время отмены прошло) так почему же вы блокируете до этого цикл while? Вы можете просто записать в режим
без цикла while.
- Хорошая кнопка debouncing/Библиотека StateChange
- Остановить мигание светодиодов
- Интеграция 2 кнопок для включения и выключения светодиода.
- Код Arduino для управления 4 светодиодами с 4 кнопок
- Нужен ли подтягивающий/понижающий резистор для цепи светодиода кнопки?
- Как прервать функцию цикла и перезапустить ее?
- Как перезапустить счетчик в программе с помощью кнопки в настройке LDR Tripwire
- Как записать последовательность кнопок и сохранить ее в массиве