I have a project that requires setting up two flow meters to one Arduino Uno Rev3. I have set one up and it's working well, the code for it is below. My question is, how do I set up the code for the second Arduino? I am new to all of this. I'm assuming I essentially copy the code but use pin 3 as the interrupt pin instead of 2 for the second sensor. How exactly would this look? Also, can I power the second sensor using the 3.3V pin? The first one is connected to the 5V pin. Thanks!
int flowpin = 2; //This is the input pin on the Arduino
double flowRate; //Value to be calculated
volative int count; //Integer needs to be set as volative to ensure it updates correctly during interrupt process
void setup() {
//setup code here, runs once
pinMode(flowPin, INPUT); //Sets the pin as input
attachInterrupt(0, Flow, RISING); //Set interrip for pin 2 (Interrupt pin 0)
}
void loop() {
//main code to run repeatedly
count = 0; //makes counter start at 0
interrups(); //enables interrupts
delay (1000); //wait 1 second
noInterrupts(); //Disable the interrups on the Arduino
//math for useful readings
flowRate = (count * 2.25); //Count pulses in last second and multiply by 2.25mL
flowRate = rlowRate * 60; //Convert seconds to minutes, giving mL / minute
flowRate = flowRate / 1000; //Convert mL to Liters, giving L / minute
Serial.println(flowRate); //Print the variable flowRate to Serial
}
void Flow()
{
count++; //every time function runs, increase count by 1
}]
I put up a screenshot of the specifications of the sensor. Here's a link to the page. You are being redirected...
Hold on, I think I just realized I was not being smart about this haha. Sorry, I'm new to Arduino. If I have a pin in the 5V connecting a breadboard, can I just connect my second sensor to the breadboard at it will also be powered by the 5V?
I was editing this code whilst others were answering.
This code should work. It compiles, uploads, and prints the expected info the the serial monitor. In my case the expected outputs are 0.00 because I haven't tested the activity on the input pins gets counted. I did simple duplication. It could be more elegant, but I didn't bother restructuring it to have an array of structs for each sensor and a calculate function.
const byte flowPinA = 2; //This is the input pin on the Arduino
const byte flowPinB = 3; //This is the input pin on the Arduino
double flowRateA; //Value to be calculated
double flowRateB; //Value to be calculated
volatile int countA; //Integer needs to be set as volatile to ensure it updates correctly during interrupt process
volatile int countB; //Integer needs to be set as volatile to ensure it updates correctly during interrupt process
void setup() {
Serial.begin(115200);
pinMode(flowPinA, INPUT); //Sets the pin as input
pinMode(flowPinB, INPUT); //Sets the pin as input
attachInterrupt(digitalPinToInterrupt(flowPinA), FlowA, RISING);
attachInterrupt(digitalPinToInterrupt(flowPinB), FlowB, RISING);
}
void loop() {
countA = 0;
countB = 0;
interrupts(); //enables interrupts
delay (1000); //wait 1 second
noInterrupts(); //Disable the interrups on the Arduino
//math for useful readings
flowRateA = (countA * 2.25); //Count pulses in last second and multiply by 2.25mL
flowRateA = flowRateA * 60; //Convert seconds to minutes, giving mL / minute
flowRateA = flowRateA / 1000; //Convert mL to Liters, giving L / minute
Serial.println(flowRateA); //Print the variable flowRate to Serial
flowRateB = (countB * 2.25); //Count pulses in last second and multiply by 2.25mL
flowRateB = flowRateB * 60; //Convert seconds to minutes, giving mL / minute
flowRateB = flowRateB / 1000; //Convert mL to Liters, giving L / minute
Serial.println(flowRateB); //Print the variable flowRate to Serial
}
void FlowA() {
countA++; //every time function runs, increase count by 1
}
void FlowB() {
countB++; //every time function runs, increase count by 1
}
Interrupts should be off for the shortest time that is practical. You could declare a couple of local variables localA and localB. Interrupts would only need to be off while you did localA = countA; and localB=countB;
Also the delay(1000) isn't going to give the best timing accuracy because there is some additional time taken to execute the other code in the loop. It might be better to poll millis() for >= 1000ms elapsed since the previous time you did the calculation.
IDK how much accuracy you would gain by making the above changes. It may not make a significant difference
I was going to suggest to @Dave_Lowther that the loop could, with a bit more code, also generate fake inputs so as to thoroughly test the sketch… then I noticed the loop does not run free. Bzzzt!
A place for a big step forward would be to rework the "interrupts on whilst a delay plays out" method.
If the counts were changed to unsigned, then the interrupts could just be left running. Start a sample period noting the counts, end it with a millis() or micros() based timing mechanism and calculate the number of pulses each counter accumulate and then… you could test it by using the rest of the time to generate the fake pulses.
I hadn't seen @alto777's post while I was making the most simple example. I'll post it anyway. All it does is print "Tick" on the serial monitor once a second.
unsigned long timeWhenLastCalcDone = 0;
const unsigned calcDelay = 1000;
void setup() {
Serial.begin(115200);
}
void loop() {
unsigned long timeNow = millis();
if ((timeNow - timeWhenLastCalcDone) >= calcDelay) {
timeWhenLastCalcDone = timeNow;
Serial.println("Tick"); // Remove this line
// Put your loop code, with the delay(1000) removed, in here
// Enable interrupts before you exit this block of code
}
}
const byte flowPinA = 2; //This is the input pin on the Arduino
const byte flowPinB = 3;
double flowRateA; //Value to be calculated
double flowRateB;
volatile int countA; //Integer needs to be set as volative to ensure it updates correctly during interrupt process
volatile int countB;
void setup() {
//setup code here, runs once
Serial.begin(115200);
pinMode(flowPinA, INPUT); //Sets the pin as input
pinMode(flowPinB, INPUT);
attachInterrupt(digitalPinToInterrupt(flowPinA), FlowA, RISING); //Set interrupt for pin 2 (Interrupt pin 0)
attachInterrupt(digitalPinToInterrupt(flowPinB), FlowB, RISING);
}
void loop() {
//main code to run repeatedly
countA = 0; //makes counter start at 0
countB = 0;
unsigned long timeNow = millis();
if ((timeNow - timeWhenLastCalcDone) >= calcDelay) {
timeWhenLastCalcDOne = timeNow;
interrupts(); //enables interrupts
noInterrupts(); //Disable the interrupts on the Arduino
//math for useful readings
flowRateA = (countA * 2.25); //Count pulses in last second and multiply by 2.25mL
flowRateA = flowRateA * 60; //Convert seconds to minutes, giving mL / minute
flowRateA = flowRateA / 1000; //Convert mL to Liters, giving L / minute
Serial.println(flowRateA); //Print the variable flowRate to Serial
flowRateB = (countB * 2.25);
flowRateB = flowRateB * 60;
flowRateB = flowRateB / 1000;
Serial.println(flowRateB);
}
}
void FlowA(){
countA++; //every time function runs, increase count by 1
}
void FlowB() {
countB++;
}
const byte flowPin[2] = {2, 3}; //This is the input pin on the Arduino
volatile unsigned int flowCount[2]; //Integer needs to be set as volative to ensure it updates correctly during interrupt process
void FlowA(){
flowCount[0]++; //every time function runs, increase count by 1
}
void FlowB() {
flowCount[1]++;
}
void setup() {
Serial.begin(115200);
for (byte f=0; f<2; f++) {
pinMode(flowPin[f], INPUT); //Sets the pin as input
}
attachInterrupt(digitalPinToInterrupt(flowPin[0]), FlowA, RISING); //Set interrupt for pin
attachInterrupt(digitalPinToInterrupt(flowPin[1]), FlowB, RISING); //Set interrupt for pin
}
void loop() {
unsigned long timeNow = millis();
static unsigned long timeWhenLastCalcDone;
if ((timeNow - timeWhenLastCalcDone) >= 1000) {
timeWhenLastCalcDone = timeNow;
for (byte f=0; f<2; f++) {
noInterrupts(); //Disable the interrupts on the
unsigned int count = flowCount[f];
flowCount[f] = 0;
interrupts(); //enables interrupts
//math for useful readings
float flowRate = (count * 2.25) * 60 / 1000; //Count pulses in last second and multiply by 2.25mL and convert to L/min
Serial.println(flowRate); //Print the variable flowRate to Serial
}
}
}
The Hall effect sensor's output is NPN open collector, so if you do not have a pullup resistor (10k) connected between pin 2 and 5V, you need: pinMode(flowPin, INPUT_PULLUP);