Светофор для LEGO

dozbot
dozbot аватар
Offline
Зарегистрирован: 12.01.2013

Вечер добрый уважаемые, на днях созрела идея сделать светофор для детского док конструктора Лего.

Суть примитивная, в док заезжает машина , замыкается контакт(или ИК датчик), от 10мин до 5 горит зеленый свет, с 5мин до 3 желтый свет, с 3мин до 0 мигает желтый, далее красный. Как только контакт разомкнулся ,светофор в доке выключился и включился светофор который за доком на въезд(принцип тот же). еще хотелось бы внедрить самостоятельную установку времени с кнопки или патенциометра. Заранее огромное спасибо. Без светофоров как то, детям уныло играется))))))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015
unsigned long timer;
bool inWork;
uint8_t curStep;
unsigned long lastMillis;

void setup()
{
timer = 0;
inWork = false;
curStep = 0;
lastMillis = millis();
}

void loop()
{
  unsigned long curMillis = millis();
  uint16_t dt = curMillis - lastMillis;
 lastMillis = curMillis;

 if(digitalRead(sensorPin) == HIGH) // если сенсор сработал
   inWork = true; // выставляем флаг работы

  if(inWork) // если флаг выставлен
  {
     timer += dt; // обновляем таймер
     switch(curStep)
     {
         case 0: // горит зелёный
                 // если горит дольше пяти минут, то тушим, иначе - пусть горит
             if(timer > 5*60000) { digitalWrite(greenLed,LOW); curStep = 1; timer = 0;} else { digitalWrite(greenLed,HIGH); }
         break;

        case 1: // горит жёлтый
                // если горит дольше двух минут - тушим, иначе - пусть горит
             if(timer > 2*60000) { digitalWrite(yellowLed,LOW); curStep = 2; timer = 0;} else { digitalWrite(yellowLed,HIGH); }        
        break;

 // другие условия обрабатываем
     }
  }
}

Ничо не проверял, тупо в лоб, с миганием разобраться несложно. Код плохой, не надо в порт каждый раз писать, привёл чисто для стартового вброса.

Green
Offline
Зарегистрирован: 01.10.2015

Мальцу своему когда-то делал. И с большим 7-сегментным индикатором даже.))

dozbot
dozbot аватар
Offline
Зарегистрирован: 12.01.2013

Спасибо огромное, +10 для вашей кармы))))

dozbot
dozbot аватар
Offline
Зарегистрирован: 12.01.2013

А не подскажите еще, можно ли как то кнопкой, или потенциометром  менять временной интервал? (+/-) по минутно.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

dozbot пишет:

А не подскажите еще, можно ли как то кнопкой, или потенциометром  менять временной интервал? (+/-) по минутно.

Можно. На форуме есть тема "Класс титановый велосипед для кнопки" - берёте оттуда этот класс, впиливаете его в проект, потом пишете что-то подобное (псевдокод):

uint16_t redWorkInterval; // интервал работы красного
uint16_t intervalStep; // на сколько меняем за одно нажатие

button bt; // наша кнопка

void setup()
{
 redWorkInterval = 300; // 300 секунд 
 intervalStep = 60;
}

void loop()
{
  if(bt.clicked)
  {
     redWorkInterval += intervalStep; // увеличили интервал
  }
}

Ну а дальше - зависит от алгоритма работы - можно сделать, чтобы интервал был кольцевым, т.е. при достижении максимального значения сбрасывался на минимальное и наоборот, можно - по длинному нажатию на кнопку делать одно, по короткому - другое - тут уж как фантазия подскажет.

dozbot
dozbot аватар
Offline
Зарегистрирован: 12.01.2013
//int sensorPin = 1;
const int Trig = 8;
const int Echo = 9;
int greenLed = 4;
int yellowLed = 7;
int redLed = 6;
int delayGr = A0;
int delayYe = A1;
int delayGreen, delayYellow;
void setup()
{
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
//pinMode(delayPin, INPUT);
//pinMode(sensorPin, INPUT);
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(redLed, OUTPUT);
delayGreen = map(0,1024,6000,60000,analogRead(delayGr));
delayYellow = map(0,1024,1000,10000,analogRead(delayYe));
}
unsigned int time_us=0;
unsigned int distance_sm=0;
void loop()
{
digitalWrite(Trig, HIGH); // Подаем сигнал на выход микроконтроллера
delayMicroseconds(10); // Удерживаем 10 микросекунд
digitalWrite(Trig, LOW); // Затем убираем
time_us=pulseIn(Echo, HIGH); // Замеряем длину импульса
distance_sm=time_us/58; // Пересчитываем в сантиметры
digitalWrite(redLed,LOW);
digitalWrite(yellowLed,LOW);
digitalWrite(greenLed,LOW);

while(!digitalRead(distance_sm<15));

digitalWrite(greenLed,HIGH);
delay(delayGreen);
digitalWrite(greenLed,LOW);
digitalWrite(yellowLed,HIGH);
delay(delayYellow);
digitalWrite(greenLed,HIGH);
digitalWrite(yellowLed,LOW);
}

Получилось сие кодоводство. Проблемы вылезли : запуск( сразу же горит зеленый, не какой реакции на уз сенсор), далее тухнет , зажигается желтый. И продолжает гореть без изменений. Потенциометр рабочий, на 500к(Думаю не в сопротивлении же дело).

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Прокомментируйте, плз, тот бред, что написан в строке 35 - что, по вашему, он должен делать? И что - делает на самом деле. Предлагаю поразмыслить, почему сразу загорается зелёный, если в функцию digitalRead вместо номера пина вы передаёте булево значение - либо true, либо false? Тогда как функция ждёт совсем другое. По сути, при таком раскладе - вы пытаетесь читать из пина с номером либо 0, либо 1.

Включите в настройках вывод сообщений компилятора - он вам покажет, что почём ;)

dozbot
dozbot аватар
Offline
Зарегистрирован: 12.01.2013

Извеняюсь за вышеизложеное кодоводство. Можно в новом коде, поправить выбор интервала ,с потенциометра ,на кнопки, и вывить все значения интервала в монитор порт? Заранее спасибо

const int Trig = 8;
const int Echo = 9;
int greenLed = 4;
int yellowLed = 7;
int redLed = 6;
int delayGr = A0;
int delayYe = A1;
int delayGreen, delayYellow;

void setup() {
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  delayGreen = map(analogRead(delayGr), 0, 1024, 6000, 60000);
  delayYellow = map(analogRead(delayYe), 0, 1024, 1000, 10000);
}

void loop() {
  digitalWrite(redLed, HIGH);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, LOW);
  while (getDistance(Trig, Echo) > 15);
  digitalWrite(greenLed, HIGH);
  digitalWrite(redLed, LOW);
  delay(delayGreen);
  digitalWrite(greenLed, LOW);
  digitalWrite(yellowLed, HIGH);
  delay(delayYellow);
}

unsigned int getDistance(byte trig, byte ping) {
  unsigned int duration = 0;
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(ping, HIGH);
  int Distance = duration / 58;
  return Distance;
}
 

 

dozbot
dozbot аватар
Offline
Зарегистрирован: 12.01.2013

Спасибо за помощь, разобрался))))))))))