RESET COUNTED PULSE WITH BLUETOOTH COMMAND WORK IN STRANGE WAY

Delta_G:
You disable interrupts, make copies of the values into other variables, enable interrupts, and then do your calculations with the copies.

I figure that later after I finally get it in my minde what copy does.
Now its clear for me.

cattledog:
lastRead needs to be typed as unsigned long. It is overflowing after a few additions of the interval value. Only variables changed within the interrupt service routine (isr) need to be typed as volatile.

//volatile int lastRead = 0; 

unsigned long lastRead = 0;

Thanks, that helped!

Delta_G:
You never ever ever ever ever ever ever "need" a delay. You can ALWAYS do things think without a delay.

You'll have to time your printing Blink Without Delay style.

OK!
Cattledog help mi out with overflowing problem.
Now I use milis.

Why delay is so problematic?

Why delay is so problematic?

delay() is a 'blocking" function, and the Arduino can not do other things (except for interrupts) during a delay period. This means that input is blocked. For example in your original program, you could not respond to the 'R' input during the delay period.

You also can not do things at different rates like read a flow rate sensor every 4 seconds, and blink an indicator led every second when fluid is flowing, and run a servo to control a valve.

As your programs get more complex, writing non blocking code is essential. Some good references are the two "stickys"

Using millis for timing, a beginners guide

and

[Demonstration code for several things at the same time

](Demonstration code for several things at the same time - Project Guidance - Arduino Forum)

Hi,
I want to say thanks to all of you who helped me to resolve some bugs and problems in my project.
I learned a lot, how to use interrupts, copy, how to convert ASCII to string to volatile.
Now my app is working like I wanted.
Can’t wait to install it on my RIB outboard and test it on the sea.
It’s not problem to install it on outboard, its more problem to find time and good weather to go to sea.
If somebody needs code and app for similar application I’m willing to share it.
Once again, thanks!

String inString = "";
String copyinString;

volatile int PulseCount; // counts total pulses coming from tahometer
volatile float FlowPulse; // measuring the rising edges of the signal (flowmetter hall)
volatile float RpmPulse; // measuring the rising edges of the signal(alternator tahometer)

int copyPulseCount; // copy counts total pulses coming from tahometer
float copyFlowPulse; // copy measuring the rising edges of the signal (flowmetter hall)
float copyRpmPulse; // copy measuring the rising edges of the signal(alternator tahometer)

float Calc;  // Liters per hour calculation from FlowPulse
float copyCalc; // copy Calc
float RPMs; // RPMs calculated from RpmPulse 
float copyRPMs; // copy RPMs                       
float flowsensor = 2; // The pin location of the flowmeter sensor
float taho = 3;  //The pin location of the alternator tahometer
float LPM; // Liter Per Mile calulated from (L/h) / (miles/h)
int incomingByte; //serial Byte received from MIT APP (GPS speed or R for reset)

unsigned long lastRead = 0;
unsigned long interval = 4000; // 4 second period for counting impulses coming from the sensors

void setup() {
     
   pinMode(flowsensor, INPUT); // initializes digital pin 2 as an input
   pinMode(taho, INPUT); // initializes digital pin 3 as an input
   Serial.begin(9600);  // This is the setup function where the serial port is initialised
   attachInterrupt(0, rpm, RISING); // and the interrupt is attached (flowmetter hall)
   attachInterrupt(1, rps, RISING); // and the interrupt is attached (alternator tahometer)
}

void loop() {
 
 if (Serial.available() > 0) {
  incomingByte = Serial.read();
  if (incomingByte == 'R') {
  PulseCount = 0;
  }
 if (incomingByte != '\n') { // As long as the incoming byte is not a newline,
    inString += (char)incomingByte; //convert the incoming byte to a char and add it to the string
    }
    else {
    copyinString = inString; // copy the string
    inString = "";  // clear the string for new input:
    }
 }
 
 if (millis() - lastRead >= interval){ // read interrupt count every 4 (interval) seconds
 lastRead  += interval; //***
 
 noInterrupts(); // disable interrupts "cli();"
 copyPulseCount = PulseCount; 
 copyFlowPulse = FlowPulse;
 copyRpmPulse = RpmPulse; 
 FlowPulse = 0;      //Set flowmeter pulses to 0 ready for calculations
 RpmPulse = 0;      //Set alternator tahometer pulses to 0 ready for calculations
 interrupts(); // enable interrupts "sei();"

 Calc = (copyFlowPulse * 60 / 127 ); // recalculate flow in L/hour from 4 second FlowPulse 
 RPMs = (copyRpmPulse * 10 / 4); // recalculate 4 second 6 pole alternator-tachometer pulses to RPM-s
 LPM = (Calc / copyinString.toFloat()); // Liters per minute calculation Calc/GPS-speed (ASCII converted to Float)
 
 Serial.print(copyPulseCount); // send total pulses from flowmeter to app (in app they will be devided with 1900 to convert it to total liters)
 Serial.print(",");
 Serial.print(Calc); // send liters per hour to app
 Serial.print(",");
 if (LPM > 0){     // to avoid sending text like "inf" or similar to app
 Serial.print(LPM); // send liters per mile
 }
 else {
 Serial.print("WAIT"); // wait masage till GPS speed and LPH starts to triger
 }
 Serial.print(",");
 Serial.print(RPMs); // send RPMs to app
 Serial.println();  // end of line for app
  }
}

 void rpm ()     //This is the function that the interupt calls 
 { 
  FlowPulse++;  
  PulseCount++;
 } 

 void rps ()  //This is the function that the interupt calls 
 { 
  RpmPulse++;  
 }