Написать условие для выполнения 2 функций с переключателями?
Я новичок в программировании и использовании продуктов Arduino, и мне было интересно, не будет ли кто-нибудь не против помочь мне с проектом, которым я пытаюсь заняться?
Если вы просмотрите мой код ниже, у меня есть 3 условия в моем случае "простоя", и программа постоянно ищет любое из этих 3 условий. Если выполняется первое условие, то вызывается случай 1; если выполняется второе условие, то вызывается случай 2; если выполняется третье условие, то вызывается случай 3. Все 3 случая возвращаются к "простаивающему" случаю после завершения работы.
Что я хотел бы сделать, так это найти способ вставить случай "предупреждение", если выполнено какое-либо из условий, ПРЕЖДЕ чем переходить к случаю 1, случаю 2 или случаю 3, не записывая функции случая "предупреждение" каждый раз для каждого из остальных 3 случаев. По сути, поток будет выглядеть следующим образом:
условие 1 --> предупреждение -->> случай 1 -->>> случай простоя;>>>
условие 2 --> предупреждение -->> случай 2 -->>> случай простоя;>>>
условие 3 --> предупреждение -->> случай 3 -->>> случай простоя:>>>
void loop() {
static byte theState = idle;
switch (theState)
{
case idle:
if (voltageA0 > 1.0) {
theState = case1;
}
if (voltageA1 < 2.0) {
theState = case2;
}
if (voltageA2 > 3.5) {
theState = case3;
}
break;
case warning:
digitalWrite(7, HIGH);
delay(5000);
digitalWrite(7, LOW);
delay(0);
break;
case 1:
digitalWrite(8, HIGH);
delay(2000);
digitalWrite(8, LOW);
delay(0);
theState = idle;
break;
case 2:
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
delay(0);
theState = idle;
break;
case 3:
digitalWrite(10, HIGH);
delay(2000);
digitalWrite(10, LOW);
delay(0);
theState = idle;
break;
}
}
Кроме того, если есть более эффективный способ сделать это с помощью кода, я весь внимание!
@Andrew, 👍2
Обсуждение2 ответа
case idle:
if (voltageA0 > 1.0 || voltageA1 < 2.0 || voltageA2 > 3.5) {
digitalWrite(7, HIGH);
delay(5000);
digitalWrite(7, LOW);
delay(0);
if (voltageA0 > 1.0) {
theState = case1;
}
if (voltageA1 < 2.0) {
theState = case2;
}
if (voltageA2 > 3.5) {
theState = case3;
}
}
Редактировать: Чтобы уточнить исходный ответ, я вставил код "предупреждение" и удалил "предупреждение о случае", так как очевидно, что это состояние больше не требуется.
Большое спасибо за вашу помощь, ребята! Полагаю, мне следовало бы объяснить, почему я использую конечный автомат для кода. Код, который я привел в качестве примера, опускает функции millis (), которые на самом деле есть в моем реальном коде. Я переписал пример без функций millis() просто на то, что я пытаюсь сделать, но случаи "предупреждение", "1", "2", и "3" все используют функции millis() для запуска светодиодов и реле. Извините, что не объяснил этого. Эдгар, спасибо, что указал на избыточность "delay(0);", которая у меня была... Я подумал, что это может быть излишним, но не был уверен. Исходя из того, что мне это нужно..., @Andrew
..вызовите другой набор функций после функции "предупреждение", специфичной для выполненного условия, я не верю, что предложенный вами пример сработает. Хотя я могу ошибаться, поэтому, пожалуйста, дайте мне знать, если я что-то пропустил :) Послушай, Альтерно, спасибо тебе и за помощь. Что-то еще, что я не объяснил, заключается в том, что состояние/функция "предупреждение" также исправляет условия, вызывая реле для отключения напряжения на некоторых устройствах. Последовательные случаи (1, 2, 3) просто используются в качестве индикатора, чтобы сказать мне, какое условие было только что выполнено, после того как состояние предупреждения устраняет проблему., @Andrew
Так что думайте об этом так... условие 1 вызовет предупреждающий случай, затем перейдите к случаю 1, где светодиод будет мигать 5 раз, указывая на то, что условие 1 только что было выполнено. условие 2 вызовет предупреждающий случай, затем перейдите к случаю 2, где светодиод будет мигать 10 раз, указывая на то, что условие 2 только что было выполнено. условие 3 вызовет предупреждающий случай, затем перейдите к случаю 3, где светодиод будет мигать 10 раз, указывая на то, что условие 3 только что было выполнено. Опять же, моя вина в том, что я не разработал все это изначально. Имеет ли это больше смысла?? Еще раз большое спасибо за помощь!, @Andrew
Спасибо! Но да, состояние предупреждения исправит любое из 3-х условий, поэтому проверка состояния ПОСЛЕ состояния предупреждения, к сожалению, не принесет никакой пользы. Лучший способ думать об этом-предположим, напряжение на выводе A0 увеличивается по мере того, как кастрюля с водой нагревается. Как только кастрюля с водой достигает определенной температуры (напряжения), функция "предупреждение" загорается светодиодом, скажем, на 10 минут, одновременно отключая источник тепла от кастрюли с водой. По истечении этих 10 минут корпус, связанный с условием (1, 2 или 3), будет мигать светодиодом определенное количество раз, указывая, какое условие было выполнено, @Andrew
Если температура воды падает ниже определенной температуры/напряжения, то срабатывает предупреждающий сигнал, а затем срабатывает сигнал 2, чтобы светодиод мигал разное количество раз, указывая на то, что сработало условие 2. Это не самые разумные примеры, но объяснить это проще, чем то, что и как я действительно контролирую входы на аналоговых выводах. Надеюсь, это имеет больше смысла, и еще раз спасибо!! :), @Andrew
В вашем коде есть что-то бессвязное. Он структурирован как
конечный автомат, и все же вы используете в нем функцию delay (). В такого рода
сценариях вся цель конечного автомата состоит в том, чтобы избежать использования
delay()
, так что ваша программа никогда не блокируется. Если вашей программе
нечем заняться, кроме как откладывать, вы можете отказаться от
конечного автомат и написать гораздо более простой код. Например:
void warn_and_flash(byte pin)
{
// Flash the "warning" LED.
digitalWrite(7, HIGH);
delay(5000);
digitalWrite(7, LOW);
// Flash the requested LED.
digitalWrite(pin, HIGH);
delay(2000);
digitalWrite(pin, LOW);
}
void loop()
{
if (voltageA0 > 1.0) warn_and_flash(8);
if (voltageA1 < 2.0) warn_and_flash(9);
if (voltageA2 > 3.5) warn_and_flash(10);
}
Я согласен. Представьте, что вы пишете код для автомобиля, а водитель надевает левый индикатор, который должен мигать раз в секунду. Вы действительно хотите, чтобы автомобиль игнорировал другие входы (тормоза, акселератор, кондиционер) в течение целой секунды, в то время как вы "задерживаетесь" на одну секунду? Думаю, нет., @Nick Gammon
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
- Запрограммировать ATMega328P и использовать его без платы Arduino.
- Не удается снова загрузиться после смены платы
- Как использовать этот 3-контактный ползунковый переключатель?
- ATMEGA328P-U vs ATMEGA328-PU
- Модуль SIM808 GSM работает нормально, GPS не работает (нет сообщения о готовности GPS при включении питания)
- Arduino 16 МГц только с 3,3 В?
- Генерация стабильной частоты
Упрощение кода перед его публикацией, как правило, хорошо. Но если вы измените его так сильно, что он станет в основном не связан с первоначальным, то правильный ответ на этот вопрос может быть неприменим к вашей реальной проблеме. Судя по вашим комментариям к ответу Look Alterno, это именно то, что произошло. Код _blocking_, который вы опубликовали, сильно отличается от неблокирующего кода, который вы используете. Пожалуйста, отредактируйте вопрос, чтобы он соответствовал вашей реальной проблеме. Это было бы более полезно, чем пытаться объяснить в комментариях степень различия кодов., @Edgar Bonet