RESET COUNTED PULSE WITH BLUETOOTH COMMAND WORK IN STRANGE WAY

Hi,

I made small project with Arduino UNO for my outboard engine TOHATSU 50 2t.
I installed flow sensor (turbine) with Hall effect to measure gasoline flow (consumption) in real time.
Arduino gets the pulses and calculate them into consumed liters, and liters per hour.
Then that information consumed liters and L/h calculated by Arduino are sent via Bluetooth serial communication to my android smart phone that has custom made application made with MIT APP.
In app I put RESET button that should reset counted consumed liters to zero when I press it.
When I power up Arduino, start measuring the consumption, press the reset button on my phone, nothing happen.
But if I press reset button on Arduino (power is always on!), than RESET button start to work.
Can somebody check my code and tell my how to avoid this.
I want that RESET works when Arduino is powered on, I don’t want to press reset button to make it work because Arduino will be installed under engine hood, and it’s not so easy to press the reset on Arduino board.
I’m not great expert in coding and maybe you will find my code chaotic but it works (partially) believe me.
If you have suggestions how to polish it and make it more professional, feel free to shear it.

volatile int PulseCount;
volatile float FlowPulse; //measuring the rising edges of the signal
volatile float RpmPulse; //measuring the rising edges of the signal
float Calc; 
float RPMs;                              
float flowsensor = 2; //The pin location of the sensor
float taho = 3;
int incomingByte;

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
   attachInterrupt(1, rps, RISING); //and the interrupt is attached
}

void loop() {

 if (Serial.available() > 0) {
 incomingByte = Serial.read();
 if (incomingByte == 'R') {
 PulseCount = 0;
 }
 }
 FlowPulse = 0;      //Set NbTops to 0 ready for calculations
 RpmPulse = 0;
 sei();            //Enables interrupts
 delay (4000);      //Wait 4 second
 cli();            //Disable interrupts
 Calc = (FlowPulse * 60 / 127 ); //(Pulse frequency x 60) /30 Q, = 1900/60 * 4 (četri sekundi interval se svodi na 1 sek) flow rate in L/hour 
 RPMs = (RpmPulse * 10 / 4); // 4 sekundni impulsi sa 6 polnog alternatora svedeni sa 1 sekundu 
 PulseCount = PulseCount++;
 Serial.print(PulseCount);
 Serial.print(",");
 Serial.print(Calc); //Prints the number calculated above
 Serial.print(",");
 Serial.print(Calc / incomingByte); //Prints the number calculated above
 Serial.print(",");
 Serial.print(RPMs);
 Serial.println();
}

void rpm ()     //This is the function that the interupt calls 

{ 
  FlowPulse++;  //This function measures the rising and falling edge of the hall effect sensors signal
  PulseCount++;
} 

void rps ()
{ 
  RpmPulse++;  

}
PulseCount = PulseCount++;

No, never do this. It is undefined. It does different things based on which compiler you use.

Use:

PulseCount++;

OR:

PulseCount = PulseCount + 1;

But never mix = and ++ on the same variable.

Serial.print(Calc / incomingByte); //Prints the number calculated above

If you haven't received anything yet then that is a divide by zero.

Get all the undefined stuff out of your code. It isn't worth working on when there are things in there that nobody knows that they do.

PulseCount = PulseCount++ works fine in application, it summarize pulses counted in one loop cycle that last 4 seconds.
That way I count all pulses from time I power my Arduino, and that represent total liters consumed.
If I use only PulseCount++; it will only calculate actual pulses from 4 sec cycle and not sum of all pulses.

Incoming byte should be GPS speed sent from android phone to Arduino.
It doesn’t work so well, but the idea was to get specific consumption in liters per nautical mile.
Arduino calculate liters per hour „calc“ and divide it with MPH that receives from Android APP.
Usually when GPS is not locked and APP doesn’t trigger the speed and 0 is sent to Arduino, result is infinity.

What about reset?
It should reset total liter pulses when it receives incoming Byte „R“ when I press reset button in application.
Instead it works only if I first press reset button on Arduino board and then start counting liters pulses. After that it works fine. Why?

What about reset?
It should reset total liter pulses when it receives incoming Byte „R" when I press reset button in application.
Instead it works only if I first press reset button on Arduino board and then start counting liters pulses. After that it works fine. Why?

Is the blinking light on the HC05 indicating connected status before you press the reset button on the Arduino?
If not, does it show connected after you push it?

PulseCount = PulseCount++ works fine in application, it summarize pulses counted in one loop cycle that last 4 seconds.
That way I count all pulses from time I power my Arduino, and that represent total liters consumed.
If I use only PulseCount++; it will only calculate actual pulses from 4 sec cycle and not sum of all pulses.

If you change compilers or Arduino versions the behavior is subject to change. It may work for you now by accident, but you should fix it. Figure out what it is actually doing. If plain ++ doesn't work the same then I don't know what it does. It is UNDEFINED in C and C++ so it can do anything from work normally to completely crash your program to causing demons to fly out from your nose and it will be working perfectly.

And when you have lines that create undefined behavior in your code, then whatever it does it exactly the right thing. You can't control it. So there is absolutely no use in trying to fix it until you write lines where we can KNOW what effect they will have.

That undefined behavior can even affect other seemingly unrelated parts of the code. So it may be that if you fix that line then other things that are broken now will start working. It may be that the rest of the code is right and it is that line that is messing them up. That's how it is with undefined behavior.

cattledog:
Is the blinking light on the HC05 indicating connected status before you press the reset button on the Arduino?
If not, does it show connected after you push it?

Yes! Bluetooth communication is working, otherwise I would not receive any data on my phone.
Also, after I push reset button on Arduino board Bluetooth communication stays connected.

First, fix the undefined behavior issue that Delta G talks about.

Yes! Bluetooth communication is working, otherwise I would not receive any data on my phone.

Are you saying that while the phone is receiving data normally, you try to send a command to the bluetooth module, but it appears not to be received until the hardware rest button is pressed on the Arduino?

cattledog:
First, fix the undefined behavior issue that Delta G talks about.

Are you saying that while the phone is receiving data normally, you try to send a command to the bluetooth module, but it appears not to be received until the hardware rest button is pressed on the Arduino?

Correct!
Only when I press reset on Arduino board things start to work as they should be.
Arduino receive incomingByte „R“ and reset counter to zero.
I fixed error in the code, I removed undefined part "PulseCount = PulseCount++;", but still same problem with reset.

I’m just beginner at coding so I didn’t know that it can work without it.
I’m more like copy/paste/modify little bit and let Arduino compiler check for errors.
That is my programming skill level 

volatile int PulseCount;
volatile float FlowPulse; //measuring the rising edges of the signal
volatile float RpmPulse; //measuring the rising edges of the signal
float Calc; 
float RPMs;                              
float flowsensor = 2; //The pin location of the sensor
float taho = 3;
int incomingByte;

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
   attachInterrupt(1, rps, RISING); //and the interrupt is attached
}

void loop() {

 if (Serial.available() > 0) {
 incomingByte = Serial.read();
 if (incomingByte == 'R') {
 PulseCount = 0;
 }
 }
 FlowPulse = 0;      //Set NbTops to 0 ready for calculations
 RpmPulse = 0;
 sei();            //Enables interrupts
 delay (4000);      //Wait 4 second
 cli();            //Disable interrupts
 Calc = (FlowPulse * 60 / 127 ); //(Pulse frequency x 60) /30 Q, = 1900/60 * 4 (četri sekundi interval se svodi na 1 sek) flow rate in L/hour 
 RPMs = (RpmPulse * 10 / 4); // 4 sekundni impulsi sa 6 polnog alternatora svedeni sa 1 sekundu 
 Serial.print(PulseCount);
 Serial.print(",");
 Serial.print(Calc); //Prints the number calculated above
 Serial.print(",");
 Serial.print(Calc / incomingByte); //Prints the number calculated above
 Serial.print(",");
 Serial.print(RPMs);
 Serial.println();
}

void rpm ()     //This is the function that the interupt calls 

{ 
  FlowPulse++;  
  PulseCount++;
} 

void rps ()
{ 
  RpmPulse++;  
}

Here is the video link how it works

Thank you for the video. It is a very clear demonstration of the problem.

Which Arduino are you using, and what is the shield attached to it?

It appears that you are plugging the Arduino into a laptop for usb power. Your code indicates that you are using hardware serial for the bluetooth communication.

If you disconnect the bluetooth module, and communicate to the arduino with the serial monitor to send the 'R' do the values reset, or is the hardware reset still required? This might give us a clue.

I'm very unsure about what is going on.

What line ending are you using for the phone transmission?

cattledog:
Thank you for the video. It is a very clear demonstration of the problem.

Which Arduino are you using, and what is the shield attached to it?

It appears that you are plugging the Arduino into a laptop for usb power. Your code indicates that you are using hardware serial for the bluetooth communication.

If you disconnect the bluetooth module, and communicate to the arduino with the serial monitor to send the 'R' do the values reset, or is the hardware reset still required? This might give us a clue.

I'm very unsure about what is going on.

What line ending are you using for the phone transmission?

I use Arduino uno board. Shield is bluetooth plus step down voltage regulator.
The reset start to function only when I manualy reset arduino. After that it works remotely by phone. Watch video again!
It looks like bluetooth must be connected before program start to work.
Im not at home so I cant test serial reset, I will try it later.

Later...
I tried what you suggest, I started Program, spin few pulses, detach Bluetooth shield and send byte R from serial monitor on my PC.
It works, it reset the counter without first resetting Arduino.
Probably problem is somewhere on app side, I will try on MIT App forum.
Thanks for suggestions and help.

It looks like bluetooth must be connected before program start to work.

Have you got rid of the undefined behavior yet? You can't really say what it should or should not do as long as that is there.

Delta_G:
Have you got rid of the undefined behavior yet? You can't really say what it should or should not do as long as that is there.

Yes I did!
See the code.

volatile int PulseCount;
volatile float FlowPulse; //measuring the rising edges of the signal
volatile float RpmPulse; //measuring the rising edges of the signal
float Calc; 
float RPMs;                              
float flowsensor = 2; //The pin location of the sensor
float taho = 3;
int incomingByte;

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
 attachInterrupt(1, rps, RISING); //and the interrupt is attached
}

void loop() {

if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte == 'R') {
PulseCount = 0;
}
}
FlowPulse = 0;      //Set NbTops to 0 ready for calculations
RpmPulse = 0;
sei();            //Enables interrupts
delay (4000);      //Wait 4 second
cli();            //Disable interrupts
Calc = (FlowPulse * 60 / 127 ); //(Pulse frequency x 60) /30 Q, = 1900/60 * 4 (četri sekundi interval se svodi na 1 sek) flow rate in L/hour 
RPMs = (RpmPulse * 10 / 4); // 4 sekundni impulsi sa 6 polnog alternatora svedeni sa 1 sekundu 
Serial.print(PulseCount);
Serial.print(",");
Serial.print(Calc); //Prints the number calculated above
Serial.print(",");
Serial.print(Calc / incomingByte); //Prints the number calculated above
Serial.print(",");
Serial.print(RPMs);
Serial.println();
}

void rpm ()     //This is the function that the interupt calls 

{ 
FlowPulse++;  
PulseCount++;
} 

void rps ()
{ 
RpmPulse++;  
}

Code tags. Please. That's really hard to read. Please formatnit and use code tags. If you don't know what that is then read the forum instructions. You should have done that to begin with.

Delta_G:
Code tags. Please. That's really hard to read. Please formatnit and use code tags. If you don't know what that is then read the forum instructions. You should have done that to begin with.

Better?

Another problem is that you use cli() then do a lot of serial printing. Serial needs interrupts to work. Your method of allowing interrupts only during the delay is backwards. Normally you would allow interrupts all the time and only turn them off long enough to make copies of the volatile variables.

Later...
I tried what you suggest, I started Program, spin few pulses, detach Bluetooth shield and send byte R from serial monitor on my PC.
It works, it reset the counter without first resetting Arduino.
Probably problem is somewhere on app side, I will try on MIT App forum.
Thanks for suggestions and help.

I just noticed this addition to an earlier post. Once you sort out the app/bluetooth situation it would be wise to completely revise you code as Delta G suggest. The format you are using which enables interrupts for a delay() period is one of the worst pieces of code floating around the internet. The flow rate code should looks something like this

volatile unsigned long  count = 0;
unsigned long copyCount = 0;

unsigned long lastRead = 0;
unsigned long interval = 1000;//one second

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  
  pinMode(2,INPUT_PULLUP);
  attachInterrupt(0, isrCount, RISING); //interrupt signal to pin 2
}

void loop()
{
  if (millis() - lastRead >= interval) //read interrupt count every second
  {
    lastRead  += interval;
    // disable interrupts,make copy of count,reenable interrupts
    noInterrupts();
    copyCount = count;
    count = 0;
    interrupts();
 
    Serial.println(copyCount);

  }
}

void isrCount()
{
  count++;
}

This is too advance for my programming skills!
I tried to invert cli() and sei() lines, result was catastrophe.
Serial print went crazy!

This is too advance for my programming skills!

Nonsense. If you can figure out how to create a complicated Android app with MIT App Inventor, you can figure out how to write correct interrupt based c++ code.