Water well pressure moniter developing



  • Scope ; I, like many others have a water well to supply our water needs. One of the inherent problems of a water well is a condition that the tank can become "water logged ". This results in the pump cycling rapidly resulting to the demise of the pump motor. I am trying to develop an system to monitor the pressure and the cycle time of the pump and set alarms in my Vera using MySensors . Being new to this I quickly realize the learning curve was steep.
    My plan is the put a relay on the pump the provide a signal when it is running ( and the length of time it is running) ; a pressure transmitter on the tank to monitor current pressure . I want to monitor pressure in case of pump failure .
    One of the problems I have incurred is I cannot find a pressure sensor .ino for this application and the files necessary for the vera.
    I purchased a generic pressure sensor and with the code below tested and refined it to provide accurate reading to serial monitor .

    int pSensor=A0; //assigning pressure sensor to pin A0
    int readValue; //declaring our readValue Variable
    float Voltage; // declare voltage variable
    float PSI; // declare pressure variable

    void setup() {
    pinMode(pSensor,INPUT); //declare psensor as a input
    Serial.begin(9600); //start serial port
    }

    void loop() {

    readValue = analogRead(pSensor); // read psensor and put value in read value
    Voltage = (5./1023.)readValue; //calculating real world voltage
    PSI = 17.78
    Voltage -8; // Calculate pressure PSI
    Serial.println(PSI); //print results to serial monitor
    delay(1000); // delay one second

    Can someone help me with a path forward. I am not asking for someone to develop it only to mentor me down the path .


  • Mod

    How about converting the PSI to hPa and use that value in the pressure example?



  • After ,posting this an doing a lot of research I have managed to totally confuse myself . I am not sure any longer what day it is. There has to be a way to accomplish this . all I want to do now is get the psi reading generate by the above sketch to my vera via a serial gateway . Someone Please remove my blinders and point me in the right direction .



  • Here is my program that monitors pressure and flow... Its a work in progress, its still has a few minor issue to work out, but it works....
    It was build using the 2.0.0 development version of MySensor.

    It uses a 0 to 5V output sensor that I found on ebay. I fed its output into an ATD converter pin via a resistor divider.. 10.2k to sensor, 19.6k to gnd... This converts the 5v from the sensor to ~3.3v for the ATD. You can use 5% resistors of 10k and 20k, calibrate the ATD by setting input to divider at 2.5v and adjusting PSIcal to give you 50PSI. Also sending a V_VAR4 message to this sender, you can adjust the PSIcal value in real time...

    It should be easy to remove all of the flow stuff from my program to give you just pressure...

    in from sensor ---10.2k-------- to ATD-pin
    to ATD-pin----19.6k----- gnd

    sensor:
    http://www.ebay.com/itm/Pressure-transducer-or-sender-100-psi-stainless-steel-for-oil-fuel-air-water-/271576977896?hash=item3f3b3fd1e8:g:oQsAAOSwxN5WU8Cs&vxp=mtr

    This sensor has three pins, +5V, gnd and output.

    /*  
     *  Ver 1.2b TRL 1-Mar-2016
     *  
     *  Water flow from a Dwyer 1gal/pulse meter
     *  We measure the period of the pulse to determine the short term flow rate
     *    We also count the pulses to obtain the total gallons used
     *    We filter the input to debounce the reed switch in the meter the best we can, with a cutoff of ~80 gal/min
     *   
     *  Water from a pressure transducer, 0 to 5v
     *    Input fron sensor is scaled by .6577, 5.0v * .6577 = 3.288v
     *    (10.2k and a 19.6k resistor, flitered with a .1uf cap)
     *   
     *  Output: 0.5V – 4.5V linear voltage output. 0 psi outputs 0.5V, 50 psi outputs 2.5V, 100 psi outputs 4.5V 
     *    0   psi = 0.33v after scalling 5.0v to 3.3v
     *    50  psi = 1.65v
     *    100 psi = 2.97v
     *    3.3v/1024 = .0032266 volt per bit
     *    
     *    TX Led was on D3, now use for pulse-in
     *
     */
    
    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * Version 1.1 - GizMoCuz
     * 
     * DESCRIPTION
     * Use this sensor to measure volume and flow of your house watermeter.
     * You need to set the correct pulsefactor of your meter (pulses per gal).
     * The sensor starts by fetching current volume reading from gateway (VAR 1).
     * Reports both volume and flow back to gateway.
     *
     * Unfortunately millis() won't increment when the Arduino is in 
     * sleepmode. So we cannot make this sensor sleep if we also want  
     * to calculate/report flow.
     * http://www.mysensors.org/build/pulse_water
     */
    
    
    
    /* ************************************************************************************** */
    // These items need to be prior to #include <MySensor.h>  below
    
    /*  Enable debug prints to serial monitor on port 0 */
    #define MY_DEBUG            // used by MySensor
    #define MY_DEBUG1           // used in this program, level 1 debug
    #define MY_DEBUG2           // used in this program, level 2 debug
    
    #define SKETCHNAME "Water and Pressure Meter"
    #define SKETCHVERSION "1.2b"
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    #define MY_IS_RFM69HW          true
    #define MY_RFM69_FREQUENCY     RF69_915MHZ      // this set frequency band, not the real operating frequency
    
    #define MY_LEDS_BLINKING_FEATURE
    #define MY_WITH_LEDS_BLINKING_INVERSE
    
    // Moteino 
    #define MY_RF69_SPI_CS 10
    #define MY_RF69_IRQ_PIN 2
    #define MY_RF69_IRQ_NUM 0
    #define MY_DEFAULT_TX_LED_PIN     9   // 4 on sensor 2a PCB as LED3 (9 == on Moteino)
    #define MY_DEFAULT_ERR_LED_PIN    6   // 6 on sensor 2a PCB as Err
    #define MY_DEFAULT_RX_LED_PIN     7   // 7 on sensor 2a PCB as Rx
    
    
    // MoteinoMEGA
    //#define MY_RF69_SPI_CS      4
    //#define MY_RF69_IRQ_PIN     2
    //#define MY_RF69_IRQ_NUM     2
    //#define MY_DEFAULT_TX_LED_PIN     15   // the PCB, on board LED
    //#define MY_DEFAULT_ERR_LED_PIN    7
    //#define MY_DEFAULT_RX_LED_PIN     6
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    #define MY_NODE_ID 6                            // My Sensor Node ID
    //#define MY_PARENT_NODE_ID 0                   // GW ID
    #define CHILD_ID    1                           // Id of my Water sensor child
    #define CHILD_ID2   2                           // Id of my 2nd sensor child
    
    /* ************************************************************************************** */
    /* These are use for local debug of code, hwDebugPrint is defined in MyHwATMega328.cpp */
    #ifdef MY_DEBUG1
    #define debug1(x,...) hwDebugPrint(x, ##__VA_ARGS__)
    #else
    #define debug1(x,...)
    #endif
    
    #ifdef MY_DEBUG2
    #define debug2(x,...) hwDebugPrint(x, ##__VA_ARGS__)
    #else
    #define debug2(x,...)
    #endif
    
    /* ************************************************************************************** */
    
    #include <SPI.h>
    #include <MySensor.h>  
    
    #define DIGITAL_INPUT_SENSOR 3                  // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
    #define SENSOR_INTERRUPT DIGITAL_INPUT_SENSOR-2     // Usually the interrupt = pin -2 (on uno/nano anyway)
    
    #define PressPin      A0                       // Pressure sensor is on analog input A0
    #define PULSE_FACTOR 1                         // Nummber of pulse per gal of your meter (One rotation/gal)
    #define SLEEP_MODE false                       // flow value can only be reported when sleep mode is false.
    #define MAX_FLOW 60                            // Max flow (gal/min) value to report. This filters outliers.
    
    
    /* ******************************************************************* */
    
    unsigned long SEND_FREQUENCY = 4000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
    unsigned long FLOW_FREQUENCY = 180000;         // time to refresh flow to gateway
    
    MyMessage flowMsg         (CHILD_ID,V_FLOW);      // 34
    MyMessage volumeMsg       (CHILD_ID,V_VOLUME);    // 35
    MyMessage lastCounterMsg  (CHILD_ID,V_VAR1);      // 24
    MyMessage VAR2Msg         (CHILD_ID,V_VAR2);      // 25
    MyMessage VAR3Msg         (CHILD_ID,V_VAR3);      // 26
    MyMessage VAR4Msg         (CHILD_ID,V_VAR4);      // 27
    MyMessage pressureMsg     (CHILD_ID,V_PRESSURE);  // 4
    
    double ppg = ((double) PULSE_FACTOR) ;            // Pulses per gal 
    
    volatile unsigned long pulseCount = 0;   
    volatile unsigned long lastBlink = 0;
    volatile unsigned long newBlink = 0;   
    volatile unsigned long interval = 0;
    volatile double flow = 0; 
    
    boolean pcReceived = false;
    
    unsigned long oldPulseCount = 0;
    
    double oldflow = 0;
    double volume = 0;                     
    double oldvolume = 0;
    
    unsigned long currentTime = 0;
    unsigned long lastSend = 0;
    unsigned long lastPulse = 0;
    
    int t1 = 0 ;
    
    int pressure = 0;
    float PSI = 0;
    float PSI_CAL = 2.0;            // Calibration of sensor
    int PSImsb = 0;
    int PSIr = 0;
    
    /* **************************************************************************** */
    /* **************************************************************************** */
    /* **************************************************************************** */
    void setup()  
    {  
      // initialize serial communication at 115200bits per second:
      Serial.begin(115200);
    
      debug1(PSTR("** Hello from the Water Meter **\n") );
      const char compile_date[] = __FILE__ ", " __DATE__ ", " __TIME__;
      debug2(PSTR("%s %s\n"), SKETCHNAME, SKETCHVERSION);
      debug2(PSTR("%s \n\n"), compile_date);
    
      // initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion) 
      pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
      
      // reference to use (DEFAULT, INTERNAL, INTERNAL1V1, INTERNAL2V56, or EXTERNAL). 
      analogReference(DEFAULT);
    
      pulseCount = oldPulseCount = 0;
    
      // Fetch last known pulse count value from gw
      //request(CHILD_ID, V_VAR1);
    
      lastSend = lastPulse = millis();      // set current time
    
      attachInterrupt(SENSOR_INTERRUPT, onPulse, FALLING);
    }
    
    /* ******************************************************************* */
    void presentation()  
    {
     // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCHNAME, SKETCHVERSION);
      wait(250);
    
      // Register this device as Waterflow sensor
      present(CHILD_ID, S_WATER);       // S_WATER = 21 
      wait(250);
    
    }
    
    /* **************************************************************************** */
    /* **************************************************************************** */
    /* **************************************************************************** */
    void loop()     
    { 
    
        _process();
        
        currentTime = millis();                 // get the current time
      
        // Only send values at a maximum frequency or woken up from sleep
      if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY))
      {
        lastSend = currentTime;
        
    //    if (!pcReceived) 
    //    {
    //      //Last Pulsecount not yet received from controller, request it again
    //      request(CHILD_ID, V_VAR1);
    //      Serial.println("Last Pulsecount not yet received from controller");
    //      return;
    //    }
    
    
      //  if (!SLEEP_MODE && (flow != oldflow) )
        {
          oldflow = flow;
    
          flow = ((60000000.0 / (double) interval) ) / ppg;
    
          if (flow < 0) flow = 0;
    
          // Check that we dont get unresonable large flow value. 
          // could happen when long wraps or false interrupt triggered
          if (flow < ((unsigned long) MAX_FLOW)) 
          {
    
            PSImsb = flow * 100;
            PSIr = PSImsb % 100;
            debug1(PSTR("gal/min: %0d.%02d\n"), PSImsb/100, PSIr);
            
            send(flowMsg.set(flow, 2));                   // Send flow value to gateway
            wait(200);
          }  
        }
    
    
        // If no Pulse count received in 2min, update gateway flow to zero
        if(currentTime - lastPulse > FLOW_FREQUENCY)
        {
          flow = 0;
          debug1(PSTR("***Sending zero flow rate\n"));
    
          send(flowMsg.set(flow, 2));                   // Send flow value to gateway
          wait(200);
        } 
    
    
        // Pulse count has changed
        if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) 
        {
          oldPulseCount = pulseCount;
    
          debug1(PSTR("Pulse Count:  %u\n"), (unsigned int) pulseCount );
          
    
          send(lastCounterMsg.set(pulseCount));         // Send  pulse count value to gw in VAR1
          wait(200);
    
          double volume = ((double) pulseCount / ((double) PULSE_FACTOR));     
          if ((volume != oldvolume) || (!SLEEP_MODE)) 
          {
            oldvolume = volume;
    
            debug1(PSTR("Volume (gal): %u\n"), (unsigned int) volume );
    
            send(volumeMsg.set (volume,0));            // Send total volume to gateway
            wait(200);
          } 
        }
    
    /* ************************************************ */
        pressure  = analogRead    (PressPin) ;        // junk read
        wait(25);
        
    /* • Output: 0.5V – 4.5V linear voltage output. 0 psi outputs 0.5V, 50 psi outputs 2.5V, 100 psi outputs 4.5V 
        0   psi = .33v after scalling 5.0v to 3.3v
        50  psi = 1.65v
        100 psi = 2.97v
    
        3.3v/1024 = .0032266 volt per bit
     */
        pressure  = analogRead    (PressPin) ;
    
        if (pressure < 106) pressure = 106;         // this is minimum of .5v
        PSI = (pressure - 106 ) * .1246;            // where did we get this?? was .119904
        PSI = PSI + PSI_CAL;                        // adjustment
        
        PSImsb = PSI * 100;
        PSIr = PSImsb % 100;
        debug1(PSTR("PSI:  %0u.%02u\n"), PSImsb/100, PSIr);
    
        send(pressureMsg.set(PSI, 2));            // Send water pressure to gateway
        wait(200);
        
      }   // end of if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY))
    
      if (SLEEP_MODE) 
      {
        sleep(SEND_FREQUENCY);
      }
      
    }   // end of loop
    
    
    /* ******************************************************************* */
    void receive(const MyMessage &message) 
    {
       //debug1(PSTR("Received message from gw\n"));
     
      if (message.sensor == CHILD_ID )
      {
        if  (message.type==V_VAR1) 
          {
            unsigned long gwPulseCount=message.getULong();
            pulseCount += gwPulseCount;
            flow=oldflow=0;
            debug1(PSTR("Received last pulse count from gw: %u\n"), pulseCount);
            pcReceived = true;
          }
        
         if ( message.type==V_VAR2) 
          {
            pulseCount = message.getULong();
            flow=oldflow=0;
            debug1(PSTR("Received V_VAR2 message from gw: %u\n"), pulseCount );
          }
        
         if ( message.type==V_VAR3) 
          {
            FLOW_FREQUENCY = message.getULong();
            debug1(PSTR("Received V_VAR3 message from gw: %u\n"), FLOW_FREQUENCY);
    
         if ( message.type==V_VAR4) 
          {
      
            PSI_CAL = message.getULong();
            debug1(PSTR("Received V_VAR4 message from gw: %u\n"), PSI_CAL);
          }
          }
        }  // end if (message.sensor == CHILD_ID )
      
      if (message.sensor == CHILD_ID2 )
        {
          
        }
    }
    
    /* ******************************************************************* */
    /* As this is an interrupt service, we need to keep the code here as short as possable */
    void onPulse()     
    {
      if (!SLEEP_MODE)
      {
        newBlink = micros();              // get the current time in us
        interval = newBlink-lastBlink;    // get the delta time in us from last interrupt
        lastBlink = newBlink;             // setup for next pulse
      }
      
      pulseCount++;       // count the pulses from meter
      lastPulse = millis();
      
    }
    
    /* ************** The End ****************** */
    
    

Log in to reply
 

Suggested Topics

  • 1
  • 2
  • 3
  • 1
  • 2
  • 1

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts