Пытаюсь поддерживать мой основной код в рабочем состоянии, если ввод не будет LOW в течение определенного промежутка времени
У меня есть код, который создает последовательный сигнал с 4 светодиодами. Она ниспадает каскадом вправо. Это работает, когда я удерживаю нажатой кнопку ввода. В чем мне нужна помощь, так это в том, чтобы код выполнялся точно так же при наличии входного сигнала .5s HIGH -> .5s LOW (повтор). Итак, что я имею в виду в терминах псевдокода, так это код, который продолжает считывать ВЫСОКИЙ сигнал до тех пор, пока сигнал не будет низким более 5 секунд.
// Светодиодные выходы
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;
//правый указатель поворота
int RTS_IN = A0;
//переменная состояния для операторов switch case
int stateRightTurn = 0;
//временная переменная
unsigned long t = 0;
//интервал - это интервал времени между операторами case
unsigned long interval = 100;
//время отключения кода
unsigned long off = 600;
void setup()
{
Serial.begin(9600);
//вводит
pinMode(RTS_IN, INPUT);
//вывод сигнала правого поворота из левого в правый
pinMode(LED_5, OUTPUT);
pinMode(LED_6, OUTPUT);
pinMode(LED_7, OUTPUT);
pinMode(LED_8, OUTPUT);
}
void loop()
{
StateRight();
}
//последовательные сигналы поворота
void StateRight()
{
switch (stateRightTurn)
{
case 0: //холостой ход
if (digitalRead(RTS_IN) == HIGH)
{
Serial.println("0000");
t = millis();
SwitchRightLedsOff();
stateRightTurn = 1;
}
break;
case 1: // Один светодиод горит
if (digitalRead(RTS_IN) == LOW)
{
Serial.println("1111-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (millis() > t + interval)
{
Serial.println("1111-HHHHHHHH");
t = millis();
digitalWrite(LED_5, HIGH);
stateRightTurn = 2;
}
break;
case 2: // Два светодиода горят
if (digitalRead(RTS_IN) == LOW)
{
Serial.println("2222-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (millis() > t + interval)
{
Serial.println("2222-HHHHHHHH");
t = millis();
digitalWrite(LED_6, HIGH);
stateRightTurn = 3;
}
break;
case 3: // Три светодиода включены
if (digitalRead(RTS_IN) == LOW)
{
Serial.println("3333-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (millis() > t + interval)
{
Serial.println("3333-HHHHHHHH");
t = millis();
digitalWrite(LED_7, HIGH);
stateRightTurn = 4;
}
break;
case 4: // Четыре светодиода включены
if (digitalRead(RTS_IN) == LOW)
{
Serial.println("4444-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (millis() > t + interval)
{
Serial.println("4444-HHHHHHHH");
t = millis();
digitalWrite(LED_8, HIGH);
stateRightTurn = 5;
}
break;
case 5: // Светодиоды не горят
if (digitalRead(RTS_IN) == LOW)
{
Serial.println("5555-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (millis() > t + interval)
{
Serial.println("55555-HHHHHHHH");
SwitchRightLedsOff();
stateRightTurn = 0;
}
break;
}
}
//способ отключения светодиодов
void SwitchRightLedsOff()
{
digitalWrite(LED_5, LOW);
digitalWrite(LED_6, LOW);
digitalWrite(LED_7, LOW);
digitalWrite(LED_8, LOW);
}
@Myles, 👍2
Обсуждение2 ответа
Если я правильно понимаю ваши требования, вы могли бы использовать переменную, чтобы определить, должны ли ваши последовательные индикаторы мигать или нет. Если входной сигнал НИЗКИЙ
более 1/2 секунды, переменная должна измениться на НИЗКИЙ
, сообщая Arduino прекратить мигание последовательных индикаторов.
Давайте представим, что ваш входной сигнал имеет правильное напряжение и очень точен с учетом времени. На отметке 501 мс, при отсутствии высокого
входного сигнала, ваши индикаторы должны перестать мигать.
Может работать простой таймер и переменная состояния. Вот тестовый набросок.
// Sketch использует 1144 байта (3%) дискового пространства программы.
// Глобальные переменные используют 19 байт (0%) динамической памяти.
class MillisTimer{
private:
unsigned long m_timeInMilliSeconds;
unsigned long m_previousMillis;
byte m_timerActive;
public:
MillisTimer(unsigned long timeInMilliSeconds):
m_timeInMilliSeconds(timeInMilliSeconds),
m_timerActive(0),
m_previousMillis(0){
}
bool Update(){
if(m_timerActive && (millis() - m_previousMillis >= m_timeInMilliSeconds)){
m_previousMillis += m_timeInMilliSeconds;
return 1;
}
else{
return 0;
}
}
void Start(){
m_timerActive = 1;
}
void Stop(){
m_timerActive = 0;
}
void ReStart(){
m_timerActive = 1;
m_previousMillis = millis();
}
byte IsActive(){
return m_timerActive;
}
};
// Создайте копию объекта для работы.
MillisTimer MyTimer(501);
byte inputPin = 2;
byte signalActive = 0;
void setup(){
// ПРИМЕЧАНИЕ: Если вход плавающий, требуется понижающий резистор.
pinMode(inputPin, INPUT);
MyTimer.Start();
// Индикатор состояния таймера для целей тестирования.
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop(){
if(digitalRead(inputPin) == HIGH){
signalActive = 1;
MyTimer.ReStart();
}
if(MyTimer.Update()){
signalActive = 0;
}
// Протестируйте вывод переменной "signalActive" с помощью встроенного светодиода на Uno.
if(signalActive == 1){
digitalWrite(LED_BUILTIN, HIGH);
}
else{
digitalWrite(LED_BUILTIN, LOW);
}
}
Я пытаюсь получить эту работу. Я дам вам знать., @Myles
Предполагая, что digitalRead(RTS_IN)
является входным сигналом, я бы прочитал его один раз в верхней части цикла и сохранил временную метку, если она высока, а затем использовал условие millis() - timestamp <= 500
в качестве фиксированной входной переменной.
Я бы также выполнил остальную часть ввода (т. Е. millis()) в верхней части функции, преобразовал сравнения времени из абсолютных значений в интервалы и рассмотрел возможность учета не включенного регистра из регистров коммутатора.
Непроверенный код:
// Светодиодные выходы
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;
//правый указатель поворота
int RTS_IN = A0;
//переменная состояния для операторов switch case
int stateRightTurn = 0;
//временная переменная
unsigned long t = 0;
//интервал - это интервал времени между операторами case
unsigned long interval = 100;
//время отключения кода
unsigned long off = 600;
void setup()
{
Serial.begin(9600);
//вводит
pinMode(RTS_IN, INPUT);
//вывод сигнала правого поворота из левого в правый
pinMode(LED_5, OUTPUT);
pinMode(LED_6, OUTPUT);
pinMode(LED_7, OUTPUT);
pinMode(LED_8, OUTPUT);
}
void loop()
{
StateRight();
}
//последовательные сигналы поворота
void StateRight()
{
const int latchInterval = 500; // ms
static unsigned long lastHigh = -latchInterval; // инициализировать в перенесенное прошлое
unsigned long now = millis();
int inState = digitalRead(RTS_IN);
if (inState == HIGH) { //таймер обновления
lastHigh = now;
}
bool enabled = (now - lastHigh <= latchInterval) ; // включен в течение 500 мс после выключения
switch (stateRightTurn)
{
case 0: //холостой ход
if (enabled)
{
Serial.println("0000");
t = now;
SwitchRightLedsOff();
stateRightTurn = 1;
}
break;
case 1: // Один светодиод горит
if (!enabled)
{
Serial.println("1111-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (now - t > interval)
{
Serial.println("1111-HHHHHHHH");
t = now;
digitalWrite(LED_5, HIGH);
stateRightTurn = 2;
}
break;
case 2: // Два светодиода горят
if (!enabled)
{
Serial.println("2222-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (now - t > interval)
{
Serial.println("2222-HHHHHHHH");
t = now;
digitalWrite(LED_6, HIGH);
stateRightTurn = 3;
}
break;
case 3: // Три светодиода горят
if (!enabled)
{
Serial.println("3333-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (now - t > interval)
{
Serial.println("3333-HHHHHHHH");
t = now;
digitalWrite(LED_7, HIGH);
stateRightTurn = 4;
}
break;
case 4: // Четыре светодиода горят
if (!enabled)
{
Serial.println("4444-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (now - t > interval)
{
Serial.println("4444-HHHHHHHH");
t = now;
digitalWrite(LED_8, HIGH);
stateRightTurn = 5;
}
break;
case 5: // Светодиоды не горят
if (!enabled)
{
Serial.println("5555-LOWLOWLOW");
SwitchRightLedsOff();
stateRightTurn = 0;
}
else if (now - t > interval)
{
Serial.println("55555-HHHHHHHH");
SwitchRightLedsOff();
stateRightTurn = 0;
}
break;
}
}
//способ отключения светодиодов
void SwitchRightLedsOff()
{
digitalWrite(LED_5, LOW);
digitalWrite(LED_6, LOW);
digitalWrite(LED_7, LOW);
digitalWrite(LED_8, LOW);
}
Это сработало отлично! Я тоже это понимаю. Я пытался сделать что-то с тем же мыслительным процессом, @Myles
Хитрость заключается в том, чтобы превратить ваши входные данные в полезную переменную состояния на основе таймера "ввод НИЗКИЙ в течение определенного промежутка времени", которую может использовать ваш код., @Dave X
- Почему светодиоды заметно мерцают?
- Кнопка переключения переключает между операторами обращения с разблокированием кнопки
- Как запустить 4 светодиода последовательно на основе кнопочного входа?
- Как установить таймеры, используя миллисекунды на 3 датчиках PIR?
- Схемы мигания светодиодов с несколькими светодиодами с помощью millis() без использования Delay()
- Получить подсчет производства за текущую минуту
- Как справиться с rollover millis()?
- Как получить текущее время и дату в Arduino без внешнего источника?
И каков ваш фактический вопрос? Ты ни о чем таком не спрашивал. И ваше описание мне кажется непонятным. Пожалуйста, выделите одну проблему в вашем коде, опишите только эту проблему, что произошло, когда вы попробовали ее, и что вы ожидали, что произойдет., @chrisl
@chrisl Я обновил основное описание. Дайте мне знать, если в этом будет больше смысла., @Myles
Если вы действительно собираетесь использовать это в реальном автомобиле, пожалуйста, подумайте, что должно произойти с вашими "последовательными сигналами поворота", когда аварийные огни автомобиля мигают одновременно. Что должны делать указатели поворота, если одновременно горит стоп-сигнал?, @VE7JRO
@VE7JRO У меня весь этот код работает одновременно с приведенным выше кодом. Я удалил все это и сегментировал только этот код для простоты., @Myles
Это не ваша проблема, но вы должны переместить
t
на другую сторону знака>
в выражениях, подобных этому:(millis ()> t + интервал)
, чтобы вы всегда сравнивали интервалы, а не временные метки. // Предлагаемое вами решение - это отключение или блокировка низких входных сигналов в течение 0,5 с после последнего наблюдаемого максимума., @Dave Xmillis ()-t
- это правильный способ обработки ролловера часов, если millis () и t имеют один и тот же тип, а интервал меньше значения ролловера, @Abel