As @PeteKnight said, it’s frustrating for any forum member to help as nobody can have patience and time to get the full picture of your project spreading across seemingly unrelated topics.
Anyway, we all can see you have lot of patience in getting help, by trying your best in researching and modifying the code yourself.
So this is just a little bit of help. The most critical issues are
- The incorrect use of ISR (“ISR not in IRAM”)
- The use of delay() in wrong place to control the relay
- Many other problems as well
Here is the preliminary fix, based on your code. Hope you study it and improve.
#ifndef ESP8266
#error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting.
#endif
#define BLYNK_PRINT Serial
#define USE_BLYNK_WM true
// Not use #define USE_SPIFFS => using EEPROM for configuration data in WiFiManager
// #define USE_SPIFFS false => using EEPROM for configuration data in WiFiManager
// #define USE_SPIFFS true => using SPIFFS for configuration data in WiFiManager
// Be sure to define USE_SPIFFS before #include <BlynkSimpleEsp8266_WM.h>
#define USE_SPIFFS false //true
#if (!USE_SPIFFS)
// EEPROM_SIZE must be <= 4096 and >= CONFIG_DATA_SIZE (currently 172 bytes)
#define EEPROM_SIZE (4 * 1024)
// EEPROM_START + CONFIG_DATA_SIZE must be <= EEPROM_SIZE
#define EEPROM_START 0
#endif
// Force some params in Blynk, only valid for library version 1.0.1 and later
#define TIMEOUT_RECONNECT_WIFI 10000L
#define RESET_IF_CONFIG_TIMEOUT true
#define CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET 5
// Those above #define's must be placed before #include <BlynkSimpleEsp8266_WM.h>
#define USE_SSL false
#if USE_BLYNK_WM
#if USE_SSL
#include <BlynkSimpleEsp8266_SSL_WM.h> //https://github.com/khoih-prog/Blynk_WM
#else
#include <BlynkSimpleEsp8266_WM.h> //https://github.com/khoih-prog/Blynk_WM
#endif
#else
#if USE_SSL
#include <BlynkSimpleEsp8266_SSL.h>
#else
#include <BlynkSimpleEsp8266.h>
#endif
char auth[] = "*";
char ssid[] = "*";
char pass[] = "*";
#endif
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 5 // Configurable, see typical pin layout above
#define SS_PIN 4 // Configurable, see typical pin layout above
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
MFRC522::MIFARE_Key key;
byte nuidPICC[4];
//Project Code
bool pinValue5;
bool pinValue10;
bool pinValue20;
bool pinValue50;
bool pinValueConfirm;
bool flag;
//Flow Rate
int limitType, tap_limit_value, timer1, timer2, timer3, rowIndex = 0, month_old;
volatile uint32_t pulseCount = 0;
float flowRate = 0.00, waterCost, waterCost_month;
float flowLitres;
float totalLitres, totalLitres_month;
#define vPIN_VALUE_5 V0
#define vPIN_VALUE_10 V1
#define vPIN_VALUE_20 V2
#define vPIN_VALUE_50 V3
#define vPIN_CONFIRM V4
#define vPIN_LVD V5
#define vPIN_TAP_LED V7
#define vPIN_TAP_LIMIT V14
#define vPIN_TAP_MANUAL V18
#define vPIN_TAP_ACTIVATE V19
#define vPIN_WATER_TOTAL V25
#define vPIN_WATER_TOTAL_MONTH V21
#define vPIN_WATER_FLOW V26
#define vPIN_WATER_COST V28
#define vPIN_WATER_COST_MONTH V11
#define vPIN_WATER_TAP V27
#define vPIN_TERMINAL V31
#define vPIN_LIMITMENU V9
#define vPIN_LAST_MONTH V10
#define FLOW_SENSOR D3 // D2
#define FLOW_CALIBRATION 4.5
#define WATER_PRICE 0.1444
bool relayActive = false;
bool parkCarDisplayed = false;
BlynkTimer timer;
WidgetLCD lcd(vPIN_LVD);
// Use true to bypass RFID validation
#define TESTING_WITHOUT_RFID true
void displayLCD(uint8_t X1, uint8_t Y1, String msg1, uint8_t X2, uint8_t Y2, String msg2)
{
parkCarDisplayed = false;
lcd.clear(); //Use it to clear the LCD Widget
lcd.print(X1, Y1, msg1); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
lcd.print(X2, Y2, msg2);
}
BLYNK_CONNECTED()
{
displayLCD(0, 0, "Welcome to", 0, 1, "Bakers got Gas");
}
BLYNK_WRITE(vPIN_VALUE_5)
{
if ( param.asInt() )
{
pinValue10 = pinValue20 = pinValue50 = pinValueConfirm = false;
pinValue5 = true;
}
if (pinValue5 && !param.asInt())
{
Serial.println("Customer requests $5 gas");
displayLCD(0, 0, "5? Please park", 0, 1, "at pump. Confirm");
}
}
BLYNK_WRITE(vPIN_VALUE_10)
{
if ( param.asInt() )
{
pinValue5 = pinValue20 = pinValue50 = pinValueConfirm = false;
pinValue10 = true;
}
if (pinValue10 && !param.asInt())
{
Serial.println("Customer requests $10 gas");
displayLCD(0, 0, "10? Please park", 0, 1, "at pump. Confirm");
}
}
BLYNK_WRITE(vPIN_VALUE_20)
{
if ( param.asInt() )
{
pinValue5 = pinValue10 = pinValue50 = pinValueConfirm = false;
pinValue20 = true;
}
if (pinValue20 && !param.asInt())
{
Serial.println("Customer requests $20 gas");
displayLCD(0, 0, "20? Please park", 0, 1, "at pump. Confirm");
}
}
BLYNK_WRITE(vPIN_VALUE_50)
{
if ( param.asInt() )
{
pinValue5 = pinValue10 = pinValue20 = pinValueConfirm = false;
pinValue50 = true;
}
if (pinValue50 && !param.asInt())
{
Serial.println("Customer requests $50 gas");
displayLCD(0, 0, "50? Please park", 0, 1, "at pump. Confirm");
}
}
BLYNK_WRITE(vPIN_CONFIRM)
{
if ( param.asInt() && (pinValue5 || pinValue10 || pinValue20 || pinValue50) )
pinValueConfirm = true;
if (pinValueConfirm && !param.asInt())
{
Serial.println("Purchase Confirmed");
}
}
void checkRFID()
{
if ( ! rfid.PICC_IsNewCardPresent())
return;
Serial.println();
flag = true;
Serial.println("Flag OK");
// Verify if the NUID has been readed
if ( ! rfid.PICC_ReadCardSerial())
return;
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.println(rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K)
{
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
if (rfid.uid.uidByte[0] != nuidPICC[0] ||
rfid.uid.uidByte[1] != nuidPICC[1] ||
rfid.uid.uidByte[2] != nuidPICC[2] ||
rfid.uid.uidByte[3] != nuidPICC[3] )
{
Serial.println(F("A new card has been detected."));
// Store NUID into nuidPICC array
for (byte i = 0; i < 4; i++)
{
nuidPICC[i] = rfid.uid.uidByte[i];
}
Serial.println(F("The NUID tag is:"));
Serial.print(F("In hex: "));
printHex(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
Serial.print(F("In dec: "));
printDec(rfid.uid.uidByte, rfid.uid.size);
}
else Serial.println(F("Card read previously."));
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
}
void clickRelay(int relayPin, uint32_t timeout)
{
static int pinRelay = relayPin;
digitalWrite(pinRelay, HIGH);
timer.setTimeout(timeout, []()
{
digitalWrite(pinRelay, LOW);
relayActive = false;
Serial.println("Stop pumping gas");
displayLCD(0, 0, "Welcome to", 0, 1, "Bakers got Gas");
});
}
void pumpControl()
{
if (!relayActive )
{
#if TESTING_WITHOUT_RFID
flag = true;
#endif
if (flag && pinValue5 && pinValueConfirm)
{
pinValue5 = pinValueConfirm = false;
relayActive = true;
clickRelay(D0, 5000);
flag = false;
displayLCD(0, 0, "Dispense $5", 0, 1, "worth of gas");
Serial.println("Dispense $5 worth of gas");
}
else if (flag && pinValue10 && pinValueConfirm)
{
pinValue10 = pinValueConfirm = false;
relayActive = true;
clickRelay(D0, 7500);
flag = false;
displayLCD(0, 0, "Dispense $10", 0, 1, "worth of gas");
Serial.println("Dispense $10 worth of gas");
}
else if (flag && pinValue20 && pinValueConfirm)
{
pinValue20 = pinValueConfirm = false;
relayActive = true;
clickRelay(D0, 10000);
flag = false;
displayLCD(0, 0, "Dispense $20", 0, 1, "worth of gas");
Serial.println("Dispense $20 worth of gas");
}
else if (flag && pinValue50 && pinValueConfirm)
{
pinValue50 = pinValueConfirm = false;
relayActive = true;
clickRelay(D0, 12000);
flag = false;
displayLCD(0, 0, "Dispense $50", 0, 1, "worth of gas");
Serial.println("Dispense $50 worth of gas");
}
else if ( !parkCarDisplayed && pinValueConfirm && (pinValue5 || pinValue10 || pinValue20 || pinValue50 ) )
{
displayLCD(0, 0, "Park car on", 0, 1, "marked location");
parkCarDisplayed = true;
}
}
}
void printHex(byte *buffer, byte bufferSize)
{
for (byte i = 0; i < bufferSize; i++)
{
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/**
Helper routine to dump a byte array as dec values to Serial.
*/
void printDec(byte *buffer, byte bufferSize)
{
for (byte i = 0; i < bufferSize; i++)
{
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], DEC);
}
}
void ICACHE_RAM_ATTR pulseCounter()
{
pulseCount++;
}
void flowSensor()
{
noInterrupts();
flowRate = pulseCount / FLOW_CALIBRATION;
pulseCount = 0;
interrupts();
//calc totals
flowLitres = (flowRate / 60);
totalLitres += flowLitres;
totalLitres_month += flowLitres;
Blynk.virtualWrite(vPIN_WATER_TOTAL, (float) totalLitres);
Blynk.virtualWrite(vPIN_WATER_FLOW, String((float) flowLitres, 0));
Blynk.virtualWrite(vPIN_WATER_TOTAL_MONTH, (float) totalLitres_month);
waterCost = waterCost + ( ( ( (float) flowLitres ) * WATER_PRICE ) / 100);
Blynk.virtualWrite(vPIN_WATER_COST, String(waterCost, 6));
waterCost_month = waterCost_month + ( ( ( (float) flowLitres ) * WATER_PRICE ) / 100);
Blynk.virtualWrite(vPIN_WATER_COST_MONTH, String(waterCost_month, 6));
}
void setup()
{
pinMode(D0, OUTPUT);
Serial.begin(115200);
//Flow Rate
pulseCount = 0;
flowRate = 0.0;
flowLitres = 0;
totalLitres = 0;
//RFID
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
for (byte i = 0; i < 6; i++)
{
key.keyByte[i] = 0xFF;
}
Serial.println(F("This code scan the MIFARE Classsic NUID."));
Serial.print(F("Using the following key:"));
printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
#if USE_BLYNK_WM
Blynk.begin("RFIC_System");
#else
Blynk.begin(auth, ssid, pass);
#endif
timer.setInterval(100L, checkRFID);
timer.setInterval(500L, pumpControl);
timer.setInterval(5000L, flowSensor);
attachInterrupt(FLOW_SENSOR, pulseCounter, FALLING);
}
void loop()
{
Blynk.run();
timer.run();
}
and the terminal output of a test using Blynk_WM library library
217] Calc Cksum = 0x2ea9, Read Cksum = 0x2ea9
[219] Header = ESP8266, Board Name = RFID-Gas
[223] SSID = ****, PW =****
[226] SSID1 = ****, PW1 = ****
[230] Server = ****.duckdns.org, Token = ****
[236] Server1 = 192.168.2.110, Token1 = ****
[243] Port = 8080
[244] Connecting MultiWifi...
[4602] WiFi connected after time: 1
[4602] SSID: ****, RSSI = -36
[4602] Channel: 10, IP address: 192.168.2.46
[4602] bg: WiFi connected. Try Blynk
[4604]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ v0.6.1 on NodeMCU
[4617] BlynkArduinoClient.connect: Connecting to ****.duckdns.org:8080
[4646] Ready (ping: 5ms).
[4914] Connected to Blynk Server = ****.duckdns.org, Token = ****
[4914] bg: WiFi+Blynk connected
Customer requests $5 gas
Customer requests $10 gas
Purchase Confirmed
Dispense $10 worth of gas
Stop pumping gas
Customer requests $50 gas
Purchase Confirmed
Dispense $50 worth of gas
Stop pumping gas
Customer requests $5 gas
Customer requests $10 gas
Customer requests $10 gas
Customer requests $20 gas
Customer requests $50 gas
Customer requests $50 gas
Customer requests $10 gas
Customer requests $10 gas
Purchase Confirmed
Dispense $10 worth of gas
Stop pumping gas
We’re here as volunteers, and are not interested in compensation. If we have to live by that, it might be very high to pay.