Skip to content

Instantly share code, notes, and snippets.

@rafabarzotto
Last active November 11, 2020 18:30
Show Gist options
  • Save rafabarzotto/ad1cef0f698f1eb518cd965ce1c04df9 to your computer and use it in GitHub Desktop.
Save rafabarzotto/ad1cef0f698f1eb518cd965ce1c04df9 to your computer and use it in GitHub Desktop.
/*********************************************************************
This is an example sketch for our Monochrome Nokia 5110 LCD Displays
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/338
These displays use SPI to communicate
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
/*
SCK 18
MOSI 23
DC 19
RST 14
CS 5
*/
#ifdef ESP32
#include <WiFi.h>
#include <HTTPClient.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#endif
#include <Arduino_JSON.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <deprecated.h>
#include <MFRC522.h>
#include <MFRC522Extended.h>
#include <require_cpp11.h>
#define BL 27
#define SCK 15
#define MOSI 2
#define DC 4
#define RST 13
#define CS 5
#define SS_PIN 21
#define RST_PIN 22
// Replace with your network credentials
const char* ssid = "Escritorio_Barzotto";
const char* password = "";
String serverName = "http://192.168.10.81/chopp/php/";
String sensorReadings;
int botao300ml = 12;
int botao500ml = 14;
int ledBotao300ml = 32;
int ledBotao500ml = 33;
int releValvula = 25;
byte sensorFluxo = 34;
int qtdEscolhida = 0;
String uidString;
float valor300;
float valor500;
int idCliente;
float saldoCliente;
float calibrationFactor = 7;
volatile byte pulseCount;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;
unsigned long tempoEscolha;
//Enumurates for state machine
enum enumState {
telaInicial,
rfidScan,
selecionaQuantidade,
liberaChopp,
aguardandoEncherCopo,
ativaSensorDeFluxo,
telaFinal,
telaErro
};
//Start with welcome screen
enumState state = telaInicial;
Adafruit_PCD8544 display = Adafruit_PCD8544(SCK, MOSI, DC, CS, RST);
//Adafruit_PCD8544 display = Adafruit_PCD8544(DC, CS, RST);
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
Serial.begin(9600);
pinMode(botao300ml, INPUT_PULLUP);
pinMode(botao500ml, INPUT_PULLUP);
pinMode(sensorFluxo, INPUT_PULLUP);
pinMode(ledBotao300ml, OUTPUT);
pinMode(ledBotao500ml, OUTPUT);
pinMode(releValvula, OUTPUT);
digitalWrite(ledBotao300ml, LOW); //LED INICIA DESLIGADO
digitalWrite(ledBotao500ml, LOW); //LED INICIA DESLIGADO
digitalWrite(releValvula, LOW); //LED INICIA DESLIGADO
digitalWrite(sensorFluxo, LOW);
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
oldTime = 0;
display.begin();
// init done
// Init MFRC522
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init();
Serial.println("RFID Pronto...");
Serial.println();
// you can change the contrast around to adapt the display
// for the best viewing!
//display.setContrast(50);
display.display(); // show splashscreen
delay(3000);
WiFi.begin(ssid, password);
Serial.println("Conectando");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(2, 15);
display.print("Conectando...");
display.display();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
display.clearDisplay();
Serial.println("");
Serial.print("Conectado ao WiFi com o IP: ");
Serial.println(WiFi.localIP());
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(2, 15);
display.print(WiFi.localIP());
display.display();
delay(5000);
display.clearDisplay();
Serial.println("Pronto ...");
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
attachInterrupt(sensorFluxo, pulseCounter, CHANGE);
}
void loop() {
switch (state)
{
case telaInicial:
qtdEscolhida = 0;
totalMilliLitres = 0;
idCliente = 0;
saldoCliente = 0;
digitalWrite(ledBotao300ml, LOW);
digitalWrite(ledBotao500ml, LOW);
digitalWrite(sensorFluxo, LOW);
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(12, 15);
display.println("Aguardando");
display.print(" Leitura..");
display.display();
delay(1000); //Sleep for a second.
if(carregarValores() == "ok"){
state = rfidScan;
} else {
state = telaErro;
}
break;
case rfidScan:
RfidScan();
break;
case selecionaQuantidade:
SelecionaQuantidade();
break;
case liberaChopp:
LiberaChopp();
break;
case ativaSensorDeFluxo:
AtivaSensorDeFluxo();
break;
case aguardandoEncherCopo:
lerSensorFluxo();
break;
case telaFinal:
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(8, 15);
display.print("Obrigado!!");
display.display();
display.clearDisplay();
delay(3000);
state = telaInicial;
break;
case telaErro:
qtdEscolhida = 0;
totalMilliLitres = 0;
idCliente = 0;
saldoCliente = 0;
digitalWrite(ledBotao300ml, LOW);
digitalWrite(ledBotao500ml, LOW);
digitalWrite(sensorFluxo, LOW);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(30, 10);
display.print("Erro");
display.setCursor(10, 20);
display.print("de Conexao");
display.setCursor(15, 30);
display.print("com o BD..");
display.display();
delay(2000);
display.clearDisplay();
break;
}
}
/**
Dump data to the Serial Monitor.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
char message[bufferSize];
for (byte i = 0; i < bufferSize; i++) {
//Serial.print(buffer[i] < 0x10 ? ” 0″ : ” “);
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
Serial.print(" = ");
uidString = String(mfrc522.uid.uidByte[0]) + String(mfrc522.uid.uidByte[1]) + String(mfrc522.uid.uidByte[2]) + String(mfrc522.uid.uidByte[3]);
Serial.print(uidString);
Serial.println(); //Move on to the next line.
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(15, 15);
display.print(uidString);
display.display();
delay(3000);
display.clearDisplay();
if (lerCartaoBanco(uidString) == "ok") {
cartaoCadastrado();
} else if (lerCartaoBanco(uidString) == "nok") {
cartaoNaoCadastrado();
} else {
state = telaErro;
}
// if (uidString == "4 21 145 138") {
// cartaoCadastrado();
// } else {
// cartaoNaoCadastrado();
// }
}
/**
Scan for RFID Tags.
*/
void RfidScan()
{
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
if ( ! mfrc522.PICC_ReadCardSerial())
return;
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
}
void SelecionaQuantidade()
{
if (digitalRead(botao300ml) == HIGH) {
Serial.println("Apertou 300");
digitalWrite(ledBotao300ml, HIGH);
qtdEscolhida = 300;
if (saldoCliente >= valor300) {
state = liberaChopp;
} else {
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(25, 15);
display.println("Saldo");
display.setCursor(0, 25);
display.print("Insuficiente..");
display.display();
delay(3000); //Sleep for a second.
display.clearDisplay();
state = telaInicial;
}
}
if (digitalRead(botao500ml) == HIGH) {
Serial.println("Apertou 500");
digitalWrite(ledBotao500ml, HIGH);
qtdEscolhida = 500;
if (saldoCliente > valor500) {
state = liberaChopp;
} else {
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(25, 15);
display.println("Saldo");
display.setCursor(0, 25);
display.print("Insuficiente..");
display.display();
delay(3000); //Sleep for a second.
display.clearDisplay();
state = telaInicial;
}
}
else {
//Serial.println("Nao Apertou");
}
}
void LiberaChopp()
{
if(descontarSaldoBanco() == "ok"){
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(6, 15);
display.print(String(qtdEscolhida) + "ml");
display.display();
delay(2000);
display.clearDisplay();
digitalWrite(releValvula, HIGH);
state = ativaSensorDeFluxo;
} else {
state = telaErro;
}
}
void AtivaSensorDeFluxo()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(8, 15);
display.print("Encha seu copo");
display.display();
//delay(2000);
digitalWrite(sensorFluxo, HIGH);
display.clearDisplay();
state = aguardandoEncherCopo;
}
void AguardandoEncherCopo()
{
lerSensorFluxo();
}
void cartaoCadastrado()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(13, 15);
display.println("Selecione");
display.setCursor(6, 25);
display.println("a Quantidade");
display.display();
delay(2000);
display.clearDisplay();
state = selecionaQuantidade;
}
void cartaoNaoCadastrado()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(30, 15);
display.print("Nao");
display.setCursor(8, 25);
display.print("Cadastrado..");
display.display();
delay(2000);
display.clearDisplay();
state = telaInicial;
}
/*
Insterrupt Service Routine
*/
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void lerSensorFluxo()
{
if ((millis() - oldTime) > 1000) // Only process counters once per second
{
// Disable the interrupt while calculating flow rate and sending the value to
// the host
detachInterrupt(sensorFluxo);
// Because this loop may not complete in exactly 1 second intervals we calculate
// the number of milliseconds that have passed since the last execution and use
// that to scale the output. We also apply the calibrationFactor to scale the output
// based on the number of pulses per second per units of measure (litres/minute in
// this case) coming from the sensor.
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Note the time this processing pass was executed. Note that because we've
// disabled interrupts the millis() function won't actually be incrementing right
// at this point, but it will still return the value it was set to just before
// interrupts went away.
oldTime = millis();
// Divide a taxa de fluxo em litros por minuto por 60, para determinar quantos litros
// passou nesse sensor no intervalo de 1 segundo, multiplicar por 1000
// para converter em mililitros
flowMilliLitres = (flowRate / 60) * 1000;
// Acumula quantos mililitros passaram
totalMilliLitres += flowMilliLitres;
if (totalMilliLitres > qtdEscolhida) {
//digitalWrite(releValvula, LOW);
state = telaFinal;
oldTime = 0;
digitalWrite(releValvula, LOW); //LED INICIA DESLIGADO
}
unsigned int frac;
Serial.print("Pulsos: ");
Serial.print(pulseCount);
Serial.print("\t"); // Print tab space
// Print the flow rate for this second in litres / minute
Serial.print("Taxa de Fluxo em Litros/min: ");
Serial.print(int(flowRate)); // Print the integer part of the variable
Serial.print("L/min");
Serial.print("\t"); // Print tab space
// Print the cumulative total of litres flowed since starting
Serial.print("Saída Total de Liquido: ");
Serial.print(totalMilliLitres);
Serial.println("mL");
Serial.print("\t"); // Print tab space
Serial.print(totalMilliLitres / 1000);
Serial.print("L");
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(6, 15);
display.print(String(totalMilliLitres) + "ml");
display.display();
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorFluxo, pulseCounter, RISING);
}
}
String lerCartaoBanco(String codCartao) {
if (WiFi.status() == WL_CONNECTED) {
String url = "getCartao.php?cod_cartao=" + codCartao;
String url_full = serverName + url;
const char* urlChar = url_full.c_str();
Serial.println(urlChar);
sensorReadings = httpGETRequest(urlChar);
JSONVar myObject = JSON.parse(sensorReadings);
if(sensorReadings != "erro"){
if (myObject["success"]) {
idCliente = JSON.stringify(myObject["data"]["id"]).toInt();
saldoCliente = JSON.stringify(myObject["data"]["saldo"]).toFloat();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0, 1);
display.println("Ola " + JSON.stringify(myObject["data"]["nome"]) + ",");
display.setTextSize(1);
display.setCursor(0, 10);
display.println("Seu saldo: ");
display.setCursor(0, 30);
display.println("R$:" + JSON.stringify(myObject["data"]["saldo"]));
display.display();
delay(4000);
display.clearDisplay();
return "ok";
} else {
return "nok";
}
} else {
return "erro";
}
} else {
}
}
String carregarValores() {
if (WiFi.status() == WL_CONNECTED) {
String url = "listaValores.php";
String url_full = serverName + url;
const char* urlChar = url_full.c_str();
Serial.println(urlChar);
sensorReadings = httpGETRequest(urlChar);
if(sensorReadings != "erro"){
JSONVar myObject = JSON.parse(sensorReadings);
valor300 = JSON.stringify(myObject["data"][0]["valor"]).toFloat();
valor500 = JSON.stringify(myObject["data"][1]["valor"]).toFloat();
Serial.println(valor300);
Serial.println(valor500);
return "ok";
} else {
return "erro";
}
} else {
}
}
String descontarSaldoBanco() {
if (WiFi.status() == WL_CONNECTED) {
String url = "salvaConsumo.php";
String url_full = serverName + url;
const char* urlChar = url_full.c_str();
String dados = "id_copo=" + String(qtdEscolhida) + "&id_cliente=" + String(idCliente);
const char* dadosChar = dados.c_str();
Serial.println(dadosChar);
sensorReadings = httpPOST(urlChar, dadosChar);
if(sensorReadings != "erro"){
JSONVar myObject = JSON.parse(sensorReadings);
Serial.println(myObject);
return "ok";
} else {
return "erro";
}
}
}
String httpGETRequest(const char* serverName) {
HTTPClient http;
// Your IP address with path or Domain name with URL path
http.begin(serverName);
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "{}";
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
payload = "erro";
}
// Free resources
http.end();
return payload;
}
String httpPOST(const char* serverName, const char* httpRequestData) {
HTTPClient http;
// Your IP address with path or Domain name with URL path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpResponseCode = http.POST(httpRequestData);
String payload = "{}";
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
payload = "erro";
}
// Free resources
http.end();
return payload;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment