Go Down

Topic: Primeiro projeto, semáforo ; Arduino Uno (Read 956 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy