@rpunkt Ok, never heard of "hook-on code", if you mean an example sketch, here is my water tank node to butcher.
#include <T2WhisperNode.h>
#include <Wire.h>
#include <RTClibExtended.h>
// Enable debug prints to serial monitor
//#define MY_DEBUG //Comment out once all working saving memory
// Enable and select radio type attached
#define MY_RADIO_RFM69
#define MY_RFM69_FREQUENCY RFM69_433MHZ // Define for frequency setting. Needed if you're radio module isn't 868Mhz (868Mhz is default in lib)
#define MY_RFM69_NETWORKID 101 // Default is 100 in lib. Uncomment it and set your preferred network id if needed
#define MY_NODE_ID 7 //Manually set the node ID here. Comment out to auto assign
//A define should be added to provide minimum power output to provide decent RSSI to the Gateway if ATC not available
#include <MyConfig.h>
#include <SPI.h>
#include <MySensors.h>
#define SN "Node7water3vWNfinalRTC"
#define SV "4"
#define FIRST_CHILD_ID 1
#define SECOND_CHILD_ID 2
#define THIRD_CHILD_ID 3
#define REED_PIN 3 // Arduino Digital I/O pin for button/reed switch
#define BatteryOn 14
#define BatteryIn A6
#define RelayOn 6
#define RelayOff 9
#define Trigpin 17
#define Echopin 16
int halfday=12;
int tankdepth, tankpercent,tankvolume,distance,test,test2,counter;
long duration;
volatile int ultrasonic;
RTC_DS3231 RTC; //we are using the DS3231 RTC
// Change to V_LIGHT if you use S_LIGHT in presentation below
MyMessage msg1(FIRST_CHILD_ID, V_LEVEL);
MyMessage msg2(SECOND_CHILD_ID, V_LEVEL);
MyMessage msg3(THIRD_CHILD_ID, V_VOLTAGE);
unsigned long SLEEP_TIME = 0;//1800000; Sleep time between reports (in milliseconds)
void setup ()
{
pinMode(REED_PIN, INPUT_PULLUP);//Output of DS3231 INT pin is connected to D3 INT1 for RTC wake-up
pinMode(BatteryOn, OUTPUT);//WN battery sample activation
pinMode(BatteryIn, INPUT);//WN ADC for battery read
pinMode(Trigpin, OUTPUT);
pinMode(Echopin,INPUT);
pinMode(RelayOn, OUTPUT);//US on
pinMode(RelayOff, OUTPUT);//US off
analogReference(INTERNAL);//All voltage reads are to 1.1 internal datum
VOFF();
sleep(100);//Allow things to settle was 1000
Wire.begin ();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__)); //set RTC date and time to COMPILE time
//clear any pending alarms
RTC.armAlarm(1, false);
RTC.clearAlarm(1);
RTC.alarmInterrupt(1, false);
RTC.armAlarm(2, false);
RTC.clearAlarm(2);
RTC.alarmInterrupt(2, false);
//Set SQW pin to OFF
RTC.writeSqwPinMode(DS3231_OFF);
//Set alarm1 every hour at XX:50
RTC.setAlarm(ALM1_MATCH_MINUTES, 0, 50, 0, 0);//set wake-up time here
RTC.alarmInterrupt(1, true);//Alarm on
}
void presentation(){
// Send the sketch version information to the gateway and Controller
sendSketchInfo(SN, SV);
// Register binary input sensor to sensor_node (they will be created as child devices)
// You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
// If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
present(FIRST_CHILD_ID, S_DUST);
present(SECOND_CHILD_ID, S_DUST);
present(THIRD_CHILD_ID, S_MULTIMETER);
}
void loop(){
// Power up US
VON();
sleep(500);//Delay to let the 5v kit stabilise
digitalWrite(Trigpin,HIGH);
sleep (100);
digitalWrite(Trigpin,LOW);
sleep(100);/// Allow decay of pulse
int voltread;
counter=0;
tankdepth=0;
while ((tankdepth<350||tankdepth>1000)&&counter<=10){//10 attempts to get proper range
READULTRASONIC();
counter++;
}
//Normal range should be 363 to 989, completely empty 1520, //First overnight runs got depth full as 363mm so formula revise
// float tankpercent=100-((989-ultrasonic)/6);
float tankpercent=100-((989-tankdepth)/6.26);//626 effective range
int tankvolume=(989-tankdepth)*2.3727;//Set to low level cut off
if(tankdepth>350&&tankdepth<1000){//Don't report if value is outwith known range
VOFF();
sleep(100);
send(msg1.set(tankvolume));//This is actual volume
sleep(100);
send(msg2.set(tankpercent,1));//This is remainder to start of 39cm Freeboard
sleep(100);
}
// }
VOFF();//If there are 2 yellow flashes it reported and switched off 1 if it failed to read
// Call for battery reading, send in every 12th RTC call?
if(halfday==12){
digitalWrite(BatteryOn, HIGH);
voltread = analogRead(BatteryIn);
float voltage = (7.272 * voltread) / 1024;
sleep(5);
digitalWrite(BatteryOn, LOW);
send(msg3.set(voltage,2));
sleep(50);
voltread=0;
sleep(50);
halfday=0;//Reset for 12 hourly cycle
}
halfday++;//Increment hourly cycle
// Rearm alarm
Wire.begin();
RTC.begin();
RTC.alarmInterrupt(1, true);
sleep(50);
Wire.end();
sleep(50);
//Go deep sleep until RTC interrups
sleep(digitalPinToInterrupt(REED_PIN),FALLING, SLEEP_TIME);
sleep(100);///Time to recover
//First clear the alarm
Wire.begin();
RTC.begin();
RTC.armAlarm(1, false);
RTC.clearAlarm(1);
RTC.alarmInterrupt(1, false);
} // end of loop
void VON(){
digitalWrite(RelayOn, HIGH);
sleep (10);
digitalWrite(RelayOn,LOW);
}
void VOFF(){
digitalWrite(RelayOff, HIGH);
sleep (10);
digitalWrite(RelayOff,LOW);
}
void READULTRASONIC(){//JSN-SR04-2.0
//Main loop checks valid range on a defined number of readings
tankdepth=0;
duration=0;
distance=0;
test=1;
test2=3;
// Normal range should lie between 389 and 989 absolutely empty is 1520
while (test!=test2){// Get two consecutive readings
digitalWrite(Trigpin, LOW);
delayMicroseconds(100);
digitalWrite(Trigpin, HIGH);
delayMicroseconds(150);
digitalWrite(Trigpin, LOW);
duration = pulseIn(Echopin, HIGH);
distance = duration/5.82;//This is in mm
if (test!=distance){
test=distance;
distance=0;
}
else{
test2=distance;
}
delay(100);///// 500 originally but why???????
}
tankdepth=distance;
}
All specific to this setup of course, but it should point you in the right direction.
It returns the volume available from the tank and the %age used. Since the actual volume can potentially overshoot the electrode (turning off the fill pump) it calculates the absolute volume above the supply pump cut-off, the %age used operates from the theoretical full mark.
I see no reason for sending the actual level, but you may have your reasons.