Go Down

Topic: Primeiro projeto, semáforo ; Arduino Uno (Read 465 times) previous topic - next topic

CanJacs

Oct 13, 2014, 02:16 am Last Edit: Oct 15, 2014, 01:57 pm by CanJacs Reason: 1
Estou com extrema dificuldade em fazer um simples semáforo... basicamente é um sinal de trânsito rodando em looping, ai eu queria colocar um botão para quando a luz dos pedestres for vermelha ou quando a luz do semáforo B ser verde esse botão gerar outro laço para fazer os pedestres andarem ...

Porém, eu já tem tentei "while" (ele para o looping  e fica esperando eu apertar o botão OU faz o laço a mais que queria colocar ficar rodando sem parar -não sei se é problema no botão ,físico ). Já tentei também o "if" , mas tenho que colocar um ponto para ser testado e também não dá muito certo...

Enfim, alguém sabe algum comando que faça o arduino esperar pelo apertar de botão  por um determinado tempo e ao mesmo tempo fazer o laço principal rodar mesmo se o botão não for apertado?

entenderam? To traumatizado, huauhauhauhauhauhauhauhahua

meu código semi feito... não está completo, tenho até outras 5 tentativas também...


Code: [Select]

int vermelho=13;
int amarelo=12;
int verde=11;
int vermelho2=10;
int amarelo2=9;
int verde2=8;
int vermelhopedestre=7;
int verdepedestre=6;
int botao=2;
unsigned long tempoderecarga;
void setup(){
pinMode(vermelho,OUTPUT);
pinMode(amarelo,OUTPUT);
pinMode(verde,OUTPUT);
pinMode(vermelho2,OUTPUT);
pinMode(amarelo2,OUTPUT);
pinMode(verde2,OUTPUT);
pinMode(vermelhopedestre,OUTPUT);
pinMode(verdepedestre,OUTPUT);
pinMode(botao,INPUT);
 
}

void semafaroA(){ //o semafaro A fica vermelho nesse ciclo

//while (true) {
//   if (digitalRead(botao) == true) {
//     pedidopedestre();
 //    break;
//   } //else semafaroA();
//  }
 delay(19900); //tempo obrigatorio considerando o tempo do outro semafaro igual a 59 segundos 59/3=19,900

digitalWrite(verde2,LOW);
digitalWrite(amarelo2,HIGH);
delay(10000);
digitalWrite(amarelo2,LOW);
digitalWrite(vermelho2,HIGH);
piscarapido();//sinal dos pedestres piscando
digitalWrite(verdepedestre,HIGH);
digitalWrite(vermelho,LOW);
digitalWrite(verde,HIGH);
delay(59700); //obrigatoria verde liberado por 43, tempo que escolhi fazendo o calculo aproximado do tempo total

semafaroB();
}
void semafaroB(){ //o semafaro B fica vermelho nesse cilo
 digitalWrite(verde,LOW);
 digitalWrite(amarelo,HIGH);
 delay(7000);
 piscarapido();
 digitalWrite(amarelo,LOW);
 digitalWrite(vermelho2,LOW);
 
}

void piscarapido(){ //sinal do pedestre pisca rapido 3 vezes idem obrigatório do texte
//istoconsome 3 segundos para ser executado
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);

}

void pedidopedestre(){
 piscarapido();
 piscarapido();
 piscarapido();
 piscarapido();
 piscarapido();
 
}

void loop(){
digitalWrite(vermelho,HIGH);
digitalWrite(verde2,HIGH);
digitalWrite(vermelhopedestre,HIGH);
 delay(1000);
 int j = digitalRead(botao);
 delay(1000);
 int x=digitalRead(botao);

 
 /*verifica se o botao foi pressionado e se faz mais de 5 seg desde a ultima vez*/
while(true){ if (j == HIGH && x==HIGH ) {
   
   delay(1000);
   pedidopedestre();
   break;

}
else{semafaroA();}

}

semafaroA();
}

andre162

Pelo que eu entendi você quer adquirir uma variavel do pedestre para modificar o semafaro em qualquer estagio, isso?

Priorize o variavel do pedestre e verefique todas as outras variaveis antes de rodar a do pedestre.

Sendo que se, o pedestre apertar o botão e mudar a variavel para HIGH ele terá que esperar o ciclo do semafaro completar, para depois deixar todos os semafaros vermelhos e ligar as luzes de pedestres no verde.

Quando o ciclo do pedestre acabar tera que setar a variavel pedestre em LOW e começar o loop novamente.

Osias Neto

Acho que sua lógica de fluxo deveria ser um pouco diferente, por exemplo em vez de delay usar a função millis() e checar o botão a cada ciclo (procura nos exemplos, blink without delay).

Acho que deveria ser tipo:
Checa botão -> checa timer -> botão pressionado? S:seta variavel. -> timer atingido? S:(variavel setada? N: proxima cor, S:vai para semaforo de pedestres) -> volta ao inicio.

Entenda que checa botao e checa timer devem rodar a cada clock do uControlador, por isso é importante não usar a função delay. Durante a rotina do semaforo de pedestres pode ter delay normal

CanJacs

#3
Oct 13, 2014, 04:36 pm Last Edit: Oct 15, 2014, 01:58 pm by CanJacs Reason: 1
Consegui! Agora de manhã na minha 7 tentativa huauhauhauhauhahua

eu coloquei uma função testar se o botão está ligado ... dei delays e vários testes do mesmo e funcionou! ^^

código final do sinal de trânsito, tudo funcionando corretamente  =(
Code: [Select]

int vermelho=13;
int amarelo=12;
int verde=11;
int vermelho2=10;
int amarelo2=9;
int verde2=8;
int vermelhopedestre=7;
int verdepedestre=6;
int botao=2;
unsigned long tempoderecarga;
void setup(){
pinMode(vermelho,OUTPUT);
pinMode(amarelo,OUTPUT);
pinMode(verde,OUTPUT);
pinMode(vermelho2,OUTPUT);
pinMode(amarelo2,OUTPUT);
pinMode(verde2,OUTPUT);
pinMode(vermelhopedestre,OUTPUT);
pinMode(verdepedestre,OUTPUT);
pinMode(botao,INPUT);
 
}

void semafaroA(){ //o semafaro A fica vermelho nesse ciclo

//while (true) {
//   if (digitalRead(botao) == true) {
//     pedidopedestre();
 //    break;
//   } //else semafaroA();
//  }
//  delay(19900); //tempo obrigatorio considerando o tempo do outro semafaro igual a 59 segundos 59/3=19,900 ;OBS: retirei esse delay e coloquei lá no loop, inicio do programa.

digitalWrite(verde2,LOW);
digitalWrite(amarelo2,HIGH);
delay(10000);
digitalWrite(amarelo2,LOW);
digitalWrite(vermelho2,HIGH);
piscarapido();//sinal dos pedestres piscando
digitalWrite(verdepedestre,HIGH);
digitalWrite(vermelho,LOW);
digitalWrite(verde,HIGH);

delay(59700); //obrigatoria verde liberado por 43, tempo que escolhi fazendo o calculo aproximado do tempo total

semafaroB();
}
void semafaroB(){ //o semafaro B fica vermelho nesse cilo
 digitalWrite(verde,LOW);
 digitalWrite(amarelo,HIGH);
 delay(7000);
 piscarapido();
 digitalWrite(amarelo,LOW);
 digitalWrite(vermelho2,LOW);
 
}

void piscarapido(){ //sinal do pedestre pisca rapido 3 vezes idem obrigatório do texte
//istoconsome 3 segundos para ser executado
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);

}

void pedidopedestre(){
 
piscarapido(); // anunciando que o pedido foi feito, mas ainda não liberando a passagem dos pedestres
digitalWrite(vermelhopedestre,HIGH);
 digitalWrite(verde2,LOW);
 delay(500);
 digitalWrite(verde2,HIGH);
 delay(500);
 digitalWrite(verde2,LOW);
 delay(500);
 digitalWrite(verde2,HIGH);
 delay(500);
 digitalWrite(verde2,LOW);
 delay(500);
 digitalWrite(verde2,HIGH);
 delay(500);
 digitalWrite(verde2,LOW);
 digitalWrite(amarelo2,HIGH);
delay(10000);
digitalWrite(amarelo2,LOW);
digitalWrite(vermelho2,HIGH);
delay(2000); //regra de passagem pedido no exercício entre vermelho e verde
digitalWrite(vermelho,LOW);
digitalWrite(verde,HIGH);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,HIGH);
delay(59700);
 
 
 digitalWrite(verde,LOW);
 digitalWrite(amarelo,HIGH);
 piscarapido();
 digitalWrite(vermelhopedestre,HIGH); //estado inicial do loop ..teoricamente não necessário, mas coloquei aqui.
 delay(7000);
 digitalWrite(amarelo,LOW);
 digitalWrite(vermelho,HIGH); //estado inical do loop
 delay(2000);
 digitalWrite(vermelho2,LOW);
 digitalWrite(verde2,HIGH); //Estado inicial do loop

 
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
void verificadorbotao(){

 while (true) {
   if (digitalRead(botao) == true) {
     pedidopedestre();
     break;
   } else {break;}
 
}

 
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
void loop(){
digitalWrite(vermelho,HIGH);
digitalWrite(verde2,HIGH);
digitalWrite(vermelhopedestre,HIGH);
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//verificando se o botão foi pressionado... enquanto isso as luzes do inicio do loop estão ligadas
//e necessario ficar apertando no mínimo 2 segundos para detectar se o botão foi apertado, depois disso ele vai para funcao pendidopedestre
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
verificadorbotao();
delay(2000);
delay(1900);
//esses delays acumulam 19,900 que é o tempo do verde de um dos semafaros

//$$$$$$$$$$$$$$$$$$$$$$$$
semafaroA();
}

CanJacs

Obrigado pelas respostas, vou procurar outras formas também de fazer, assim que me recuperar do trauma huahuauhauhauh


:smiley-sweat:

CanJacs

#5
Oct 15, 2014, 01:52 pm Last Edit: Oct 15, 2014, 01:54 pm by CanJacs Reason: 1
Fazendo um pequeno UP no tópico...
segundo um professor esse "Break" que usei não poderia , pois isso "quebra  lógica", para min se existe esse comando no programa deveria ser usando uhauhauhahua em fim ...

uma forma de contornar esse problema de vários teste é fazer um comando "for" e dentro dele colocar "if" de verificação, ficou assim:

int soma;
for(soma=0;soma<=100;soma++){
delay(199);
if (digitalRead(botao)==1){soma=101;  pedidopedestre(); }
if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
}
isso substituiu todas essa linhas aqui abaixo:
Code: [Select]

delay(2000);
verificadorbotao();
verificadorbotao2;
delay(2000);
verificadorbotao();
verificadorbotao2();
delay(2000);
verificadorbotao();
verificadorbotao2;
delay(2000);
verificadorbotao();
verificadorbotao2();
delay(2000);
verificadorbotao();
verificadorbotao2();
delay(2000);
verificadorbotao();
verificadorbotao2();
delay(2000);
verificadorbotao();
verificadorbotao2();
delay(2000);
verificadorbotao2();
verificadorbotao();
delay(2000);
verificadorbotao2();
verificadorbotao();
delay(1900);

Além dessa os períodos que tinha delays maiores de 2s eu substitui por períodos "for" e dentro "if". Isso garantiu que a qualquer momento do programa eu possa pará-lo  no momento que quero que o botao 2 funcione e também o periodo que o botao1 funcione.

Code: [Select]

int vermelho=13;
int amarelo=12;
int verde=11;
int vermelho2=10;
int amarelo2=9;
int verde2=8;
int vermelhopedestre=7;
int verdepedestre=6;
int botao=2;
int botao2=3; //botao de parada durante os sinais vermelho e verde ao mesmo tempo,ou seja, nos períodos longos.
unsigned long tempoderecarga;
void setup(){
pinMode(vermelho,OUTPUT);
pinMode(amarelo,OUTPUT);
pinMode(verde,OUTPUT);
pinMode(vermelho2,OUTPUT);
pinMode(amarelo2,OUTPUT);
pinMode(verde2,OUTPUT);
pinMode(vermelhopedestre,OUTPUT);
pinMode(verdepedestre,OUTPUT);
pinMode(botao,INPUT);
pinMode(botao2,INPUT);  
}

void semafaroA(){ //o semafaro A fica vermelho nesse ciclo


//  delay(19900); //tempo obrigatorio considerando o tempo do outro semafaro igual a 59 segundos 59/3=19,900 ;OBS: retirei esse delay e coloquei lá no loop, inicio do programa.

digitalWrite(verde2,LOW);
digitalWrite(amarelo2,HIGH);
//aqui existira um delay de 10s , mas substitui por uma verificação de 10s
//verificacao10s();
int soma;
for(soma=0;soma<=100;soma++){
delay(100);
if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
}

digitalWrite(amarelo2,LOW);
digitalWrite(vermelho2,HIGH);
piscarapido();//sinal dos pedestres piscando
digitalWrite(verdepedestre,HIGH);
digitalWrite(vermelho,LOW);
digitalWrite(verde,HIGH);

//delay de 59,7s abaixo; //obrigatoria verde liberado por 43, tempo que escolhi fazendo o calculo aproximado do tempo total; coloquei aproximadamente 60s de verificação para substituir logo abaixo
for(soma=0;soma<=597;soma++){
delay(100);
if (digitalRead(botao2)==1){soma=598; foradeoperacao();}
}

}
void semafaroB(){ //o semaforo B fica vermelho nesse cilo
 digitalWrite(verde,LOW);
 digitalWrite(amarelo,HIGH);
   int soma;
   for(soma=0;soma<=70;soma++){
 delay(100);
 if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
 }
 piscarapido();
 digitalWrite(amarelo,LOW);
 digitalWrite(vermelho2,LOW);
 
}

void piscarapido(){ //sinal do pedestre pisca rapido 3 vezes item obrigatório do teste
//isto consome 3 segundos para ser executado
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,HIGH);
delay (500);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,LOW);
delay(500);

}

void pedidopedestre(){
 
piscarapido(); // anunciando que o pedido foi feito, mas ainda não liberando a passagem dos pedestres
digitalWrite(vermelhopedestre,HIGH);
 digitalWrite(verde2,LOW);
 delay(500);
 digitalWrite(verde2,HIGH);
 delay(500);
 digitalWrite(verde2,LOW);
 delay(500);
 digitalWrite(verde2,HIGH);
 delay(500);
 digitalWrite(verde2,LOW);
 delay(500);
 digitalWrite(verde2,HIGH);
 delay(500);
 digitalWrite(verde2,LOW);
 digitalWrite(amarelo2,HIGH);
//abaixo um delay de 10s
int soma;
for(soma=0;soma<=100;soma++){
delay(100);
if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
}

digitalWrite(amarelo2,LOW);
digitalWrite(vermelho2,HIGH);
delay(2000); //regra de passagem pedido no exercício entre vermelho e verde
digitalWrite(vermelho,LOW);
digitalWrite(verde,HIGH);
digitalWrite(vermelhopedestre,LOW);
digitalWrite(verdepedestre,HIGH);
//abaixo um delay "for" de 59,700s;
 for(soma=0;soma<=597;soma++){
delay(100);
if (digitalRead(botao2)==1){soma=598; foradeoperacao();}
}
 
 
 digitalWrite(verde,LOW);
 digitalWrite(amarelo,HIGH);
 piscarapido();
 //espera de 7s abaixo
 digitalWrite(vermelhopedestre,HIGH); //estado inicial do loop ..teoricamente não necessário, mas coloquei aqui
 for(soma=0;soma<=70;soma++){
 delay(100);
 if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
 }
 digitalWrite(amarelo,LOW);
 digitalWrite(vermelho,HIGH); //estado inical do loop
 delay(2000);
 digitalWrite(vermelho2,LOW);
 digitalWrite(verde2,HIGH); //Estado inicial do loop

 
}

void foradeoperacao(){
 digitalWrite(vermelho,LOW);
 digitalWrite(amarelo,LOW);
 digitalWrite(verde,LOW);
 digitalWrite(vermelho2,LOW);
 digitalWrite(amarelo2,LOW);
 digitalWrite(verde2,LOW);
 digitalWrite(vermelhopedestre,LOW);
 digitalWrite(verdepedestre,LOW);
 delay(60);
 
 digitalWrite(amarelo,HIGH);
 digitalWrite(amarelo2,HIGH);
 digitalWrite(vermelhopedestre,HIGH);
 digitalWrite(verdepedestre,HIGH);
 delay(500);
   digitalWrite(amarelo,LOW);
 digitalWrite(amarelo2,LOW);
 digitalWrite(vermelhopedestre,LOW);
 digitalWrite(verdepedestre,LOW);
 delay(500);
if (digitalRead(botao2)==0){ foradeoperacao();}
else{delay(5000);
digitalWrite(vermelho,HIGH);
digitalWrite(verde2,HIGH);
digitalWrite(vermelhopedestre,HIGH);
int soma;
for(soma=0;soma<=100;soma++){
delay(199);
if (digitalRead(botao)==1){soma=101;  pedidopedestre(); }
if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
}
semafaroA();}
}

void loop(){
 
 //estado inicial de todo o loop, para evitar problemas de troca, o loop inicial marca todas as variaveis possíveis
digitalWrite(verde,LOW);
digitalWrite(vermelho,HIGH);
digitalWrite(amarelo,LOW);
digitalWrite(verde2,HIGH);
digitalWrite(amarelo2,LOW);
digitalWrite(vermelho2,LOW);
digitalWrite(vermelhopedestre,HIGH);
digitalWrite(verdepedestre,LOW);
//abaixo verifica se o botão UM ou DOIS estão ligados e de acordo manda o código para respectiva funcao; no total esse "for" tem 19,90s só que está quebrado em tempos de 0,199s em 100 partes
int soma;
for(soma=0;soma<=100;soma++){
delay(199);
if (digitalRead(botao)==1){soma=101;  pedidopedestre(); }
if (digitalRead(botao2)==1){soma=101; foradeoperacao();}
}
//esses delays acumulam 19,900 que é o tempo do verde de um dos semafaros
semafaroA();
}





Encontrei um erro no código, mas é de tempos de acendimento do semáforo , note também que escrevi semáforo errado hehehe mas também vou corrigir mais tarde ^^ Eu estava errando escrever if por confundi os estados iniciais... portanto o código também ficava rodando direito quando eu não queria... além dos botões físicos dar problema e eu ter que apertar e tentar fazer ele voltar a funcionar normalmente ...enfim, traumas ^^ obrigado pelas dicas de novo ^^

HugoPT

#6
Oct 15, 2014, 03:18 pm Last Edit: Oct 15, 2014, 03:22 pm by HugoPT Reason: 1
Em regra usar delays é má pratica de programaçao por tanto o teu programa apesar de te parecer funcionar a meu ver nao esta correcto e foge há boa pratica de programaçao.
Em resumo imagina que a funçao delay nao existe , e tenta refazer o teu programa.Todo o teu programa esta baseado em delays e assumes que toda a operaçao do semaforo esta num seguimento temporal inalteravel.Isto nao é verdade num semaforo!
Por exemplo tens a funçao piscarapido() que deve demorar cerca de 3 segundos como dizes mas e se alguem tocar num dos botoes?
Obviamente o teu programa nao contempla isso e vais perder esse pedido no botao.Entao isso quer dizer que o operador desse semaforo tem de tentar advinhar e ir carregando a espera de ter sorte em nao cair em nenhum desses delays ....
A chave para fazeres o teu programa bem esta nas seguintes pesquisas:
Blink without delay
Interrupts
Code: [Select]

for(soma=0;soma<=597;soma++){
delay(100);
if (digitalRead(botao2)==1){soma=598; foradeoperacao();}
}

}

Eu sou um gajo do contra, portanto e se eu carregar so no botao que referes nesta funçao(pinMode(botao,INPUT);  e nao no teu botao2?
Fico a tentar advinhar o que raio o semaforo anda a fazer, ou considero o que esta avariado e aventuro-me a atravessar de qualquer das formas?
Bons estudos
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

Go Up