I'm using pulseIn() to estimate water flow in a radiant heat system. The flow meter is a simple impeller that drives a hall effect sensor. I'm not doing any switch bounce logic, since I assume the hall effect switch is bounce-free. Looking at the waveform on a scope appears to confirm that, but there is enough jitter in the signal that I can't look at the edges in detail.
The cycle width coming out of the flow meter is between 10 msec and 100 msec wide, so the pulse width is 5-50 msec. The code below takes five samples and averages them and divides by 10. For the 50 msec pulse width I should see counts around 5000. So for this setup the counts should be between 500-5000.
I'm getting random numbers between 125 and 1600. Is this a pulseIn() problem or some obscurity of unsigned long math or lcd.print() issue? (pulsew is unsigned long)
// check flow rate
pulsew = 0 ;
for (int i=0; i < 5; i++) {
pulsew = pulsew + pulseIn(7, LOW) ; }
pulsew = pulsew / 50 ;
lcd.setCursor(13,2) ;
lcd.print(pulsew) ;
lcd.print(" ") ;
Even though there is about 5 msec of jitter (water flow is not laminar by any means) in the waveform, the wave looks perfectly square and very evenly balanced high and low.
/*
Constant temperature radiant heat controller.
*/
int Unit_ID = 0x12 ; // The office display unit ID is 0x11
int Temp3 ;
int Temp4 ;
int Sys1 = 1 ; // One/High for off
int Sys2 = 1 ; // One/High for off
int Set1 = 60 ; // set point temperature of 60 degrees F
int Set2 = 60 ; // set point temperature of 60 degrees F
int Band = 1 ; // Hysteresis band width is +/- 1 degree F
unsigned long pulsew = 0 ; // pulse width in microseconds
// Load Libraries
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
// Load Libraries for DS1820 and OneWire
#include <OneWire.h>
#include <DallasTemperature.h>
// Define variables LCD:
#define I2C_ADDR 0x27 // Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS3 3
#define ONE_WIRE_BUS4 4
// Setup oneWire instance to communicate with devices
OneWire oneWire3(ONE_WIRE_BUS3);
OneWire oneWire4(ONE_WIRE_BUS4);
// Pass oneWire reference to Dallas Temperature.
DallasTemperature sensor3(&oneWire3);
DallasTemperature sensor4(&oneWire4);
// -------------------------------------
int led = 13 ;
//Initialise the LCD
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
// ---------------- SETUP ---------------------------
void setup() {
delay(200) ; // give LCD time to stabilize
lcd.begin (20,4);
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
// Goto first column (column, line),
lcd.setCursor ( 0, 0 );
lcd.print("2-chan thermostat ") ;
lcd.setCursor (0,1) ;
lcd.print(" Two Sensors Max") ;
delay(1500) ;
// Start the OneWire library
sensor3.begin() ;
sensor4.begin() ;
pinMode(led,OUTPUT) ;
pinMode(11,OUTPUT) ;
pinMode(12,OUTPUT) ;
delay (250) ;
digitalWrite(11,HIGH) ; // Turn off system 1
digitalWrite(12,HIGH) ; // Turn off system 2
}
// ---------------- LOOP -----------------------
void loop() {
lcd.setCursor ( 0, 1 ) ;
lcd.print(" LOOP ") ;
delay(1000) ;
lcd.setCursor ( 0, 1 ) ;
lcd.print("-------------------") ;
readtemp() ;
delay (350) ;
lcd.setCursor(0,2) ;
lcd.print(" ") ;
lcd.print(Temp3/100.0) ;
lcd.print(" ") ;
lcd.setCursor(0,3) ;
lcd.print(" ") ;
lcd.print(Temp4/100.0) ;
lcd.print(" ") ;
// Prepare hyteresis tree
// System 1 Branch
if (Sys1) {
if (Temp3/100.0<(Set1-Band)) {
Sys1 = 0 ;
digitalWrite(11,LOW) ; } // Turn system 1 on
}
else {
if (Temp3/100.0>(Set1+Band)) {
Sys1 = 1 ;
digitalWrite(11,HIGH) ; } // Turn system 1 off
}
// System 2 Branch
if (Sys2) {
if (Temp4/100.0<(Set2-Band)) {
Sys2 = 0 ;
digitalWrite(12,LOW) ; } // Turn system 2 on
}
else {
if (Temp4/100.0>(Set2+Band)) {
Sys2 = 1 ;
digitalWrite(12,HIGH) ; } // Turn system 2 off
}
// write status
lcd.setCursor(7,2) ;
if (Sys1) { lcd.print(" OFF ") ; }
else { lcd.print(" ON ") ; }
lcd.setCursor(7,3) ;
if (Sys2) { lcd.print(" OFF ") ; }
else { lcd.print(" ON ") ; }
// check flow rate
pulsew = 0 ;
for (int i=0; i < 5; i++) {
pulsew = pulsew + pulseIn(7, LOW) ; }
pulsew = pulsew / 50 ;
lcd.setCursor(13,2) ;
lcd.print(pulsew) ;
lcd.print(" ") ;
// blink the led to show each loop
digitalWrite(led, HIGH) ;
delay(300) ; // make LED flash more visible
digitalWrite(led, LOW) ;
delay(3450) ; // make an approximate 5-second loop
}
//----------------------------------
void readtemp(void) {
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
sensor3.requestTemperatures();
sensor4.requestTemperatures();
// Convert temps to Fahrenheit x100 (integer)
Temp3 = ((sensor3.getTempCByIndex(0) * 9 / 5)+32) * 100 ;
Temp4 = ((sensor4.getTempCByIndex(0) * 9 / 5)+32) * 100 ; }
// ------------------------------------------------
Some Hall effect switches are DEFINITELY NOT bounce free, especially if the transitions are slow. Take a closer look with the scope.
Edges are clean. I will fess up to stupidity. Bent wire on the breadboard. Looked good, but I took it apart in frustration and discovered the short.