10 de julho de 2020

Semáforo com botão para pedestre

Como realmente funciona o botão de pedestre nos semáforos e como fazer funcionar sem utilizar a função delay no projeto.


Existem algumas lógicas que podem ser aplicadas aos semáforos com botão para o pedestre e, as mais comuns são:
  • Sinal verde para veículos possui o tempo programado para determinados horários e, quando o botão de pedestre é pressionado, o tempo é reduzido.
  • Sinal verde para veículos sempre ativo até que o botão de pedestre seja pressionado.
Na primeira lógica, a redução do tempo do sinal verde para os veículos também pode ser variável de acordo com o horário.

Alguns outros pontos da lógica dos semáforos:
  • Como para os pedestres não existe o sinal amarelo, o sinal vermelho permanece piscando por alguns segundos, sinalizando que o tempo do sinal verde dos pedestres está próximo do fim.
  • Ao ser acionado o sinal vermelho para os veículos, existe um tempo de segurança antes que o sinal verde para os pedestres seja ativado.
No projeto, temos dois potenciômetros para controlar os tempos dos sinais verde e vermelho dos veículos. Cada um podendo estar entre 15 e 90 segundos.

Ao ser pressionado o botão de pedestre, o tempo do sinal verde para veículos é reduzido pela metade.
Exemplo para o sinal verde com 60 segundos:
- Ao completar 10 segundos e o botão for pressionado, permanecerá em verde até completar 30 segundos.
- Com 40 segundos e o botão for pressionado, como metade do tempo já foi ultrapassado, imediatamente o sinal amarelo será habilitado.

Não foi necessário utilizar a função delay() pois a biblioteca MillisTimerLib faz o controle dos tempos do semáforo.

Segue o esquema elétrico e o código fonte:


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*---------------------------------------------------------
  Programa : SEMÁFORO COM BOTÃO PARA PEDESTRE
  Autor    : Fellipe Couto [ http://www.efeitonerd.com.br ]
  Data     : 10/07/2020
  ---------------------------------------------------------*/
#include <MillisTimerLib.h> //https://github.com/fellipecouto/MillisTimerLib [ http://www.efeitonerd.com.br ]

#define POT_GREEN A0 //Potenciômetro para controlar o tempo do sinal verde para carros
#define POT_RED   A1 //Potenciômetro para controlar o tempo do sinal vermelho para carros

MillisTimerLib timer1(500);      //Inicializa timer1 com 500ms
const int ledCar[3] = {3, 4, 5}; //Pinos semáforo carro
const int ledPed[2] = {6, 7};    //Pinos semáforo pedestre
const int btn = 8;               //Pino botão
const int yellowTime = 4;        //Tempo do sinal amarelo (segundos)
const int alertPedTime = 5;      //Tempo do sinal vermelho do pedreste em alerta (segundos)
int control = 1;                 //Controle do semaforo: 1=Verde 2=Amarelo 3=Vermelho seguro 4=Vermelho 5=Alerta pedestre
int count = 0;                   //Contador para controle de tempo do semaforo
bool btnPressed = false;         //Controle do botão de pedestre

void setup() {
  //Configura os pinos do semáforo e do botão
  for (int i = 0; i < 3; i++) {
    pinMode(ledCar[i], OUTPUT);
    if (i < 2) pinMode(ledPed[i], OUTPUT);
  }
  pinMode(btn, INPUT_PULLUP);
}

void loop() {
  int greenTime = map(analogRead(POT_GREEN), 0, 1023, 15, 90); //Tempo do sinal verde. De 15 a 90 segundos
  int redTime = map(analogRead(POT_RED), 0, 1023, 15, 90);     //Tempo do sinal vermelho. De 15 a 90 segundos

  if (timer1.timer()) {
    switch (control) {
      case 1:
        greenCar();
        break;
      case 2:
        yellowCar();
        break;
      case 3:
        redCarSafety();
        break;
      case 4:
        redCar();
        break;
      case 5:
        alertPed();
        break;
    }

    count++;
    if ((control == 1 && count == greenTime * 2) || (control == 1 && count >= greenTime) && btnPressed) {
      control = 2;
      count = 0;
      btnPressed = false;
    } else if (control == 2 && count == yellowTime * 2) {
      control = 3;
      count = 0;
    } else if (control == 3 && count == 2) {
      control = 4;
      count = 0;
    } else if (control == 4 && count == (redTime * 2) - (alertPedTime * 2)) {
      control = 5;
      count = 0;
    } else if (control == 5 && count == (alertPedTime * 2) + 1) {
      control = 1;
      count = 0;
    }
  }

  if (control == 1 && digitalRead(btn) == LOW) {
    btnPressed = true;
  }
}

void greenCar() {
  digitalWrite(ledCar[0], HIGH); //Verde carro
  digitalWrite(ledCar[1], LOW);  //Amarelo carro
  digitalWrite(ledCar[2], LOW);  //Vermelho carro
  digitalWrite(ledPed[0], LOW);  //Verde pedestre
  digitalWrite(ledPed[1], HIGH); //Vermelho pedestre
}

void yellowCar() {
  digitalWrite(ledCar[0], LOW);  //Verde carro
  digitalWrite(ledCar[1], HIGH); //Amarelo carro
  digitalWrite(ledCar[2], LOW);  //Vermelho carro
  digitalWrite(ledPed[0], LOW);  //Verde pedestre
  digitalWrite(ledPed[1], HIGH); //Vermelho pedestre
}

void redCarSafety() {
  digitalWrite(ledCar[0], LOW);  //Verde carro
  digitalWrite(ledCar[1], LOW);  //Amarelo carro
  digitalWrite(ledCar[2], HIGH); //Vermelho carro
  digitalWrite(ledPed[0], LOW);  //Verde pedestre
  digitalWrite(ledPed[1], HIGH); //Vermelho pedestre
}

void redCar() {
  digitalWrite(ledCar[0], LOW);  //Verde carro
  digitalWrite(ledCar[1], LOW);  //Amarelo carro
  digitalWrite(ledCar[2], HIGH); //Vermelho carro
  digitalWrite(ledPed[0], HIGH); //Verde pedestre
  digitalWrite(ledPed[1], LOW);  //Vermelho pedestre
}

void alertPed() {
  digitalWrite(ledPed[0], LOW); //Verde pedestre
  digitalWrite(ledPed[1], !digitalRead(ledPed[1])); //Vermelho pedestre
}

Um comentário: