Система освещения светофора с датчиками
Я пытаюсь создать систему светофора с ультразвуковым датчиком дальности, а также светозависимым резистором. Я пытаюсь сделать так, чтобы по умолчанию было 2 секунды красного света, 1 секунда желтого, 2 секунды зеленого, затем 1 секунда желтого, затем это будет повторяться до тех пор, пока не произойдет что - то еще-у меня все работает нормально.
Тогда я хочу 2 разных состояния.
Тот, где, если что-то поставляется с датчиком 10 см, то раздастся звуковой сигнал, и желтый индикатор должен мигать 10 раз с интервалом 0,1 мс. Когда объект удаляется, он должен вернуться к настройкам по умолчанию.
Во-вторых, я хочу, чтобы, когда LDR обнаружит, что индикатор упал ниже определенного уровня, красный индикатор включится и будет гореть до тех пор, пока объект не приблизится к датчику. Когда объект находится рядом с датчиком, он должен затем выключить красный свет и включить зеленый свет.
Вот весь код, который у меня есть до сих пор, и я не могу понять, почему он не работает. Любая помощь будет признательна Спасибо
#define ECHOPIN 3
#define TRIGPIN 2
float distance;
long distancecm;
int RED = 13;
int YELLOW = 12;
int GREEN = 11;
int piezoPin = 8;
int sensorpin = A0;
int sensorvalue = 0;
void setup() {
pinMode(RED, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(GREEN, OUTPUT);
Serial.begin(9600);
pinMode(ECHOPIN, INPUT);
pinMode(TRIGPIN, OUTPUT);
}
void distancesensor()
{
digitalWrite(TRIGPIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGPIN,HIGH);
delayMicroseconds(10);
digitalWrite(TRIGPIN,LOW);
distance = pulseIn(ECHOPIN, HIGH);
distancecm = distance/29.1/2;
if (distancecm <=10);
for (int j=1; j<=5; j=j+1)
{
tone(piezoPin, 1, 500);
digitalWrite(YELLOW, HIGH);
delay(100);
break;
}
}
void lightsensor()
{
sensorvalue = analogRead(sensorpin);
if (sensorvalue > 500)
digitalWrite(RED,HIGH);
digitalWrite(TRIGPIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGPIN,HIGH);
delayMicroseconds(10);
digitalWrite(TRIGPIN,LOW);
distance = pulseIn(ECHOPIN, HIGH);
distance = distance/58;
while (distance >10)
digitalWrite(RED,LOW);
digitalWrite(GREEN,HIGH);
digitalWrite(TRIGPIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGPIN,HIGH);
delayMicroseconds(10);
digitalWrite(TRIGPIN,LOW);
distance = pulseIn(ECHOPIN, HIGH);
distance = distance/58;
}
void loop() {
distancesensor;
lightsensor;
digitalWrite(RED, HIGH); //RED ON
delay(2000); //WAIT 2 SECONDS
digitalWrite(RED, LOW); //RED OFF
delay(200);
distancesensor;
lightsensor;
digitalWrite(YELLOW, HIGH); //YELLOW ON
delay(1000); //WAIT 1 SECOND
digitalWrite(YELLOW, LOW); //YELLOW OFF
delay(200);
distancesensor;
lightsensor;
digitalWrite(GREEN, HIGH); //GREEN ON
delay(2000); //WAIT 2 SECONDS
digitalWrite(GREEN, LOW); //GREEN OFF
delay(200);
distancesensor;
lightsensor;
digitalWrite(YELLOW, HIGH); //YELLOW ON
delay(1000); //WAIT 1 SECOND
digitalWrite(YELLOW, LOW); //YELLOW OFF
delay(200);
distancesensor;
lightsensor;
//REPEAT
}
@M Aves, 👍-1
Обсуждение1 ответ
Фотография вашей схемы на самом деле не показывает, как подключены все компоненты. Для этого вам следует либо нарисовать схему (что вы можете сделать с помощью инструмента "Схема" непосредственно в редакторе вопросов), либо предоставить хорошую видимую схему подключения, как при фритцевании (хотя правильная схема была бы лучше).
На данный момент я не вижу никакой неправильной проводки, хотя вам определенно следует перепроверить ее и добавить правильную схему к вашему вопросу.
Для вашего кода я вкратце опишу функциональность неблокирующего кода и конечного автомата:
- Неблокирующий код: Задача, требующая много времени (это означает много времени для микроконтоллера; в данном контексте секунды-это много), вы не должны использовать код, который блокирует выполнение всей программы, пока задача не будет завершена. Вместо этого вы должны только в ближайшее время проверить, есть ли какие-либо действия, которые необходимо предпринять. Если нет, быстро перейдите к другому коду. Это позволяет вам выполнять, что, по-видимому, является многозадачностью. Для временных последовательностей вы можете использовать функцию
millis ()
. Он возвращает количество миллисекунд с момента запуска программы и переполняется через 50 дней. Следующий код сохраняет метку времени, когда светодиод был включен в последний раз, и проверяет, прошло ли достаточно миллисекунд с момента последнего включения. Таким образом, вы можете сделать что-то еще в то же время (например, проверить состояние ваших датчиков). Также обратитесь кпримеру BlinkWithoutDelay для Arduino IDE.
unsigned long timestamp = 0;
unsigned long interval = 500;
...
void loop(){
if(millis() - timestamp > interval){
digitalWrite(led_pin, !digitalRead(led_pin));
timestamp = millis();
}
}
- Конечный автомат: Конечный автомат (State Machine) - это код, который содержит текущее состояние в переменной, в основном числовой. Эта переменная считывается при каждом цикле цикла и используется для определения того, какой фрагмент кода должен быть выполнен. В вашем случае у вас будут состояния "красный свет включен", "желтый свет включен", "зеленый свет включен", "расстояние менее 10 см" и "LDR сообщает о состоянии низкой освещенности". Каждый из них получает свой собственный номер. Для удобства вы должны использовать перечисление. Теперь на каждом цикле цикла мы используем переключатель, чтобы перейти к нужному коду в зависимости от состояния. В вашем случае вы бы установили код состояния с неблокирующим поведением, как описано выше. Тогда вам нужны только переходы между состояниями, задав переменную состояния.
enum STATE {STATE1, STATE2, STATE3};
STATE state = STATE1;
...
void loop(){
switch(state){
case STATE1:
digitalWrite(led1_pin, HIGH);
if(millis() - timestamp > interval){
digitalWrite(led1_pin, LOW);
state = STATE2;
}
break;
case STATE2:
// doing whatever this state needs to do and then do transition with setting state variable
break;
case STATE3:
// doing whatever this state needs to do and then do transition with setting state variable
}
}
Для проектирования состояний и переходов иногда имеет смысл набросать их на бумаге. Пузырь с именами-это состояние, а затем вы соединяете эти состояния стрелками.
Поскольку вы хотите проверить датчики в каждом состоянии, вам следует сделать это вне инструкции switch. Затем функции измерения не делают ничего другого, кроме измерения и соответствующей настройки переменной
состояния
(поэтому там нет digitalWrite()
или задержки ()
).
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Как это не работает? Опишите проблему дальше? Разве он не реагирует на ваши датчики? Вы получаете ошибку компиляции?, @chrisl
Старайтесь не использовать задержку для других вещей, кроме действительно простого тестового кода. Вместо этого используйте неблокирующий код, как в примере BlinkWithoutDelay IDE Arduino. И такого рода проект я бы запрограммировал как конечный автомат, что также упростило бы работу при использовании неблокирующего кода, @chrisl
именно этот вопрос задавался раньше, и я думаю, что это была другая операция, которая говорит мне, что это может быть школьное задание. ... это школьное задание? ... вы написали код?, @jsotola
Крисл, проблема в том, что датчики, похоже, ни на что не реагируют. я не получаю никаких ошибок компиляции., @M Aves
jsotola тогда я посмотрю. спасибо, это универ-проект, и да, я сам написал весь код., @M Aves
Кингдукен, я не понимаю, что ты имеешь в виду?, @M Aves
Вполне вероятно, что схема не реагирует, потому что код занят ожиданием в функции задержки. У вас есть задержка до 2,8 с между измерениями. Покажите нам вашу схему/проводку, чтобы мы могли проверить, что задержки действительно являются проблемой, @chrisl
Крис Айв обновил пост картинкой того, как выглядит проводка., @M Aves