(SOLVED-bent wire) Flaky readings from pulseIn()

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.

Post ALL your code.

Mark

/*

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.