Milis() function can't work properly

Please help me, I run 2 milis() functions for telegram and Water flow sensor. when I running the program, the water calculation becomes problematic. But Telegram can run. Can the milis() function run simultaneously in one program?

BlynkTimer timer;

char ssid[] = " ?"; // Sesuikan dengan nama wifi anda
char pass[] = ""; // sesuaikan password wifi
// Inisialisasi Telegram BOT
#define BOTtoken "" // token bot telegram yang telah dibuat
#define SENSOR 2 //SENSOR WATERFLOW

//SENSOR CALCULATE
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
boolean ledState = LOW;
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned long flowMilliLitres;
unsigned int totalMilliLitres;
float flowLitres;
float totalLitres;

//RELAY
int relay = 12;
int pinValue1, pinValue2, pinValue3;

int batas = 1;

void IRAM_ATTR pulseCounter()
{
pulseCount++;
}

void (* resetFunc) (void) =0; //reset

//pin virtual blynk
BLYNK_WRITE(V1) //TAMBAH VOLUME
{
pinValue1 = param.asInt();

if(pinValue1 == 1){
batas++;
}

if(pinValue1 == 0) {

}

}

BLYNK_WRITE(V2)//KURANGI VOLUME
{
pinValue2 = param.asInt();

if(pinValue2 == 1){
batas--;
}

if(pinValue2 == 0) {

}

}

BLYNK_WRITE (V5) // Reset
{
if (param.asInt()==1) {
resetFunc();
delay(5000);
}
}
void kirimdata()
{
String debit = String (flowRate, 2);
String volume = String(totalLitres, 2);
Blynk.virtualWrite(V0, String (volume));
Blynk.virtualWrite(V3, batas);
Blynk.virtualWrite(V4, String (debit));
}

//Telegram
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
int botRequestDelay = 1000;
unsigned long lastTimeBotRan;

void handleNewMessages(int numNewMessages) {
Serial.println("handleNewMessages");
Serial.println(String(numNewMessages));

for (int i=0; i<numNewMessages; i++) {
String chat_id = String(bot.messages[i].chat_id);
String text = bot.messages[i].text;

String from_name = bot.messages[i].from_name;
if (from_name == "") from_name = "Guest";

if (text == "/CEK") {
String volume = String(totalLitres, 2);
String temp = "V : ";
temp += String (volume);
temp +=" L";
bot.sendMessage(chat_id,temp, "");
}
if (text == "/FlowOn") {
digitalWrite(relay, LOW);
bot.sendMessage(chat_id, "Aliran air sudah diaktifkan", "");
}
if (text == "/FlowOff") {
digitalWrite(relay, HIGH);
bot.sendMessage(chat_id, "Aliran air sudah dinonaktifkan", "");
}

//Cek Command untuk setiap aksi
if (text == "/start") {
  String welcome = "Welcome  " + from_name + ".\n";
  welcome += "/CEK : PERIKSA VOLUME \n";
  welcome += "/FlowOn : Nyalakan Water Flow \n";
  welcome += "/FlowOff : Matikan Water Flow\n";
  bot.sendMessage(chat_id, welcome, "Markdown");
}

}
}
void setup() {
lcd.begin();
lcd.clear();
lcd.backlight();
lcd.setCursor(0,0); //lcd
lcd.print("Water Flow Meter");
lcd.setCursor(0,1);
lcd.print("NIM: 18410300323");
delay(3000);
lcd.clear();

//blynk auth
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
timer.setInterval(1000L, kirimdata);

//relay dan sensor
pinMode(relay, OUTPUT);
pinMode(SENSOR, INPUT_PULLUP);
digitalWrite(relay, LOW);
Serial.begin(115200);

client.setInsecure();

// Seting NodeMCU pada mode WiFi to station dari akses point yang dikoneksikan
//
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);

// Menampilkan proses koneksi
Serial.print("Connecting Wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
lcd.print("Connecting...");

while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);

}

Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Connected");
lcd.setCursor(0,1);
lcd.print(WiFi.localIP());
delay(500);

Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

lcd.clear();
lcd.setCursor(0,0);
lcd.print("Connected");
lcd.setCursor(0,1);
lcd.print(WiFi.localIP());
delay(500);

//WATERFLOW
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
previousMillis = 0;

attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING);
}
void loop() {
//PERHITUNGAN WATERFLOW

currentMillis = millis();
if (currentMillis - previousMillis > interval)
{

pulse1Sec = pulseCount;
pulseCount = 0;

// 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() - previousMillis)) * pulse1Sec) / calibrationFactor;
previousMillis = millis();

// Divide the flow rate in litres/minute by 60 to determine how many litres have
// passed through the sensor in this 1 second interval, then multiply by 1000 to
// convert to millilitres.
flowMilliLitres = (flowRate / 60) * 1000;
flowLitres = (flowRate / 60);

// Add the millilitres passed in this second to the cumulative total
totalMilliLitres += flowMilliLitres;
totalLitres += flowLitres;

// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(flowRate);  // Print the integer part of the variable
Serial.print("L/min");
Serial.print("\t");       // Print tab space

}

if (millis() > lastTimeBotRan + botRequestDelay) {
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

while(numNewMessages) {
  Serial.println("got response");
  handleNewMessages(numNewMessages);
  numNewMessages = bot.getUpdates(bot.last_message_received + 1);
}

lastTimeBotRan = millis();

}
lcd.setCursor(0,0);
//lcd.print("L/min: ");
//lcd.print(flowRate);
lcd.print("Batas: ");
lcd.print(batas);
lcd.print(" L ");

lcd.setCursor(0,1);
lcd.print("Total: ");
lcd.print(totalLitres);
lcd.print(" L ");

//logika solenoid
if(totalLitres > batas){
Blynk.logEvent("air_maksimal");
Serial.print("AIR MAKSIMAL");

digitalWrite(relay,HIGH);

}else{
digitalWrite(relay, LOW);
}
Blynk.run();
timer.run(); // Initiates BlynkTimer

}

You never said what the problem actually was. "the water calculation becomes problematic" tells no one anything. A precise description of what goes wrong is required.

And that blob of unformatted code is pretty much unreadable. Use the <CODE/> formatting tool.

I will say that using signed longs to store returns from millis() is just asking for trouble in the long run. And the snippet below is problematic as well.

Let's begin again, shall we? Please fix your code presentation, and tell us exactly what the problem is.

And I'd say to take your Telegram credentials out, but that ship has sailed. The whole world has them now.

1 Like

@evansyah33 Welcome to the forum!

Please open your sketch in the IDE, and then use the following three keyboard shortcuts:

  1. Ctrl+A
  2. Ctrl+T
  3. Ctrl+Shift+C

Next, open a response in this thread, and use the following shortcut:

Ctrl+V

Finally, click the ⮪ Reply button.

1 Like

Wrap that code in a code block...

Ensure also that any code you present here is complete. At least the library include statements appear to be missing.

1 Like

Swap lines 22-44 with lines 56-78. Hmmmmmm! that may not match your line numbers oh well it takes to long to read the forum guidelines so you can get an accurate answer. For additional help, check out useful links and tutorials: Useful Links on Arduino Forum.

#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID ""
#define BLYNK_TEMPLATE_NAME "Flow Sensor"
#define BLYNK_AUTH_TOKEN ""


#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <SPI.h>
#include <Wire.h>
#include <BlynkSimpleEsp8266.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); 

BlynkTimer timer;

char ssid[] = "Nyari Apa ?";     // Sesuikan dengan nama wifi anda
char pass[] = "Pahala33"; // sesuaikan password wifi
// Inisialisasi Telegram BOT
#define BOTtoken  "" // token bot telegram yang telah dibuat
#define SENSOR 2 //SENSOR WATERFLOW

//SENSOR CALCULATE
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
boolean ledState = LOW;
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned long flowMilliLitres;
unsigned int totalMilliLitres;
float flowLitres;
float totalLitres;

//RELAY
int relay = 12;
int pinValue1, pinValue2, pinValue3;

int batas = 1;


void IRAM_ATTR pulseCounter()
{
  pulseCount++;
}

void (* resetFunc) (void) =0; //reset

//pin virtual blynk
BLYNK_WRITE(V1) //TAMBAH VOLUME
{
  pinValue1 = param.asInt();   

  if(pinValue1 == 1){
   batas++;
  }
  
  if(pinValue1 == 0) {
 
  }
  
}

BLYNK_WRITE(V2)//KURANGI VOLUME
{
  pinValue2 = param.asInt();   

  if(pinValue2 == 1){
   batas--;
  }
  
  if(pinValue2 == 0) {
 
  }
  
}

BLYNK_WRITE (V5) // Reset
{
if (param.asInt()==1) {
resetFunc();
delay(5000);
}
}
void kirimdata()
{
  String debit = String (flowRate, 2);
  String volume = String(totalLitres, 2);
  Blynk.virtualWrite(V0, String (volume));
  Blynk.virtualWrite(V3, batas);
  Blynk.virtualWrite(V4, String (debit));
}



//Telegram
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
int botRequestDelay = 1000;
unsigned long lastTimeBotRan;

void handleNewMessages(int numNewMessages) {
  Serial.println("handleNewMessages");
  Serial.println(String(numNewMessages));

  for (int i=0; i<numNewMessages; i++) {
    String chat_id = String(bot.messages[i].chat_id);
    String text = bot.messages[i].text;

    String from_name = bot.messages[i].from_name;
    if (from_name == "") from_name = "Guest";
if (text == "/CEK") {
    String volume = String(totalLitres, 2);
    String temp = "V : ";
       temp += String (volume);
       temp +=" L";
      bot.sendMessage(chat_id,temp, "");
    }
if (text == "/FlowOn") {
      digitalWrite(relay, LOW);
      bot.sendMessage(chat_id, "Aliran air sudah diaktifkan", "");
    }
     if (text == "/FlowOff") {
      digitalWrite(relay, HIGH);
      bot.sendMessage(chat_id, "Aliran air sudah dinonaktifkan", "");
    }
    
     
    //Cek Command untuk setiap aksi
    if (text == "/start") {
      String welcome = "Welcome  " + from_name + ".\n";
      welcome += "/CEK : PERIKSA VOLUME \n";
      welcome += "/FlowOn : Nyalakan Water Flow \n";
      welcome += "/FlowOff : Matikan Water Flow\n";
      bot.sendMessage(chat_id, welcome, "Markdown");
    }
  }
}
void setup() {
lcd.begin();
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0,0);  //lcd
  lcd.print("Water Flow Meter");
  lcd.setCursor(0,1);
  lcd.print("NIM: 18410300323");
  delay(3000);
  lcd.clear();
  
 //blynk auth
 Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
 timer.setInterval(1000L, kirimdata);

  //relay dan sensor
  pinMode(relay, OUTPUT);
  pinMode(SENSOR, INPUT_PULLUP);
  digitalWrite(relay, LOW);
  Serial.begin(115200);

  client.setInsecure();

  // Seting NodeMCU pada mode WiFi to station dari akses point yang dikoneksikan
  // 
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  // Menampilkan proses koneksi
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  lcd.print("Connecting...");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);

  
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Connected");
  lcd.setCursor(0,1);
  lcd.print(WiFi.localIP());
  delay(500);

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Connected");
  lcd.setCursor(0,1);
  lcd.print(WiFi.localIP());
  delay(500);

  //WATERFLOW
  pulseCount = 0;
  flowRate = 0.0;
  flowMilliLitres = 0;
  totalMilliLitres = 0;
  previousMillis = 0;
 
  attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING);
  }
void loop() {
//PERHITUNGAN WATERFLOW

currentMillis = millis();
  if (currentMillis - previousMillis > interval) 
  {
    
    pulse1Sec = pulseCount;
    pulseCount = 0;
 
    // 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() - previousMillis)) * pulse1Sec) / calibrationFactor;
    previousMillis = millis();
 
    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    flowMilliLitres = (flowRate / 60) * 1000;
    flowLitres = (flowRate / 60);
 
    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitres += flowMilliLitres;
    totalLitres += flowLitres;
    
    // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(flowRate);  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space
  }


if (millis() > lastTimeBotRan + botRequestDelay)  {
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

    while(numNewMessages) {
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }

    lastTimeBotRan = millis();
  }
   lcd.setCursor(0,0);
   //lcd.print("L/min: ");
   //lcd.print(flowRate);
   lcd.print("Batas: ");
   lcd.print(batas);
   lcd.print(" L  ");
   
   lcd.setCursor(0,1);    
   lcd.print("Total: ");
   lcd.print(totalLitres);
   lcd.print(" L  ");

   //logika solenoid
   if(totalLitres > batas){  
    Blynk.logEvent("air_maksimal");
    Serial.print("AIR MAKSIMAL");
    
    digitalWrite(relay,HIGH);
  }else{
    digitalWrite(relay, LOW);
  }
  Blynk.run();
  timer.run(); // Initiates BlynkTimer

}

First of all I'm sorry and apologize to every one cause its my first time using Forum , an second I want to say thank you for your help . and now lets start begin for the trouble. I Just Using 2 function milis on waterflow sensor and Telegram messege respons. The flow sensor calculating wrong differently, but when i try to remove the Telegram Milis () replay , my calculating sensor just fine. IS that milis can affect to my calculating sensor if i'm not separated the function ?