setMode режимы управления две ветви по void loop()

pickuper220
Offline
Зарегистрирован: 09.07.2015
Здравствуйте, господа
 
Предлагаю разобрать следующую программу "Светофор"
 
Суть программы. 
Работать по двум режимам "auto и manual"
Авто - светофор работает сам по себе переключая интервалы по заданию. Режим задается di1
Ручной - пешеход нажимает на кнопку и светофор перекрывает движение транспорта. кнопка di2
 
Сами по себе алгоритмы режимов рабочие, если поместить их в void loop(){}
Но в setMode (){} работать не хотят.
 
Идея в том, что бы void loop() выбирал режимы, а работа шла по setMode()
пример рабочего проекта (упрощенного) на 58й странице тут
 
 
int di1 = 3;
int di2 = 5;
 
//тут можно установить длительность стопа для машин
//в режиме с кнопкой
int delay1manRed = 15000;
//зеленый машинам (стоп людям)
int delay2autGreen = 10000;
//красный машинам (зеленый людям)
int delay3autRed = 10000;
 
int mode2 = 0;
 
int do1red = 11;
int do2yel = 10;
int do3green = 9;
 
void setup(){
  pinMode(di1, INPUT);
  pinMode(di2, INPUT);
  pinMode(do1red, OUTPUT);
  pinMode(do2yel, OUTPUT);
  pinMode(do3green, OUTPUT);
}
 
void setMode (int mode){
  if(mode == 1)
  {
    digitalWrite(do3green, HIGH);
    delay(delay2autGreen);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(1000);
    digitalWrite(do2yel, HIGH);
    delay(2000);
    digitalWrite(do2yel, LOW);
    digitalWrite(do1red, HIGH);
    delay(delay3autRed);
    digitalWrite(do2yel, HIGH);
    delay(2000);
    digitalWrite(do1red, LOW);
    digitalWrite(do2yel, LOW);
    digitalWrite(do3green, HIGH);
  }
  else if(mode == 0)
  {
   digitalWrite(do3green, HIGH);
   int nazal1 = digitalRead(di2);
   if(nazal1 == HIGH)
   {
    delay(5);
    nazal1 = HIGH;
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(800);
    digitalWrite(do3green, HIGH);
    delay(800);
    digitalWrite(do3green, LOW);
    delay(1000);
    digitalWrite(do2yel, HIGH);
    delay(2000);
    digitalWrite(do2yel, LOW);
    digitalWrite(do1red, HIGH);
    delay(delay1manRed);
    digitalWrite(do2yel, HIGH);
    delay(2000);
    digitalWrite(do1red, LOW);
    digitalWrite(do2yel, LOW);
    digitalWrite(do3green, HIGH);
    }
  }
}
 
void loop(){
   int nazal2 = digitalRead(di1);
   if(nazal2 == HIGH)
   {
    delay(5);
    
   }
   if(mode2 == 3)
   {
    mode2 = 0;
    setMode(mode2);
   }
 }
Клапауций 911
Offline
Зарегистрирован: 18.10.2015

pickuper220 пишет:
Идея в том, что бы void loop() выбирал режимы, а работа шла по setMode()

идея, что в дуино всё есть void loop() , ещё не посетила голову изомбретателя?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А чего тут разбирать?

В начале написано 

int mode2 = 0;

а в loop() стоит проверка

 if(mode2 == 3)

и если верно, то вызывается setMode

Вопрос к ТС на засыпку: Когда, где, при каких обстоятельствах и с какого перепугу mode2 вдруг станет равным 3?

Ответ: никогда, нигде, ни при каких и ни с какого - она всегда будет нулём.

Стало быть setMode не вызывается никогда.

Клапауций 911
Offline
Зарегистрирован: 18.10.2015

ЕвгенийП пишет:

Ответ: никогда, нигде, ни при каких и ни с какого - она всегда будет нулём.

ТС хочет, что бы луп творил магию.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Кстати, вот эта конструкция:

mode2 = 0;
setMode(mode2);
 
тоже весьма глубокомысленная. Правда толку от неё негусто, так как она никогда не срабатывает, но сама по себе - очень достойная вещь!
bwn
Offline
Зарегистрирован: 25.08.2014

А еще половина кода состоящая из delay(), тоже супер.
Нескоро пешеход сумеет нажать кнопку.)))) Как водитель, приветствую такую реализацию светофора))))

saftik
Offline
Зарегистрирован: 08.04.2015

я конечно не большой специалист но мне кажеться что код вообще говеный .  

и как сказал уважаемый bwn с таким количеством delay () "Нескоро пешеход сумеет нажать кнопку"

я бы сделал как то так . еще можно кнопку пешехода поставить на int 0 прерывание (pin 2) и использовать interrupt
 

#define RED_LED     13
#define YELLOW_LED  12
#define GREEN_LED   11
#define STOP_BTN    10   // кнопка для пешехода
#define AUTO_MANUAL  9   // тумблер выбара режимов
 void setup() {
  pinMode(RED_LED,     OUTPUT);
  pinMode(YELLOW_LED,  OUTPUT);
  pinMode(GREEN_LED,   OUTPUT);
  pinMode(STOP_BTN,    INPUT_PULLUP);  // кнопка подтянута к " + " при нажатии замыкать на ноль
  pinMode(AUTO_MANUAL, INPUT_PULLUP);

}

 void loop() {
  if (digitalRead(AUTO_MANUAL)==HIGH) {
     avto();
     }
  else {
     manual();
   }
 } 
 void avto () {
   
     ______________________ ;          // (ваш код) работа в автоматическом режиме
 }
   
 void manual(){
     ______________________ ;          // (ваш код) работа в ручном режиме
  
   if (digitalRead(STOP_BTN)==LOW) {   // если пешеход нажал кнопку
     ______________________ ; }        // (ваш код) 
 
 }

 

saftik
Offline
Зарегистрирован: 08.04.2015

вот хорошая статья почитайте.

http://robotosha.ru/arduino/multi-tasking-arduino.html

а еще пины не обязательно обьявлять как INT можно их просто #define ("дефайнить ")
http://alxarduino.blogspot.com/2013/08/delay.html

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Светофор - обычный конечный автомат. Вешать кнопку на прерывание - как на счёт дребезга? Сколько раз возникнет прерывание? Это скорее костыли, нежели решение проблемы.

saftik
Offline
Зарегистрирован: 08.04.2015

вы правы, но я сразу сказал что я не спец )) можно конечно дребезг убрать на железном уровне но проще без прерываний
 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Если даёте советы, то говорить, что Вы не спец звучит, как минимум странно. Это не значит, что любой человек не может давать советы.
Либо советуйте, либо молчите, либо не удивляйтесь и не оправдывайтесь.
Иначе получается, что я щас скажу, что я не спец, обложу всех херами и обижусь, если кто то мне ответит не так, как я хочу.
В гугле море информации, в том числе про дребезг и прерывания. Потому я тут как КЭП ответил.
Я всего лишь попытался поправить, потому что форум читают люди, которые в этом нифига не понимают и мой ответ был больше для них.
Ничего личного