// simple project using Arduino UNO and 16x2 character display to display smooth gauge,
// created by upir, 2022
// youtube channel: https://www.youtube.com/upir_upir
// FULL TUTORIAL: https://youtu.be/ZzIGHiHObYw
// GAUGE IN 11 MINUTES TUTORIAL: https://youtu.be/upE17NHrdPc
// Links related to this project:
// Arduino UNO - https://s.click.aliexpress.com/e/_AXDw1h
// Arduino breadboard prototyping shield - https://s.click.aliexpress.com/e/_ApbCwx
// 16x2 displays with IIC - https://s.click.aliexpress.com/e/_9Hl3JV
// 16x2 display with RGB backlight - https://s.click.aliexpress.com/e/_9wgpeb
// original sketch from YWROBOT - https://wokwi.com/arduino/libraries/LiquidCrystal_I2C/HelloWorld
// character creator - https://tusindfryd.github.io/screenduino/
// another character creator - https://maxpromer.github.io/LCD-Character-Creator/
// sprintf explanation - https://www.programmingelectronics.com/sprintf-arduino/
// custom characters simplest project - https://wokwi.com/projects/294395602645549578
// Arduino I2C scanner - https://playground.arduino.cc/Main/I2cScanner/
// 16x2 available characters - https://docs.wokwi.com/parts/wokwi-lcd1602#font
// Bitwise Operators in GIFs - https://blog.wokwi.com/bitwise-operators-in-gifs/
// Bitwise operators Arduino documentation - https://www.arduino.cc/reference/en/language/structure/bitwise-operators/bitshiftleft/
#include <LiquidCrystal_I2C.h> // if you don´t have I2C version of the display, use LiquidCrystal.h library instead
#include <Keypad.h>
#include <SdFat.h>
//SOBRE O LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// set the LCD address to 0x27 for a 16 chars and 2 line display
//LiquidCrystal_I2C lcd(0x3f,16,2); // set the LCD address to 0x3f for a 16 chars and 2 line display
// if you don´t know the I2C address of the display, use I2C scanner first (https://playground.arduino.cc/Main/I2cScanner/)
int screenWidth = 16;
int screenHeight = 2;
int stringStart = 0;
int stringEnd = 0;
int scrollCursor = screenWidth;
String line1 = "Tecle * ";
String line2 = "Sistema de controle de acesso."; //scroll this line
//SOBRE O TECLADO
#define linhasTCL 4
#define colunasTCL 4
char mapaTeclado[4][4]={{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};
byte pinos_linhas[linhasTCL]={6,7,8,9};
byte pinos_colunas[colunasTCL]={2,3,4,5};
Keypad teclado=Keypad(makeKeymap(mapaTeclado),pinos_linhas,pinos_colunas,linhasTCL,colunasTCL);
// Estudo sobre ARRAY
//Linha 0 igual aos usuários;
//Linha 1 igual às senhas; Ex: [0][0] = usuario 1, [0][1] = senha usuario 1, [1][0] = usuario 2, [1][1] = senha usuario 2, etc...;
String ARAYdoExercicio [10][2];
//String ARAYdoExercicio [10];
String LiberaGravarUser;
String SENHALiberaGravarUser = "A1234567";
int col = 0;
int row = 0;
int colsalvadofor = 0;
int FazeroQue = 0;
String Vazio = "";
// Fim estudo sobre ARRAY
int pulandoCol = 0;
int pulandoRow = 0;
String NomeUsuario = "Giuliano";
String IDGiuliano = "12345678912";
String IDUsuario = "12345678912";
String SENHAUsuario = "12345678";
String SENHADigitada;
String IDUsuarioDigitado;
String NovoIDUsuario;
String SenhaNovoUsuario;
String SenhaNovoUsuarioConfirmanda;
//#define SD_CS 10 // SD card select pin
void setup()
{
Serial.begin(57600);
lcd.init(); // initialize the 16x2 lcd module
lcd.backlight(); // enable backlight for the LCD module
lcd.begin(screenWidth, screenHeight);
/// ReadCsvFile
#define SD_FAT_TYPE 3
/*
Change the value of SD_CS_PIN if you are using SPI and
your hardware does not use the default value, SS.
Common values are:
Arduino Ethernet shield: pin 4
Sparkfun SD shield: pin 8
Adafruit SD shields and modules: pin 10
*/
// SDCARD_SS_PIN is defined for the built-in SD on some boards.
#ifndef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SS;
#else // SDCARD_SS_PIN
// Assume built-in SD is used.
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif // SDCARD_SS_PIN
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(50)
// Try to select the best SD card configuration.
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS
//------------------------------------------------------------------------------
#if SD_FAT_TYPE == 0
SdFat sd;
File file;
File root;
#elif SD_FAT_TYPE == 1
SdFat32 sd;
File32 file;
File32 root;
#elif SD_FAT_TYPE == 2
SdExFat sd;
ExFile file;
ExFile root;
#elif SD_FAT_TYPE == 3
SdFs sd;
FsFile file;
FsFile root;
#endif // SD_FAT_TYPE
if (!sd.begin(SD_CONFIG)) {
sd.initErrorHalt(&Serial);
return;}
else {
Serial.println("o SD_CS_PIN é :");
Serial.println(SD_CS_PIN);
Serial.println("o SD_FAT_TYPE é :");
Serial.println(SD_FAT_TYPE);
Serial.println("o FIFO_SDIO é :");
Serial.println(FIFO_SDIO);
Serial.println("o SPI_CLOCK é :");
Serial.println(SPI_CLOCK);
Serial.println("o HAS_SDIO_CLASS é :");
Serial.println(HAS_SDIO_CLASS);
Serial.println("cartão iniciou corretamente");
}
delay (100000);
}
void loop()
{
Serial.print ("Fazer o que começou com: ");
Serial.println (FazeroQue);
if(FazeroQue == 0)
{
// Neste if o sistema de rolagem de linha.
lcd.setCursor (0, 1); // Seting the cursor on first row
lcd.print (line1);
lcd.setCursor (scrollCursor, 0); // Seting the cursor on first row and (scrolling from left to right)
lcd.print(line2.substring(stringStart, stringEnd)); // To print line1 first character "T"
//Serial.println (line2.substring(stringStart, stringEnd));
delay (250);
//lcd.clear(); // clear message
lcd.setCursor(0, 0);
lcd.print(" ");
if (stringStart == 0 && scrollCursor > 0)
{
scrollCursor --; // moving cursor from 16 to 0
stringEnd ++;
} //character T, H, I, S ...
// it wil print out character from 0 to 15 (entire length of the screen)
else if (stringStart == stringEnd)
{
stringStart = stringEnd = 0; // start oll over again
scrollCursor = screenWidth;
}
else if (stringEnd == line2.length() and scrollCursor == 0)
{
stringStart ++;
} // if reaches to end character
else // it will print out character from (1 to 16) to end character
{
stringStart ++;
stringEnd ++;
}
}
zerandotecla:
char tecla=teclado.getKey();
if(tecla != NO_KEY)
{
if(tecla == '*' and FazeroQue == 0) // interrompendo por timer
{
DigitandoIdUser ();
MudandoFazeroQue1 ();
pulandoCol = 5;
pulandoRow = 1;
lcd.setCursor(pulandoCol, pulandoRow);
goto saindodoinisenha;
}
if(tecla == '*' and FazeroQue == 0)
{
DigitandoIdUser ();
MudandoFazeroQue1 ();
pulandoCol = 5;
pulandoRow = 1;
lcd.setCursor(pulandoCol, pulandoRow);
goto saindodoinisenha;
}
if(tecla == '#' and FazeroQue != 0)
{
MudandoFazeroQue0 ();
IDUsuarioDigitado="";
SENHADigitada="";
LiberaGravarUser = "";
SenhaNovoUsuario="";
SenhaNovoUsuarioConfirmanda="";
NovoIDUsuario = "";
lcd.clear();
goto saindodoinisenha;
}
if(tecla == 'A' and FazeroQue == 0) // Digitando senha Libera Função especial
{
LiberaGravarUser+=tecla; // Só será usado uma vez, para salvar o # no LiberaGravarUser
DigitandoLiberaGravarUser ();
MudandoFazeroQue8 ();
lcd.clear();
pulandoCol = 0;
pulandoRow = 0;
lcd.print(tecla);
MudandoColumm ();
//columusuario ();
//linhausuario ();
goto saindodoinisenha;
}
if(tecla == 'D' and FazeroQue == 0) // Digitando senha Libera Função especial
{
for ( int col = 0; col < 10; col++)
{
if (ARAYdoExercicio[col][row]!=Vazio)
{
Serial.println (col);
Serial.println (ARAYdoExercicio[col][row]);
//goto SairdolacoFor;
}
}
}
if(tecla != '#' and tecla != '*' and FazeroQue == 1)
{
IDUsuarioDigitado+=tecla;
Serial.println (IDUsuarioDigitado);
lcd.setCursor(pulandoCol, pulandoRow);
lcd.print(tecla);
//delay(500); // DELAY DE 1 SEGUNDOS
//lcd.setCursor(pulandoCol, pulandoRow);
//lcd.print("*");
MudandoColumm();
if(IDUsuarioDigitado.length()==11 && VerificaSenha(IDUsuario, IDUsuarioDigitado)==1)
{
UsuarioCorreto ();
pulandoCol = 6;
pulandoRow = 1;
IDUsuarioDigitado="";
goto zerandotecla;
//Serial.println (SENHAUsuario);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHADigitada);
}
if(IDUsuarioDigitado.length()==11 && VerificaSenha(IDUsuario, IDUsuarioDigitado)==0)
{
FazeroQue = FazeroQue - FazeroQue;
lcd.setCursor (0,0);
lcd.print("Usuario,nao cadastrado.");
lcd.setCursor (0,1); // Seting the cursor on first row
lcd.print ("Tente novamente.");
delay (4000);
lcd.clear();
IDUsuarioDigitado="";
delay (4000);
//Serial.println (SENHAUsuario);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHADigitada);
}
//else{ SENHADigitada+=tecla;}
//Serial.println (SENHADigitada);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHAUsuario);
}
if(tecla != '#' and tecla != '*' and FazeroQue == 2)
{
SENHADigitada+=tecla;
lcd.setCursor(pulandoCol, pulandoRow);
lcd.print(tecla);
delay(500); // DELAY DE 1 SEGUNDOS
lcd.setCursor(pulandoCol, pulandoRow);
lcd.print("*");
MudandoColumm();
if(SENHADigitada.length()==8 && VerificaSenha(SENHAUsuario, SENHADigitada)==1)
{
SenhaCorreta ();
SENHADigitada="";
//Serial.println (SENHAUsuario);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHADigitada);
}
if(SENHADigitada.length()==8 && VerificaSenha(SENHAUsuario, SENHADigitada)==0)
{
SenhaErrada ();
SENHADigitada="";
//Serial.println (SENHAUsuario);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHADigitada);
}
//else{ SENHADigitada+=tecla;}
//Serial.println (SENHADigitada);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHAUsuario);
}
if(pulandoCol <= 15 and tecla != '*' and FazeroQue == 3)
{
lcd.setCursor(pulandoCol, pulandoRow);
lcd.print(tecla);
MudandoColumm();
//if(VerificaSenha(SENHAUsuario, SENHADigitada))
//{
//Serial.println (SENHAUsuario);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHADigitada);
//lcd.clear();
//lcd.print("senha correta Giuliano");
//}
//else{ SENHADigitada+=tecla;}
//Serial.println (SENHADigitada);
//Serial.println (NomeUsuario);
//Serial.println (IDGiuliano);
//Serial.println (SENHAUsuario);
}
if(FazeroQue == 5) // Confirmando SENHA novo usuario 8 digitos
{
SenhaNovoUsuarioConfirmanda+=tecla;
Serial.println (SenhaNovoUsuarioConfirmanda);
lcd.print(tecla);
MudandoColumm ();
if(SenhaNovoUsuarioConfirmanda.length()==8 && VerificaSenha(SenhaNovoUsuario, SenhaNovoUsuarioConfirmanda)==1)
{
pulandoCol = 0;
pulandoRow = 1;
lcd.setCursor(pulandoCol, pulandoRow);
lcd.print("SENHA IGUAL");
row = 1;
ARAYdoExercicio[colsalvadofor][row] = SenhaNovoUsuarioConfirmanda; // Salvando a senha
col = 0;
row = 0;
delay (4000);
SenhaNovoUsuario=("");
SenhaNovoUsuarioConfirmanda=("");
pulandoCol = 0;
pulandoRow = 0;
lcd.clear();
MudandoFazeroQue0 ();
}
else if (SenhaNovoUsuarioConfirmanda.length()==8 && VerificaSenha(SenhaNovoUsuario, SenhaNovoUsuarioConfirmanda)==0)
{
pulandoCol = 0;
pulandoRow = 1;
lcd.setCursor(pulandoCol, pulandoRow);
lcd.print("SENHA DIFERENTE");
col = 0;
row = 0;
delay (4000);
SenhaNovoUsuario=("");
SenhaNovoUsuarioConfirmanda=("");
pulandoCol = 0;
pulandoRow = 0;
lcd.clear();
MudandoFazeroQue0 ();
}
goto zerandotecla;
}
if(FazeroQue == 6) // Digitando SENHA novo usuario 8 digitos
{
SenhaNovoUsuario+=tecla;
Serial.println (SenhaNovoUsuario);
lcd.print(tecla);
MudandoColumm ();
if(SenhaNovoUsuario.length()==8)
{
MudandoFazeroQue5 ();
ConfirmandoSenhaNovoUsuario ();
pulandoCol = 0;
pulandoRow = 1;
lcd.setCursor(pulandoCol, pulandoRow);
}
goto zerandotecla;
}
if(FazeroQue == 7) // Digitando novo ID usuario 12 digitos CPF de preferencia
{
NovoIDUsuario+=tecla;
Serial.println (NovoIDUsuario);
lcd.print(tecla);
MudandoColumm ();
if(NovoIDUsuario.length()==11)
{
for ( int col = 0; col < 10; col++)
{
//if (isblank(ARAYdoExercicio[i]))
if (ARAYdoExercicio[col][row]==Vazio)
{
//Serial.println (i);
//Serial.println ("antes do array vazio");
//Serial.println (ARAYdoExercicio[i]);
//Serial.println (i);
//Serial.println ("depois do array vazio");
ARAYdoExercicio[col][row]=NovoIDUsuario;
//Serial.println (ARAYdoExercicio[col][row]);
//Serial.println (NovoIDUsuario);
colsalvadofor = col;
goto SairdolacoFor;
}
if (ARAYdoExercicio[col][row]==NovoIDUsuario)
{
lcd.clear();
lcd.print("Usuario ja cadastrado.");
MudandoFazeroQue0 ();
NovoIDUsuario = "";
goto zerandotecla;
}
}
SairdolacoFor:
MudandoFazeroQue6 ();
NovoIDUsuario = "";
DigitandoSenhaNovoUsuario ();
pulandoCol = 0;
pulandoRow = 1;
lcd.setCursor(pulandoCol, pulandoRow);
}
goto zerandotecla;
}
if(FazeroQue == 8) // Digitando senha Libera Gravar User
{
LiberaGravarUser+=tecla;
DigitandoLiberaGravarUser ();
lcd.print(tecla);
Serial.println (LiberaGravarUser);
MudandoColumm ();
if(LiberaGravarUser.length()==8 && VerificaSenha(SENHALiberaGravarUser, LiberaGravarUser)==1)
{
RegistrandoIdUser ();
MudandoFazeroQue7 ();
lcd.setCursor(0, 1);
pulandoCol = 0;
pulandoRow = 1;
LiberaGravarUser = "";
}
//columusuario ();
//linhausuario ();
goto saindodoinisenha;
}
if(pulandoCol == 14 and FazeroQue == 9)
{
//delay(1000); // DELAY DE 1 SEGUNDOS
lcd.clear();
//lcd.print("Conferindo informação");
//lcd.setCursor(0, 1);
//lcd.print("Aguarde...");
}
saindodoinisenha:
if(pulandoCol == 14 and FazeroQue == 10)
{
//delay(1000); // DELAY DE 1 SEGUNDOS
//lcd.clear();
//lcd.print("Conferindo informação");
//lcd.setCursor(0, 1);
//lcd.print("Aguarde...");
}
//if(tecla == NO_KEY and pulandoCol !=0 and pulandoCol <14 and FazeroQue == 1)
//{
//lcd.setCursor(pulandoCol, pulandoRow);
//lcd.print("_");
//delay(500); // DELAY DE 1 SEGUNDOS
//lcd.setCursor(pulandoCol, pulandoRow);
//lcd.print(" ");
//delay(500); // DELAY DE 1 SEGUNDOS
//}
}
}
int MudandoColumm() //Função que só retorna valor, se chamada no loop
{
if (pulandoCol<15){pulandoCol = pulandoCol +1;}
else if (pulandoCol=15){pulandoCol = pulandoCol -15;}
return pulandoCol;
}
int VoltaInicio() //Função que só retorna valor, se chamada no loop
{
lcd.clear();
}
int MudandooRow () //Função que só retorna valor, se chamada no loop
{
if (pulandoRow<1){pulandoRow = pulandoRow +1;}
else if (pulandoRow=1){pulandoRow = pulandoRow -1;}
return pulandoRow;
}
int CapturaTecla () //não funciona só funciona no loop
{
char tecla=teclado.getKey();
if(tecla != NO_KEY);
return tecla;
}
int DigitandoIdUser () //Função que só retorna valor, se chamada no loop
{
lcd.clear();
lcd.print("Digite o seu ID");
lcd.setCursor(0, 1);
lcd.print("user:_");
}
int RegistrandoIdUser () //Função que só retorna valor, se chamada no loop
{
lcd.clear();
lcd.print("Registre novo ID User:");
lcd.setCursor(0, 1);
lcd.print("_");
}
int DigitandoSenhaNovoUsuario () //Função que só retorna valor, se chamada no loop
{
lcd.clear();
lcd.print("Registre sua SENHA:");
lcd.setCursor(0, 1);
lcd.print("_");
}
int ConfirmandoSenhaNovoUsuario () //Função que só retorna valor, se chamada no loop
{
lcd.clear();
lcd.print("Confirme sua SENHA:");
lcd.setCursor(0, 1);
lcd.print("_");
}
int DigitandoLiberaGravarUser () //Função que só retorna valor, se chamada no loop
{
lcd.setCursor(pulandoCol, pulandoRow);
}
int UsuarioCorreto () //Função que só retorna valor, se chamada no loop
{
//lcd.clear();
//lcd.print("Conferindo informação");
//lcd.setCursor(0, 1);
//lcd.print("Aguarde...");
delay(1000); // DELAY DE 1 SEGUNDOS
lcd.clear();
lcd.print("Bom dia ");
lcd.print (NomeUsuario);
lcd.setCursor(0, 1);
lcd.print("senha:_");
FazeroQue = FazeroQue +1;
return FazeroQue;
}
int SenhaCorreta () //Função que só retorna valor, se chamada no loop
{
lcd.clear();
lcd.print("Porfavor, feche o portão após entrar.");
lcd.setCursor(0, 1);
lcd.print("Obrigado.");
delay(4000); // DELAY DE 4 SEGUNDOS
lcd.clear();
FazeroQue = FazeroQue -2;
return FazeroQue;
}
int SenhaErrada () //Função que só retorna valor, se chamada no loop
{
lcd.clear();
lcd.print("Senha incorreta.");
lcd.setCursor(0, 1);
lcd.print("Tente novamente.");
delay(4000); // DELAY DE 4 SEGUNDOS
lcd.clear();
FazeroQue = FazeroQue -2;
return FazeroQue;
}
int MudandoFazeroQue1 () //Função que só retorna valor, se chamada no loop
{
if (FazeroQue==0){FazeroQue = FazeroQue +1;}
return FazeroQue;
}
int MudandoFazeroQue0 () //Função que só retorna valor, se chamada no loop
{
if (FazeroQue!=0){FazeroQue = FazeroQue - FazeroQue;}
return FazeroQue;
}
int MudandoFazeroQue8 () //Função que só retorna valor, se chamada no loop
{
if (FazeroQue==0){FazeroQue = FazeroQue +8;}
return FazeroQue;
}
int MudandoFazeroQue7 () //Função que só retorna valor, se chamada no loop
{
if (FazeroQue==8){FazeroQue = FazeroQue -1;}
return FazeroQue;
}
int MudandoFazeroQue6 () //Função que só retorna valor, se chamada no loop
{
if (FazeroQue==7){FazeroQue = FazeroQue -1;}
return FazeroQue;
}
int MudandoFazeroQue5 () //Função que só retorna valor, se chamada no loop
{
if (FazeroQue==6){FazeroQue = FazeroQue -1;}
return FazeroQue;
}
bool VerificaSenha(String sa, String sd) //Para comparar a senha digitada com a senha do sistema
{
bool resultado;
if(sa.compareTo(sd)==0) //se o compareTo encontra senhas iguais retorna 0 (true).
{resultado=true;}
else
{resultado=false;}
return resultado;
}