Hello All,
So I am working on a project that uses an Arduino for the brunt of my operation for the different components I am used. I have 3 motors that pump water from one place to another and then some motorized ball valves that open up to drain the water back to where the pumps are. Then I have 2 ultrasonic sensors that I use to measure the depth level of the water in each container. I also have flow meters hooked up to each pump and each valve making for a total of 5 flow meters.
My question is that I have everything else working but when introducing the Flow meter code into my Arduino code it will stop the serial printing of data due to the interrupt and it never leaving the ISR for counting pulses to calculate the flow data.
The thing that encompasses all of this is a rasperrypi that I've made a GUI in using the tkinter library in python. That part isn't really having issues. I will post both my arduino code and python code below and I would appreciate any feedback that will allow me to measure the flow meter data and still allow me to use the other functions in the code since they are being utilized in the GUI to open these valves or turn on these pumps. Thank you
Arduino:
//Variables for Pumps & Valves
int receivedChar;
int receivedChar1;
boolean newData = false;
int count = 0;
//Variables for Flow Meters
volatile int count1;
//Pins for sensors
const int trigPin = 51;
const int echoPin = 50;
const int trigPin1 = 53;
const int echoPin1 = 52;
//Pins for FlowMeters
const int flowPin = 2;
//Variables for Sensors
long duration;
int distance;
long duration1;
int distance1;
//Variables for Flow Meters
double flowRate;
//Function to setup pins
void setup()
{
Serial.begin(9600);
pinMode(3, OUTPUT); //Pump 1
pinMode(5, OUTPUT); //Pump 2
pinMode(6, OUTPUT); //Pump 3
pinMode(7, OUTPUT); //Geist Valve
pinMode(8, OUTPUT); //Quarry Valve
pinMode(trigPin, OUTPUT); //Ultrasonic Trig Pin
pinMode(echoPin, INPUT); //Ultrasonic Echo Pin
pinMode(trigPin1, OUTPUT); //Ultrasonic Trig Pin
pinMode(echoPin1, INPUT); //Ultrasonic Echo Pin
pinMode(flowPin, INPUT_PULLUP); //Flow meter pin
attachInterrupt(0, Flow, RISING); //Configure interrupt to run Flow function
}//end setup
//Main loop
void loop()
{
recvInfo();
lightLED(); //Function for motors
ultrasonicSensor(); //Geist sensor function
ultrasonicSensor1(); //Quarry sensor function
count1 = 0; //count variable for flow meters
interrupts(); //Enable interrupts
delay(250); //short delay
noInterrupts(); //Disable Interrupts
flowRate = (count1 * 2.25); //Take pulses and multiply by 2.25mL
flowRate = flowRate * 60; //Convert seconds to minutes
flowRate = flowRate / 1000; //Convert mL to Liters (L / Min)
Serial.println(flowRate); //Print flowRate to Serial
Serial.flush();
}//end loop
void recvInfo()
{
while (Serial.available() > 0)
{
receivedChar = Serial.read();
newData = true;
count++;
if(count == 2)
{
newData = false;
}//end if
}//end while
}//end recvInfo()
//Motor function
void lightLED()
{
int led = (receivedChar - '0');
if(newData == true)
{
digitalWrite(led, HIGH);
}//end HIGH if
if(newData == false)
{
digitalWrite(led, LOW);
count = 0;
}//end LOW if
}//end lightLED()
void ultrasonicSensor()
{
//Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
//Sets the trigPin on HIGH state for 10 ms
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
//Calculating distance
distance = duration*0.034/2;
//Prints the distance to the Serial Monitor
//Serial.print("Distance: ");
Serial.println(distance);
delay(250);
Serial.flush();
}//end ultrasonicSensor()
void ultrasonicSensor1()
{
//Clears the trigPin
digitalWrite(trigPin1, LOW);
delayMicroseconds(2);
//Sets the trigPin on HIGH state for 10 ms
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin1, LOW);
//Reads the echoPin, returns the sound wave travel time in microseconds
duration1 = pulseIn(echoPin1, HIGH);
//Calculating distance
distance1 = duration1*(0.034/2);
//Prints the distance to the Serial Monitor
//Serial.print("Distance1: ");
Serial.println(distance1);
delay(250);
Serial.flush();
}//end ultrasonicSensor1()
//Function for flow meters
void Flow()
{
count1++; //Every time this function is called, increment count1 by 1
}
Python:
from tkinter import *
import serial
import time
import threading
ser = serial.Serial('/dev/ttyACM0', 9600)
class Window(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_window()
#Window Function
def init_window(self):
self.master.title("GUI")
self.pack(fill=BOTH, expand=1)
#Start/Stop Pump 1 button on GUI
pump1 = Button(self, text="Pump 1", command=self.Pump1)
pump1.place(x=10, y=100)
#Start/Stop Pump 2 button on GUI
pump2 = Button(self, text="Pump 2", command=self.Pump2)
pump2.place(x=150, y=100)
#Start/Stop Pump 3 button on GUI
pump3 = Button(self, text="Pump 3", command=self.Pump3)
pump3.place(x=290, y=100)
#Open/Close Geist Valve on GUI
GeistValve = Button(self, text="Geist", command=self.Valve1)
GeistValve.place(x=10, y=150)
#Open/Close Quarry Valve on GUI
QuarryValve = Button(self, text="Quarry", command=self.Valve2)
QuarryValve.place(x=150, y=150)
#Input Box for Ultrasonic Sensor (Geist1)
serial_data1 = ser.readline(4)
Sensor1 = Text(self, width=4, height=1)
Sensor1.place(x=10, y=180)
Sensor1.insert(END, serial_data1)
#update Sensor1 Value
def update_Sensor1():
serial_data1 = ser.readline(4)
Sensor1.delete("1.0","end")
Sensor1.insert(END, serial_data1)
Sensor1.after(1000,update_Sensor1)
Sensor1.after(1000,update_Sensor1)
#Input Box for Ultrasonic Sensor (Geist2)
serial_data2 = ser.readline(8)
Sensor2 = Text(self, width=4, height=1)
Sensor2.place(x=150, y=180)
Sensor2.insert(END, serial_data2)
#update Sensor2 Value
def update_Sensor2():
serial_data2 = ser.readline(8)
Sensor2.delete("1.0", "end")
Sensor2.insert(END, serial_data2)
Sensor2.after(1000,update_Sensor2)
Sensor2.after(1000,update_Sensor2)
#Input Box for Flow Meter 1
#serial_data5 = ser.readline(12)
#FlowMeter1 = Text(self, width=4, height=1)
#FlowMeter1.place(x=10, y=210)
#FlowMeter1.insert(END, serial_data5)
#update FlowMeter1 Value
#def update_FlowMeter1():
# serial_data5 = ser.readline(12)
# FlowMeter1.delete("1.0", "end")
# FlowMeter1.insert(END, serial_data5)
# FlowMeter1.after(1000,update_FlowMeter1)
#FlowMeter1.after(1000,update_FlowMeter1)
#Quit button on GUI
quitButton = Button(self, text="Quit", command=self.client_exit)
quitButton.place(x=350, y=270)
#Function to exit window when quit button is pressed
def client_exit(self):
exit()
#Function for starting pump 1
def Pump1(self):
ser.write('4'.encode())
#Function for starting pump 2
def Pump2(self):
ser.write('5'.encode())
#Function for starting pump 3
def Pump3(self):
ser.write('6'.encode())
#Function for opening Geist Valve
def Valve1(self):
ser.write('7'.encode())
#Function for opening Quarry Valve
def Valve2(self):
ser.write('8'.encode())
root = Tk()
root.geometry("400x300") #GUI size
app = Window(root)
root.mainloop()