Galera, seguinte, estou fazendo um projeto onde existem 6 semáforos para veículos e um para pedestres. Preciso que o código funcione alternando os leds a cada 10s conforme solicitado, essa parte esta funcionando ok. Porem eu preciso interromper esse loop, fechar todos os semáforos para veículos e abrir o de pedestres ao apertar um push button. Alem disso deve ser exibido uma contagem regressiva num display de 7 segmentos.

Meu codigo esta funcionando tudo certo, exceto a interrupção com o pushbutton. ela parece não estar executando os codigos dentro dela.

Segue o codigo: 

  #define carroAr 30 //define semaforo A vermelho

  #define carroAg 31 //define semaforo A verde

  

  #define carroBr 32 //define semaforo B vermelho

  #define carroBg 33 //define semaforo B verde

  #define carroCr 34 //define semaforo C vermelho

  #define carroCg 35 //define semaforo C verde

  

  #define carroDr 36 //define semaforo D vermelho

  #define carroDg 37 //define semaforo D verde

  #define carroEr 38 //define semaforo E vermelho

  #define carroEg 39 //define semaforo E verde

  #define carroFr 40 //define semaforo F vermelho

  #define carroFg 41 //define semaforo F verde

  #define carroGr 42 //define semaforo G vermelho

  #define carroGg 43 //define semaforo G verde

byte seven_seg_digits[10][7] = { 

{ 0,0,0,0,0,0,1 },  // = 0                                    

{ 1,0,0,1,1,1,1 },  // = 1                                    

{ 0,0,1,0,0,1,0 },  // = 2                                    

{ 0,0,0,0,1,1,0 },  // = 3                                    

{ 1,0,0,1,1,0,0 },  // = 4                                    

{ 0,1,0,0,1,0,0},   // = 5                                    

{ 0,1,0,0,0,0,0 },  // = 6                                    

{ 1,1,1,0,0,0,0 },  // = 7                                    

{ 1,1,1,1,1,1,1 },  // = 8                                    

{ 1,1,1,0,0,1,1 },  // = 9 

};

  

  int botao = 2;

void sevenSegWrite(byte digit) {     

  byte pin = 2;     

  for (byte segCount = 0; segCount < 7; ++segCount) {        

    digitalWrite(pin, seven_seg_digits[digit][segCount]);        

    ++pin;         

    } }

  

  

  

  void setup()  {  

   

     int i=0;

     attachInterrupt(0,interrupcao,RISING);

pinMode(3, OUTPUT); //Pino 3 do Arduino ligado ao segmento A       

pinMode(4, OUTPUT); //Pino 4 do Arduino ligado ao segmento B     

pinMode(5, OUTPUT); //Pino 5 do Arduino ligado ao segmento C     

pinMode(6, OUTPUT); //Pino 6 do Arduino ligado ao segmento D     

pinMode(7, OUTPUT); //Pino 7 do Arduino ligado ao segmento E     

pinMode(8, OUTPUT); //Pino 8 do Arduino ligado ao segmento F     

pinMode(9, OUTPUT); //Pino 9 do Arduino ligado ao segmento G     

pinMode(10, OUTPUT); //Pino 10 do Arduino ligado ao segmento PONTO     

     

     

      pinMode (carroAr, OUTPUT);

      pinMode (carroAg, OUTPUT);

      

      pinMode (carroBr, OUTPUT);

      pinMode (carroBg, OUTPUT);

          

      pinMode (carroCr, OUTPUT);

      pinMode (carroCg, OUTPUT);

      pinMode (carroDr, OUTPUT);

      pinMode (carroDg, OUTPUT);

      pinMode (carroEr, OUTPUT);

      pinMode (carroFg, OUTPUT);

      pinMode (carroFr, OUTPUT);

      pinMode (carroFg, OUTPUT);

      pinMode (carroGr, OUTPUT);

      pinMode (carroGg, OUTPUT);

  

    pinMode(botao, INPUT); //Configura o pino 2 como entrada    

  

    int verde[6] = {31, 33, 35, 37, 41, 43};

    int vermelho[6] = {30, 32, 34, 36, 40, 42};

  //seta os leds verdes apagados e vermelhos acesos.

  for (i=0; i<8; i++){

    digitalWrite(vermelho[i], HIGH);

    digitalWrite(verde[i], LOW);

  }}

  

  void interrupcao(){ //Função executada quando ocorre a interrupção externa

    int verde[6] = {31, 33, 35, 37, 41, 43};

    int vermelho[6] = {30, 32, 34, 36, 40, 42};

    

  //apaga todos os verdes e acende os vermelhos

   for(int i=0; i<7; i++){

      digitalWrite(vermelho[i], HIGH);

      digitalWrite(verde[i], LOW);}

      delay(500);

   

     digitalWrite(carroEr, LOW); //apaga o vermelho

      digitalWrite(carroEg, HIGH); //acende o verde

//ONDE ENTRA CODIGO DO DISPLAY

for (byte count = 10; count > 0; --count) {

  delay(1000);

  sevenSegWrite(count - 1);

}

     

    digitalWrite(carroEr, HIGH); //acende o vermelho

    digitalWrite(carroEg, LOW);  //apaga o verde

    delay(500);

    

  }

  

  

  void loop() {

 

    int verde[6] = {31, 33, 35, 37, 41, 43};

    int vermelho[6] = {30, 32, 34, 36, 40, 42};

  

  digitalWrite(verde[3], HIGH);//ligado direto 

  digitalWrite(vermelho[3], LOW);

  //CASO A

  digitalWrite(vermelho[1], HIGH);

  digitalWrite(verde[0], HIGH);

  digitalWrite(verde[2], HIGH);

  digitalWrite(verde[6], HIGH);

  digitalWrite(verde[5], HIGH);

  digitalWrite(vermelho[0], LOW);

  digitalWrite(vermelho[2], LOW);

  digitalWrite(vermelho[6], LOW);

  digitalWrite(vermelho[5], LOW);

  delay(10000);  

  //Pisca LED Vermelho     

  for(int i=15 ; i>0 ; i--) 

  {    

  digitalWrite(vermelho[0], !(digitalRead(vermelho[0])));

  delay(i*50); 

  //Aguarda 500 milissegundos    

  }  

  

  //CASO B

  digitalWrite(vermelho[0], HIGH);

  digitalWrite(verde[0], LOW);

  digitalWrite(vermelho[2], LOW);

  digitalWrite(verde[2], HIGH);

  delay(10000);

//Pisca LED Vermelho     

  for(int i=15 ; i>0 ; i--) 

  {    

  digitalWrite(vermelho[2], !(digitalRead(vermelho[2])));

  delay(i*50); 

  //Aguarda 500 milissegundos    

  }  

  

  //Caso C

  digitalWrite(verde[2], LOW);

  digitalWrite(vermelho[2], HIGH);

  digitalWrite(verde[1], HIGH);

  digitalWrite(vermelho[1], LOW);

    delay(10000);

    

//Pisca LED Vermelho     

  for(int i=15 ; i>0 ; i--) 

  {    

  digitalWrite(vermelho[5], !(digitalRead(vermelho[5])));

  delay(i*50); 

  //Aguarda 500 milissegundos    

  }  

    

 //CASO D

  digitalWrite(vermelho[5], HIGH);

 digitalWrite(verde[5], LOW);

   delay(10000);

//Pisca LED Vermelho     

  for(int i=15 ; i>0 ; i--) 

  {    

  digitalWrite(vermelho[1], !(digitalRead(vermelho[1])));

  digitalWrite(vermelho[6], !(digitalRead(vermelho[6])));

  delay(i*50);   //Aguarda 500 milissegundos    

  }  

   

 //CASO E

  digitalWrite(verde[1], LOW);

  digitalWrite(verde[6], LOW);

  digitalWrite(verde[2], HIGH);

  digitalWrite(vermelho[1], HIGH);

  digitalWrite(vermelho[6], HIGH);

   digitalWrite(vermelho[2], LOW);

     delay(10000);

    

  

  

  }

  

  

  

    

Exibições: 552

Responder esta

Respostas a este tópico

Olá.

  De cara vejo que vc usou delay dentro de uma interrupçao.

  Isso não deve funcionar (nunca testei). Acontece que todas as outras interrupções ficam comprometidas quando vc está dentro de uma. Se vc demora dentro de uma interrupção por ex os contadores de tempo que são incrementados por interrupção podem parar. Não posso dizer que param, mas não é assim que se faz.

  Minha sugestão para seu projeto seria:

1) Interrupção: Seta uma variável que indica que foi solicitada a passagem de pedestres e retorna imediatamente.

2) Loop principal no estilo máquina de estados.

Estado 1 = Verde de um lado e vermelho de outro. Pedestre vermelho Aguarda um tempo 10x

Estado 2 = Amarelo de um lado e vermelho do outro. Pedestre Vermelho Aguarda x2 tempo 1x

Se flag de botao nao pressionado pula pro estado 4.

Estado 3 = Vermelho de um lado e vermelho do outro. Pedestre Verde.Aguarda x3 tempo. 3x

Estado 4 = Vermelho de um lado e verde do outro. Pedestres vermelhos. Aguarda um tempo 10x

Estado 5 = Vermelho de um lado e amarelo do outro. Aguarda 1x

Se flag de botao nao pressionado pula pro estado 7.

Estado 6 = Vermelho de um lado e vermelho do outro. Pedestre verde.

Estado 7= .... Pedestre vermelho.

E assim vai.

Esses estados ficam bem num case. 

Em vez de fazer o delay dentro do case ficaria mais polido programar um contador decrescente. A cada loop ele tira um. Quando chega a zero ele repete o case, que reprograma conforme o valor que deve esperar.

Boa ideia, temos assim pelo menos 4 caminhos:

1) Uma tripona (linguiçona) com acende led e apaga led, delay e tal, como é hj.

2) Uma variável que indica o estado e um case, que conforme o valor dessa variável escolhe qual grupo de acendeled e apagaled acionar.

Vide:

https://www.arduino.cc/en/Reference/SwitchCase

3) Uma lógica para cada led, equacionada partindo dos bits de uma contador de estado, devidamente otimizada por mapas de karnaugh.

Vide:

https://pt.wikipedia.org/wiki/Mapa_de_Karnaugh

4) Outro caminho, que seria fazer uma matriz. As maquinas de lavar antigas que tinham um botão que girava lentamente para trocar de operação são uma forma de entender esse metodo. Outro são as caixas de musica, mas esse é muito corriqueiro, melhor pensar nas maquinas de lavar.

Vc teria uma matriz onde as linhas são os estados ou mesmo o numero de segundos. As colunas são as saídas. 

Zeros e uns nas colunas acionam os leds correspondentes.

Vide:

https://www.arduino.cc/en/Reference/Array

Acredito que não seja uma competição por melhor método, então faça do jeito que ficar melhor na sua opinião. 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço