Pump over filling

Hey,

sometimes (maybe once every 50 uses) when my code runs it will randomly fill more than my desired volume (pulse count)

I'm wondering if i could have issues with using interrupt in the while loop

any help would be appreciated

int flowSensorPin = 21; // define the pin number for the flow sensor (yellow)
int pumpPin = 53; // define the pin number for the pump (orange)

// Flow sensor variables
volatile unsigned int pulseCount = 0;

//timer settings
unsigned long startTime; // variable to store the start time of the timer
const unsigned long MAX_TIME_18 = 4000; // maximum time allowed for filling 18mL, in milliseconds

void setup() {
  Serial.begin(9600); // initialize the serial monitor
  pinMode(pumpPin, OUTPUT);
  digitalWrite(pumpPin, LOW);
  
  // Initialize flow sensor pin and interrupt
  pinMode(flowSensorPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(flowSensorPin), pulseCounter, FALLING);
 
void loop() {
  // 18 - if the coordinates are valid and within the button boundaries
  if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE && tp.x > R1 && tp.x < R2 && tp.y > C1 && tp.y < C2) {
    startTime = millis(); // store the start time of the timer
        
    // Reset pulse count
    pulseCount = 0;
    
    tft.setCursor(5, 50); // set the cursor position
    tft.setTextColor(textColour, backColour); // set the text color
    tft.println("FILLING 18mL"); // print the current weight text

    tft.setCursor(5, 80); // set the cursor position
    tft.setTextColor(textColour, backColour); // set the text color
    tft.println("              "); // print message on the screen

    // Activate the pump and start counting pulses
    digitalWrite(pumpPin, HIGH);

    while (pulseCount < 32) {
      Serial.print("Pulses: ");
      Serial.println(pulseCount);
      
      if (millis() - startTime >= MAX_TIME_18) { // check if the button is pressed and if the timer has exceeded the maximum time
      Serial.println("Fill time exceeded. Tank needs to be refilled.");
      tft.setCursor(5, 80); // set the cursor position
      tft.setTextColor(textColour, backColour); // set the text color
      tft.println("BOTTLE EMPTY"); // print message on the screen
      break; // stop the filling process
      }
    }
   
    // Deactivate the pump
    digitalWrite(pumpPin, LOW);
  }
}

// Interrupt function to count pulses
void pulseCounter() {
  pulseCount++;
}

Hi,
When it faults, does it just keep running, or does it eventually stop?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

What sort of motor is your pump, DC or AC?

Thanks... Tom.. :smiley: :+1: :coffee: :australia:

this can quick fill the com port buffer and stuck

If you mean once in every 50 restarts or power cycles or reboots, you may have an uninitiated variable.

Do you have compiler warnings cranked up in the IDE? They can be adjusted in the preferences and default to quiet.

Heed all warnings you get, seek to eliminate or totally understand why you mightn't have to worry about them. Really eliminate is best.

HTH

a7

I would change the variable pulseCount to byte, since you only count up to 32 and with a multi-byte variable (such as unsigned int) you really should be temporarily disabling interrupts when using outside the interrupt service routine.

1 Like

Is that the entire code that exhibits the problem? I see nowhere you are initializing a display or reading the touchscreen, but you are referencing both of those.

it eventually stops just overfills

12V DC pump

hope this is good enough (this is not the exact hardware i used but just photos i found online so you get the idea of how its setup)

thank you for this information - am i best to just remove this from my code unless i want to actually monitor it when i have a PC plugged in

system just stays on and sits there in idle till you want to pump was water, im guessing around once every 50 uses it would overfill

I dont, and ive just used the arduino IDE so far have thought about moving to visual studio code, can you tell me where i can do this in the arduino IDE or do i need to move to different software?

I will do other amounts of higher pulse counts but the code is the same just a different amount of pulses for more water I just didn't include the full code in my post

Ive looked into disabling interrupts with either:

interrupts ();
noInterrupts ();

OR
attachInterrupt();
detachInterrupt();

but not 100% sure where i would put them in my code

Yes, can be for any amount of water measured but i just put this snippet of the code as its exactly the same for other amount only thing that changes is the pulse count

I just didn't include the full code with touchscreen initializing etc...

    noInterrupts ();
    // Reset pulse count
    pulseCount = 0;
    interrupts ();
    noInterrupts ();
    int tempPulseCount = pulseCount;
    interrupts ();
    while (tempPulseCount < 32) {
      noInterrupts ();
      tempPulseCount = pulseCount;
      interrupts ();
      Serial.print("Pulses: ");
      Serial.println(tempPulseCount );
      
      if (millis() - startTime >= MAX_TIME_18) { // check if the button is pressed and if the timer has exceeded the maximum time
      Serial.println("Fill time exceeded. Tank needs to be refilled.");
      tft.setCursor(5, 80); // set the cursor position
      tft.setTextColor(textColour, backColour); // set the text color
      tft.println("BOTTLE EMPTY"); // print message on the screen
      break; // stop the filling process
      }
    }

Thanks @ToddL1962

this might sound stupid but can you explain to me why we need to have the tempPulseCount?

Not a stupid question. The Arduino UNO has an ATMega328p processor which is an 8-bit processor. One result of that is that if you have multibyte variables shared between ISR and non-ISR code then the update of those variables could be interrupted and cause them to be corrupted if care is not taken in the non-ISR code. One method is to disable interrupts, copy the multi-byte variable into a temp variable, then re-enable interrupts. You want to disable interrupts for as short a time as possible.

In the Arduino IDE select preferences…

To enable compiler warnings from within the Arduino IDE, open menu FilePreferences , and then tick Show verbose output during: compilation and/or Show verbose output during: upload

The warnings will be shown in red ink. I'm not sure it would have help here, but it's a Good Idea no matter.

a7

Hi,
Thanks for the image, but a proper schematic would have been better.

What are the electrical specs of the pump?
What are the specs of the power supply?
Links to both would be helpful.

Changing your baud rate to 115200, would also help your monitor update.

Tom.. :smiley: :+1: :coffee: :australia:

We really need to see the entire code.

Thanks for the info @ToddL1962 that makes sense

I'm actually running an Arduino Mega for this project does this change anything you have said compared to the Arduino Uno?

@alto777 thanks for the tips

I dont have a proper schematic so this is the best i got for now.

600mA @ 12V DC

2A @ 12V DC its just an old router power supply pack I had in the cupboard

I'm using an Arduino Mega can I change the baud rate that high on it? I thought I had to stay at 9600