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 ****************** */