/*
progama feito pelo Gabriel Nacimento Luz
este projeto foi feito para controlar o acesso ao um estacionamento
de 6 vagas com indicação luminosa em cada uma
sendo 3 vagas podendo ser especiais ou não
a tela lcd serve para indicar a quantidade de vagas
os servos sevem para dar o controle da cancela de entrada e saida
tem 6 botões que simulam sensores de presença nas vagas para indicar
se estão sendo usadas ou não
tem 2 botões que controlam a cancela de entrada e saida
exite um multiplexador de 4 entradas e 16 saidas que servem para o controle de cada led
ultilizado, sendo 15 leds controlados separadamente
os leds são RGB para melhor controle
*/
// bibliotecas ultilizadas
#include <LiquidCrystal_I2C.h> // para funcionamento do LCD usando Comunicação I2C
#include <ESP32Servo.h> // para funcionamento do motor servo
#include <Wire.h> //para funcionamento da comunicação I2C
// definição de portas ultilizadas do ESP32
#define SV1 23
#define SV2 4
#define SV3 16
#define SV4 17
#define SV5 5
#define SV6 18
#define B1 2
#define B2 19
#define RGB_S0 27
#define RGB_S1 26
#define RGB_S2 25
#define RGB_S3 33
#define EN 14
#define sig 32
#define pot 34
// definição dos servos
Servo servoMotor_in;
Servo servoMotor_out;
//definição dos pinos dos servos
const int servo_in = 13;
const int servo_out = 12;
//matriz para escolha de portas do multiplexador
int8_t rgb_set[16]{
0b00000000,// porta 0
0b00000001,// porta 1
0b00000010,// porta 2
0b00000011,// porta 3
0b00000100,// porta 4
0b00000101,// porta 5
0b00000110,// porta 6
0b00000111,// porta 7
0b00001000,// porta 8
0b00001001,// porta 9
0b00001010,// porta 10
0b00001011,// porta 11
0b00001100,// porta 12
0b00001101,// porta 13
0b00001110,// porta 14
0b00001111 // porta 15
};
//caracteres personalizados:
//Caractere personalizado 1
byte ct1[] = {
B00011, // ..
B00111, // ...
B01110, // ...
B11100, //...
B11000, //..
B11000, //..
B11000, //..
B11000 //..
};
//Caractere personalizado 2
byte ct2[] = {
B11000, //..
B11000, //..
B11000, //..
B11000, //..
B11100, //...
B01110, // ...
B00111, // ...
B00011 // ..
};
//Caractere personalizado 3
byte ct3[] = {
B11001, //.. .
B11110, //....
B00111, // ...
B00000, //
B00000, //
B00000, //
B00000, //
B00000 //
};
//Caractere personalizado 4
byte ct4[] = {
B00000, //
B11111, //.....
B11111, //.....
B00011, // ..
B00011, // ..
B00111, // ...
B11110, //....
B11001 //.. .
};
//Caractere personalizado 5
byte ct5[] = {
B11110, //....
B00010, // .
B00010, // .
B00010, // .
B00010, // .
B00010, // .
B00010, // .
B00010 // .
};
//Caractere personalizado 6
byte ct6[] = {
B00010, // .
B00010, // .
B00010, // .
B00011, // ..
B00000, //
B00000, //
B00000, //
B11111 //.....
};
//Caractere personalizado 7
byte ct7[] = {
B00000, //
B00000, //
B00000, //
B11111, //.....
B00001, // .
B00001, // .
B00001, // .
B11111 //.....
};
byte ct8[] = {
B01111, //
B10000, //
B10111, //
B10111, //
B10111, //
B10111, //
B10000, //
B01111 //
};
byte ct9[] = {
B11111, //
B00000, //
B00000, //
B00000, //
B00000, //
B00000, //
B00000, //
B11111 //
};
byte ct10[] = {
B11111, //
B00000, //
B11111, //
B11111, //
B11111, //
B11111, //
B00000, //
B11111 //
};
byte ct11[] = {
B11110, //
B00001, //
B00001, //
B00001, //
B00001, //
B00001, //
B00001, //
B11110 //
};
byte ct12[] = {
B11110, //
B00001, //
B11101, //
B11101, //
B11101, //
B11101, //
B00001, //
B11110 //
};
//
//definição do LCD e seu Endereço do I2C
LiquidCrystal_I2C LCD((0x27), 20, 4);
//declarações das variaveis do tipo inteiro
int teste = 0; //usado para selecionar portas do multiplexador
int vsp = 0; //usado para selecionar quantidades de vagas especiais
int tempo = 0; // usado para contar voltas no loop
int vaga_ocup = 0; //usado para indicar vagas normais ocupadas
int vaga_livre = 0; //usado para indicar vagas normais livres
int vaga_esp_ocup = 0; //usado para indicar vagas especiais ocupadas
int vaga_esp_livre = 0; //usado para indicar vagas especiais livres
int servo1 = 90; //usado para controlar o servo da cancela de entrada
int servo2 = 90; //usado para controlar o servo da cancela de saida
//
//declarações das variaveis do tipo boolean
bool ss1 = 0; //usado para verificar status do botão (sensor de presença)
bool ss2 = 0; //usado para verificar status do botão (sensor de presença)
bool ss3 = 0; //usado para verificar status do botão (sensor de presença)
bool ss4 = 0; //usado para verificar status do botão (sensor de presença)
bool ss5 = 0; //usado para verificar status do botão (sensor de presença)
bool ss6 = 0; //usado para verificar status do botão (sensor de presença)
bool b1 = 0; //usado para verificar status do botão da cancela de entrada
bool b2 = 0; //usado para verificar status do botão da cancela de entrada
//
void setup() {
servoMotor_in.attach(servo_in); //definição do servo de entrada
servoMotor_out.attach(servo_out); //definição do servo de saida
Serial.begin(115200); //definição da comunicação serial
//Apresentação inicial
LCD.init(); //inicia o LCd
LCD.backlight(); //liga a luz de fundo do LCD
LCD.createChar(0, ct1); // define o caractere 1 personalizado como 0
LCD.createChar(1, ct2); // define o caractere 2 personalizado como 1
LCD.createChar(2, ct3); // define o caractere 3 personalizado como 2
LCD.createChar(3, ct4); // define o caractere 4 personalizado como 3
LCD.createChar(4, ct5); // define o caractere 5 personalizado como 4
LCD.createChar(5, ct6); // define o caractere 6 personalizado como 5
LCD.createChar(6, ct7); // define o caractere 7 personalizado como 6
LCD.createChar(7, ct8); // define o caractere 8 personalizado como 7
LCD.setCursor(1,1); // direciona o texto no LCD para a posição coluna 1 linha 1
LCD.write(0); //escreve o caractere personalizado no LCD
LCD.write(2); //escreve o caractere personalizado no LCD
LCD.write(4); //escreve o caractere personalizado no LCD
LCD.setCursor(1,2); // direciona o texto no LCD para a posição coluna 1 linha 2
LCD.write(1); //escreve o caractere personalizado no LCD
LCD.write(3); //escreve o caractere personalizado no LCD
LCD.write(5); //escreve o caractere personalizado no LCD
LCD.write(6); //escreve o caractere personalizado no LCD
delay(5);
LCD.setCursor(11,1); // direciona o texto no LCD para a posição coluna 11 linha 1
LCD.print("By"); //escreve o texto no LCD
delay(5);
LCD.setCursor(7,2); // direciona o texto no LCD para a posição coluna 7 linha 2
LCD.print("Gabriel Luz"); //escreve o texto no LCD
delay(1500);
LCD.clear();
LCD.createChar(8, ct9); // define o caractere 9 personalizado como 8
LCD.createChar(9, ct10); // define o caractere 10 personalizado como 9
LCD.createChar(10, ct11); // define o caractere 11 personalizado como 10
LCD.createChar(11, ct12); // define o caractere 12 personalizado como 11
LCD.setCursor(0,0); // direciona o texto no LCD para a posição coluna 0 linha 0
LCD.print("SENAI 3AT"); //escreve o texto no LCD
LCD.setCursor(0,1); // direciona o texto no LCD para a posição coluna 0 linha 1
LCD.print("PROF: REBECA"); //escreve o texto no LCD
LCD.setCursor(0,3); // direciona o texto no LCD para a posição coluna 0 linha 3
LCD.write(7); //escreve o caractere personalizado no LCD
for(teste = 0; teste < 18; teste++){
LCD.write(8); //escreve o caractere personalizado no LCD
}
LCD.write(10); //escreve o caractere personalizado no LCD
teste = 0;
delay(500);
LCD.setCursor(0,3); // direciona o texto no LCD para a posição coluna 1 linha 3
LCD.write(7); //escreve o caractere personalizado no LCD
LCD.setCursor(0,2); // direciona o texto no LCD para a posição coluna 0 linha 2
LCD.print(0); //escreve o texto no LCD
LCD.print("% "); //escreve o texto no LCD
LCD.setCursor(1,3); // direciona o texto no LCD para a posição coluna 1 linha 3
for(teste = 1; teste < 20; teste++){
LCD.write(9); //escreve o caractere personalizado no LCD
delay(100);
int testeteste = map(teste, 1, 19, 0, 100);
LCD.setCursor(0,2); // direciona o texto no LCD para a posição coluna 9 linha 2
LCD.print(testeteste); //escreve o texto no LCD
LCD.print("% "); //escreve o texto no LCD
if(teste == 10){
delay(1500);
LCD.setCursor(0,1); // direciona o texto no LCD para a posição coluna 0 linha 1
LCD.print("PROF:THIAGO FRANSONI"); //escreve o texto no LCD
}
LCD.setCursor(teste,3); // direciona o texto no LCD para a posição coluna x linha 3
if(teste == 18)delay(1500);
}
LCD.setCursor(19,3); // direciona o texto no LCD para a posição coluna x linha 3
LCD.write(11); //escreve o caractere personalizado no LCD
teste = 0;
//
delay(500);
pinMode(SV1, INPUT); //define o pino como entrada
pinMode(SV2, INPUT); //define o pino como entrada
pinMode(SV3, INPUT); //define o pino como entrada
pinMode(SV4, INPUT); //define o pino como entrada
pinMode(SV5, INPUT); //define o pino como entrada
pinMode(SV6, INPUT); //define o pino como entrada
pinMode(B1, INPUT); //define o pino como entrada
pinMode(B2, INPUT); //define o pino como entrada
pinMode(EN, OUTPUT); //define o pino como Saida
pinMode(RGB_S0, OUTPUT); //define o pino como Saida
pinMode(RGB_S2, OUTPUT); //define o pino como Saida
pinMode(RGB_S3, OUTPUT); //define o pino como Saida
pinMode(RGB_S1, OUTPUT); //define o pino como Saida
pinMode(sig, OUTPUT); //define o pino como Saida
LCD.clear(); //limpa o texto no LCD
LCD.setCursor(0,0); // direciona o texto no LCD para a posição coluna 0 linha 0
LCD.print(" Vagas "); //escreve o texto no LCD
LCD.setCursor(0,1); // direciona o texto no LCD para a posição coluna 0 linha 1
LCD.print(" Normal | Especial "); //escreve o texto no LCD
LCD.setCursor(0,2); // direciona o texto no LCD para a posição coluna 0 linha 2
LCD.print("Livre: 0"); //escreve o texto no LCD
LCD.setCursor(0,3); // direciona o texto no LCD para a posição coluna 0 linha 3
LCD.print("Ocup.: 0"); //escreve o texto no LCD
LCD.setCursor(9,2); // direciona o texto no LCD para a posição coluna 9 linha 2
LCD.print("| Livre: 0"); //escreve o texto no LCD
LCD.setCursor(9,3); // direciona o texto no LCD para a posição coluna 9 linha 3
LCD.print("| Ocup.: 0"); //escreve o texto no LCD
delay(110);
}
void loop() {
// faz a leitura do ponteciomentro e converte o valor para o intervalo de 0 a 3
vsp = map(analogRead(pot), 0, 3500, 0, 3);
delay(5);
digitalWrite(sig, 0); //desliga o pino sig
digitalWrite(EN, 0); //desliga o pino EN
vaga1(); //chama o void vaga1
vaga2(); //chama o void vaga2
vaga3(); //chama o void vaga3
vaga4(); //chama o void vaga4
vaga5(); //chama o void vaga5
vaga6(); //chama o void vaga6
if(teste == 10)Cancela(); //se teste for igual a 10, chama o void cancela
if(tempo >= 100){ //se tempo for igual a 100 executa os seguintes comando.
tempo = 0; //define tempo igual 0
if(vsp == 0){ //se não tiver vaga especial
vaga_esp_ocup = 0; // vaga especial ocupada igual a 0
vaga_ocup = ss1 + ss2 + ss3 + ss4 + ss5 + ss6; //conta as vagas normais ocupadas
vaga_livre = 6 - vaga_ocup; //define quantas vagas normais estão livre
}
if(vsp == 1){ //se tiver 1 vaga especial
vaga_esp_ocup = ss1; // conta as vagas especiais ocupadas
vaga_ocup = ss2 + ss3 + ss4 + ss5 + ss6; //conta as vagas normais ocupadas
vaga_livre = 5 - vaga_ocup; //define quantas vagas normais estão livre
}
if(vsp == 2){ //se tiver 2 vagas especiais
vaga_esp_ocup = ss1 + ss2; // conta as vagas especiais ocupadas
vaga_ocup = ss3 + ss4 + ss5 + ss6; //conta as vagas normais ocupadas
vaga_livre = 4 - vaga_ocup; //define quantas vagas normais estão livre
}
if(vsp == 3){ //se tiver 3 vagas especiais
vaga_esp_ocup = ss1 + ss2 + ss3; // conta as vagas especiais ocupadas
vaga_ocup = ss4 + ss5 + ss6; //conta as vagas normais ocupadas
vaga_livre = 3 - vaga_ocup; //define quantas vagas normais estão livre
}
vaga_esp_livre = vsp - vaga_esp_ocup; //define quantas vagas especiais estão livre
LCD.setCursor(7,2); // direciona o texto no LCD para a posição coluna 7 linha 2
LCD.print(vaga_livre); //escreve a variavel no LCD
LCD.setCursor(7,3); // direciona o texto no LCD para a posição coluna 7 linha 3
LCD.print(vaga_ocup); //escreve a variavel no LCD
LCD.setCursor(18,2); // direciona o texto no LCD para a posição coluna 18 linha 2
LCD.print(vaga_esp_livre); //escreve a variavel no LCD
LCD.setCursor(18,3); // direciona o texto no LCD para a posição coluna 18 linha 3
LCD.print(vaga_esp_ocup); //escreve a variavel no LCD
}
delay(1);
digitalWrite(EN, 0); //desliga o pino EN
RGB(teste); //Chama o Void RGB enviando a variavel teste
teste++; // adiciona +1 na variavel teste
if(teste >= 16)teste = 0; // se teste e igual ou maior que 16, transforma em 0
tempo++; // adiciona +1 na variavel tempo
}
//void RGB com 1 variavel para receber
void RGB(int V){
// led vaga 1
if(teste == 0 && ss1 == 1){ //define se o led vernelho no pino 0 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 1 && ss1 == 0 && vsp <= 0){ //define se o led verde no pino 1 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 2 && ss1 == 0 && vsp >= 1){ //define se o led azul no pino 2 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
// led vaga 2
if(teste == 3 && ss2 == 1){ //define se o led vernelho no pino 3 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 4 && ss2 == 0 && vsp <= 1){ //define se o led verde no pino 4 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 5 && ss2 == 0 && vsp >= 2){ //define se o led azul no pino 5 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
//led vaga 3
if(teste == 6 && ss3 == 1){ //define se o led vernelho no pino 6 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 7 && ss3 == 0 && vsp <= 2){ //define se o led verde no pino 7 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 8 && ss3 == 0 && vsp >= 3){ //define se o led verde no pino 8 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
//led vaga 4
if(teste == 9 && ss4 == 1){ //define se o led vernelho no pino 9 do multiplexador deve ligar
digitalWrite(sig, 1);
}
if(teste == 10 && ss4 == 0){ //define se o led verde no pino 10 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
//led vaga 5
if(teste == 11 && ss5 == 1){ //define se o led vernelho no pino 11 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 12 && ss5 == 0){ //define se o led verde no pino 12 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
//led vaga 6
if(teste == 13 && ss6 == 1){ //define se o led vernelho no pino 13 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
if(teste == 14 && ss6 == 0){ //define se o led verde no pino 14 do multiplexador deve ligar
digitalWrite(sig, 1); //liga o led
}
digitalWrite(RGB_S0, rgb_set[V] & 0b00000001); //compara a variavel da matriz com a constante para decidir se liga ou não
digitalWrite(RGB_S1, rgb_set[V] & 0b00000010); //compara a variavel da matriz com a constante para decidir se liga ou não
digitalWrite(RGB_S2, rgb_set[V] & 0b00000100); //compara a variavel da matriz com a constante para decidir se liga ou não
digitalWrite(RGB_S3, rgb_set[V] & 0b00001000); //compara a variavel da matriz com a constante para decidir se liga ou não
}
void vaga1 (){ // void para verificação do botão (sensor) da vaga 1
if(digitalRead(SV1) == 1 && ss1 == 0)ss1 = 1; // se o botão estiver pressionado e o set igual a 0, ele transforma o set em 1
if(digitalRead(SV1) == 0 && ss1 == 1)ss1 = 0; // se o botão não estiver pressionado e o set igual a 1, ele transforma o set em 0
}
void vaga2 (){ // void para verificação do botão (sensor) da vaga 2
if(digitalRead(SV2) == 1 && ss2 == 0)ss2 = 1; // se o botão estiver pressionado e o set igual a 0, ele transforma o set em 1
if(digitalRead(SV2) == 0 && ss2 == 1)ss2 = 0; // se o botão não estiver pressionado e o set igual a 1, ele transforma o set em 0
}
void vaga3 (){ // void para verificação do botão (sensor) da vaga 3
if(digitalRead(SV3) == 1 && ss3 == 0)ss3 = 1; // se o botão estiver pressionado e o set igual a 0, ele transforma o set em 1
if(digitalRead(SV3) == 0 && ss3 == 1)ss3 = 0; // se o botão não estiver pressionado e o set igual a 1, ele transforma o set em 0
}
void vaga4 (){ // void para verificação do botão (sensor) da vaga 4
if(digitalRead(SV4) == 1 && ss4 == 0)ss4 = 1; // se o botão estiver pressionado e o set igual a 0, ele transforma o set em 1
if(digitalRead(SV4) == 0 && ss4 == 1)ss4 = 0; // se o botão não estiver pressionado e o set igual a 1, ele transforma o set em 0
}
void vaga5 (){ // void para verificação do botão (sensor) da vaga 5
if(digitalRead(SV5) == 1 && ss5 == 0)ss5 = 1; // se o botão estiver pressionado e o set igual a 0, ele transforma o set em 1
if(digitalRead(SV5) == 0 && ss5 == 1)ss5 = 0; // se o botão não estiver pressionado e o set igual a 1, ele transforma o set em 0
}
void vaga6 (){ // void para verificação do botão (sensor) da vaga 6
if(digitalRead(SV6) == 1 && ss6 == 0)ss6 = 1; // se o botão estiver pressionado e o set igual a 0, ele transforma o set em 1
if(digitalRead(SV6) == 0 && ss6 == 1)ss6 = 0; // se o botão não estiver pressionado e o set igual a 1, ele transforma o set em 0
}
void Cancela(){ // void para controlar a cancela
if(digitalRead(B1) == 1 && b1 == 0){ //se botao for pressionado e set igual a 0
b1 = 1; //transforma o set em 1
if(servo1 == 0){ // troca a variavel entre 90 e 0
servo1 = 90;
}else {
servo1 = 0;
}
}
if(digitalRead(B1) == 0 && b1 == 1)b1 = 0; // se botao não for pressionado e set igual a 1 transforma o set em 0
if(digitalRead(B2) == 1 && b2 == 0){ // se botao for pressionado e set igual a 0
b2 = 1;
if(servo2 == 0){ // troca a variavel entre 90 e 0
servo2 = 90;
}else {
servo2 = 0;
}
}
if(digitalRead(B2) == 0 && b2 == 1)b2 = 0; // se botao não for pressionado e set igual a 1 transforma o set em 0
servoMotor_in.write(servo1); //manda o servo ir para a posição escrita na variavel
servoMotor_out.write(servo2); //manda o servo ir para a posição escrita na variavel
}