Looking for assistance with Blynk project

I’m not exactly sure if this is allowed to be posted here, but anyways I’m wondering if anyone in here would be generous enough to help me complete my project in return for payment compensation. I’m designing and building app communication with NodeMCU, Arduino Mega 2560, RFID, Flow Rate sensor and a Relay / Water pump, where 4 payment options and a confirm are the Blynk Input buttons. I would say I have 75% of the coding completed and a general understanding of Blynk I just need some hands on help finalizing everything. I speak english but I could use whatever help I could get.

The community seems generous but I don’t want to feel like a burden continuously asking for free help. Please contact me if interested.

Maybe post what you got for code, explaining what you want and what’s not working… maybe someone will help you complete it yourself.

1 Like

Right now i’m having issues with my flow rate sensor, I would like it to be displaying my flow rate on w value display on Blynk. However when I upload my code it seems like my nodeMCU is turning off and on repeatedly.

The general idea for my recreational project is the simulation of autonomous car payment, where there are 4 input prices $5/10/20/50 as well as a confirm button. My code without the flowSensor function works however when I add it in it (seemingly) causes my nodeMCU to crash.

In my COM3 (nodeMCU) monitor it spams

18:23:14.142 ->    / _ )/ /_ _____  / /__
18:23:14.176 ->   / _  / / // / _ \/  '_/
18:23:14.209 ->  /____/_/\_, /_//_/_/\_\
18:23:14.243 ->         /___/ v0.6.1 on NodeMCU
18:23:14.276 -> 
18:23:14.276 -> [639] Connecting to blynk-cloud.com:80
18:23:14.309 -> [801] Ready (ping: 47ms).
18:23:14.579 -> ISR not in IRAM!
18:23:14.579 -> 
18:23:14.579 -> User exception (panic/abort/assert)
18:23:14.612 -> Abort called
18:23:14.646 -> 
18:23:14.646 -> >>>stack>>>
18:23:14.646 -> 
18:23:14.646 -> ctx: cont```


my full code is

#include <SPI.h>
#include <MFRC522.h>
constexpr uint8_t RST_PIN = 5;     // Configurable, see typical pin layout above
constexpr uint8_t 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
int pinValue0;
int pinValue1;
int pinValue2;
int pinValue3;
int pinValue4;
int flag;
int relay1;

//Flow Rate
int limitType, tap_limit_value, timer1, timer2, timer3, rowIndex = 0, month_old;
volatile byte pulseCount = 0;
float flowRate = 0.00, waterCost, waterCost_month;
float flowMilliLitres;
float totalMilliLitres, totalMilliLitres_month;
#define vPIN_TABLE                V1
#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

//Blynk
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
char auth[] = "g-zo8C8skr7RglPQneF7IlGRWVKscg2w";
char ssid[] = "75fennellwest";
char pass[] = "fennellhouse75";
BlynkTimer timer;
WidgetLCD lcd(V5);

BLYNK_WRITE(V0){
   pinValue0 = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("Customer requests $5 gas: ");
  Serial.println(pinValue0);
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "5? Please park"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "at pump & Confirm");
}
BLYNK_WRITE(V1){
   pinValue1 = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("Customer requests $10 gas: ");
  Serial.println(pinValue1);
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "10? Please park"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "at pump & Confirm");
}
BLYNK_WRITE(V2){
   pinValue2 = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("Customer requests $20 gas: ");
  Serial.println(pinValue2);
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "20? Please park"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "at pump & Confirm");
}
BLYNK_WRITE(V3){
   pinValue3 = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("Customer requests $50 gas: ");
  Serial.println(pinValue3);
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "50? Please park"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "at pump & Confirm");
}
BLYNK_WRITE(V4){
   pinValue4 = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("Confirm Purchase: ");
  Serial.println(pinValue4);
}




void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "Welcome to"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "Bakers got Gas");
  timer.setInterval(1000L, checkRFID);
  timer.setInterval(1000L, relay);
  timer.setInterval(1000, flowSensor);
//  timer.setInterval(1000L, sendLCD);
//  timer.setInterval(1000L, flow);
  pinMode(D0, OUTPUT);


//Flow Rate
  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  attachInterrupt(FLOW_SENSOR, pulseCounter, FALLING);

//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);
}

void checkRFID()
{
    if ( ! rfid.PICC_IsNewCardPresent())
    return;
    Serial.println();
    flag = 1;
    Serial.println("Flag 1");
 
  // 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 relay(){
 if (pinValue0 == 1 && pinValue4 ==1 && flag ==1)
 {  
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(4, 0, ""); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(4, 1, "");
  digitalWrite(D0, HIGH); 
  delay(5000);
  digitalWrite(D0, LOW); 
  Serial.println("Dispense $5 worth of gas");
  flag = 0;
  Serial.println("flag = 0");
    lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, ""); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "");

 }
 else if ( pinValue1 == 1 && pinValue4 == 1 && flag == 1)
 {
    digitalWrite(D0, HIGH); 
  delay(7500);
  digitalWrite(D0, LOW); 
  Serial.println("Dispense $10 worth of gas");
  flag = 0;
 }
 else if ( pinValue2 == 1 && pinValue4 == 1 && flag == 1)
 {
    digitalWrite(D0, HIGH); 
  delay(10000);
  digitalWrite(D0, LOW); 
  Serial.println("Dispense $20 worth of gas");
  flag = 0;
 } 
 else if ( pinValue3 == 1 && pinValue4 == 1 && flag == 1)
 {
   digitalWrite(D0, HIGH); 
  delay(12000);
  digitalWrite(D0, LOW); 
  Serial.println("Dispense $50 worth of gas");
  flag = 0; 
 } 
 
 else  if (pinValue0 == 1 && pinValue4 ==1)
 {  
  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "Please park car"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "on marked location");
 }
 else if ( pinValue1 == 1 && pinValue4 == 1)
 {
    lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "Please park car"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "on marked location");
 }
 else if ( pinValue2 == 1 && pinValue4 == 1)
 {
    lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "Please park car"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "on marked location");
 }
 else if ( pinValue3 == 1 && pinValue4 == 1)
 {
    lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "Please park car"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
  lcd.print(0, 1, "on marked location");
 }
}

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 pulseCounter() {
  pulseCount++;
}

void flowSensor() {
  detachInterrupt(FLOW_SENSOR);
  flowRate = pulseCount / FLOW_CALIBRATION;
  pulseCount = 0;
  attachInterrupt(FLOW_SENSOR, pulseCounter, FALLING);
  //calc totals
  flowMilliLitres = (flowRate / 60) * 1000;
  totalMilliLitres += flowMilliLitres;
  totalMilliLitres_month += flowMilliLitres;
  Blynk.virtualWrite(vPIN_WATER_TOTAL, (float)totalMilliLitres / 1000);
  Blynk.virtualWrite(vPIN_WATER_FLOW,  String((float)flowMilliLitres, 0));
  Blynk.virtualWrite(vPIN_WATER_TOTAL_MONTH, (float)totalMilliLitres_month / 1000);
  waterCost = waterCost + ( ( ( (float)flowMilliLitres / 1000 ) * WATER_PRICE ) / 100);
  Blynk.virtualWrite(vPIN_WATER_COST, String(waterCost, 6));
  waterCost_month = waterCost_month + ( ( ( (float)flowMilliLitres / 1000 ) * WATER_PRICE ) / 100);
  Blynk.virtualWrite(vPIN_WATER_COST_MONTH, String(waterCost_month, 6));
} 


void loop()
{
  Blynk.run();
  timer.run();
}```

This error message is caused because you don’t have the ICACHE_RAM_ATTR attribute in the name of your interrupt service routine (ISR) function. So your pulseCounter ISR name should look like this:

void ICACHE_RAM_ATTR pulseCounter()

When you do this, you’ll probably find that you get a compiler error message that says something like "pulseCounter was not declared in this scope. You fix this by moving your pulseCounter IRS above your void setup in your sketch.

As you now have three reasonably active topics that are all about the same project, I’m going to lock this topic and one other, and ask that all future posts are made in the following topic…

Pete.