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

Тема в разделе "Arduino & Shields", создана пользователем Dozbot, 7 апр 2016.

  1. Dozbot

    Dozbot Нуб

    Да совершенно верно))))))
     
  2. Dozbot

    Dozbot Нуб

    Код (C++):
    int sensorPin = 9;
    int greenLed = 8;
    int yellowLed = 7;
    int redLed = 6;
    unsigned long timer;
    bool inWork;
    uint8_t curStep;
    unsigned long lastMillis;

    void setup()
    {
    timer = 0;
    inWork = false;
    curStep = 0;
    lastMillis = millis();
    pinMode(sensorPin, INPUT);
    pinMode(greenLed, OUTPUT);
    pinMode(yellowLed, OUTPUT);
    pinMode(redLed, OUTPUT);
    }

    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;
    case 2: // горит жёлтый
                    // если горит дольше двух минут - тушим, иначе - пусть горит
                 if(timer > 1*60000) { digitalWrite(redLed,LOW); curStep = 3; timer = 0;} else { digitalWrite(redLed,HIGH); }      
            break;
    // другие условия обрабатываем
         }
      }
    }
    Вот собственно что есть, теперь не могу понять, почему как код программы завершил последнее действие, он повторно перестает реагировать на кнопку.
     
  3. ostrov

    ostrov Гуру

    Блин, как вычурно написан код то. Задача то на один опрос датчика, три переключения светодиодов и три делея. Ничего же больше не происходит в теле, зачем таймер запускать, к тому же самодельный?
     
  4. Dozbot

    Dozbot Нуб

    Что же тогда исправить что бы было нормально?
     
  5. Dozbot

    Dozbot Нуб

    Код (C++):
    delay(1000*10);
    В таком формате????
     
  6. ostrov

    ostrov Гуру

    Вот код ниже вставить в луп. Идея такая: горит красный пока не сработает датчик. Датчик сработал, загорелся зеленый на 5 минут, потом желтый на 2 минуты, потом красный до очередной сработки датчика. Если логика нужна другая, следует поправить по шаблону.

    Код не компилировал, возможно есть опечатки.

    Код (C++):
    digitalWrite(redLed,HIGH);
    digitalWrite(yellowLed,LOW);
    digitalWrite(greenLed,LOW);

    while(!digitalRead(sensorPin));

    digitalWrite(greenLed,HIGH);
    delay(300000);
    digitalWrite(greenLed,LOW);
    digitalWrite(yellowLed,HIGH);
    delay(120000);
     
  7. Dozbot

    Dozbot Нуб

    Спасибо, а как можно менять временной интервал , например кнопкой? Точнее как это в коде выглядит?
     
  8. ostrov

    ostrov Гуру

    Опять же смотря когда, если в процессе работы, то надо добавлять ее опрос постоянно. Если до, то отдельную процедуру для выбора. лучше с обратной связью. Легче всего потенциометром, длительность задержки в делеях вычислять по формуле от полученного значения с потенциометра. Но это опять же до запуска светофора, потому что пока работает делей, МК ничего не видит и не слышит. Если, конечно, прерывания не задействовать, но наверное так усложнять ни к чему.
     
  9. Dozbot

    Dozbot Нуб

    Да лучше конечно до запуска, ибо в процессе работы уже как то не очень смотрится.
     
  10. ostrov

    ostrov Гуру

    Вот дешево и сердито. Как подключить подсмотреть здесь.

    Добавить пин на потенциометр, обозвать например delayPin. В сетапе поставить что то вроде:
    Код (C++):
    delayGreen = map(0,1024,6000,60000,analogRead(delayPin);
    delayYellow = map(0,1024,1000,10000,analogRead(delayPin);
    Соответственно в лупе заменить числа в делеях на переменные delayGreen и delayYellow. Не забыть их предварительно объявить, например как int.
     
    Последнее редактирование: 13 апр 2016
  11. Dozbot

    Dozbot Нуб

    Код (C++):
    int sensorPin = 9;
    int greenLed = 8;
    int yellowLed = 7;
    int redLed = 6;
    int delayPin = 5;
    int delayGreen, delayYellow;
    void setup()
    {
    pinMode(delayPin, INPUT);
    pinMode(sensorPin, INPUT);
    pinMode(greenLed, OUTPUT);
    pinMode(yellowLed, OUTPUT);
    pinMode(redLed, OUTPUT);
    delayGreen = map(0,1024,6000,60000,analogRead(delayPin));
    delayYellow = map(0,1024,1000,10000,analogRead(delayPin));
    }

    void loop()
    {
    digitalWrite(redLed,HIGH);
    digitalWrite(yellowLed,LOW);
    digitalWrite(greenLed,LOW);

    while(!digitalRead(sensorPin));

    digitalWrite(greenLed,HIGH);
    delay(delayGreen);
    digitalWrite(greenLed,LOW);
    digitalWrite(yellowLed,HIGH);
    delay(delayYellow);
    }
    Еще раз огромное спасибо.
     
    Последнее редактирование: 13 апр 2016
  12. Dozbot

    Dozbot Нуб

    Код (C++):
    //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к(Думаю не в сопротивлении же дело).
     
  13. ostrov

    ostrov Гуру

    Это что такое? Как оно по вашему работает?
    Код (C++):
    while(!digitalRead(distance_sm<15));
     
  14. ostrov

    ostrov Гуру

    И главное, проверьте правильность подключения всех компонентов!

    Код (C++):
    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;
    }
     
  15. Dozbot

    Dozbot Нуб

    Еще раз огромное спасибо))) Все работает, у меня еще последний вопрос, если допустим мне нужно будет узнать через serial сколько, я накрутил времени, предполагаю , что что то, на что надо делить?
     
  16. ostrov

    ostrov Гуру

    В переменных delayGreen и delayYellow содержатся значения задержек в миллисекундах, их и смотрите. Кстати, масштаб изменений от крутилки можно менять двумя последними цифрами в каждом преобразовании map().
     
  17. Dozbot

    Dozbot Нуб

    Хорошо я вас понял) Спасибо)