Hi there! Reading the Watermark sensor is no easy task indeed. Took us a while to get accurate and reliable data out of these sensors.
First of all, take a look at the official documentation provided by Irrometer: https://www.irrometer.com/200ss.html
Especially the pseudo-AC excitation is very important and make sure you calibrate the readings using the soil temperature.
There's quite some off-the-shelf hardware on the market already. Look for a device that has a low power consumption so you can measure throughout the year, for example:
https://www.crodeon.com/blogs/news/connecting-a-watermark-sensor-to-the-cloud
Let me know if you have any more questions!
Here is the sketch if anyone can help out.
#include <SPI.h>
#include <MySensor.h>
#define CHILD_ID_LIGHT 0
#define LIGHT_SENSOR_ANALOG_PIN 1
#define NODE_ID 9
int BATTERY_SENSE_PIN = A2; // select the input pin for the battery sense point
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
MySensor gw;
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
int lastLightLevel;
int oldBatteryPcnt = 0;
void setup()
{
// use the 1.1 V internal reference
//analogReference(INTERNAL);
gw.begin(NULL, NODE_ID, false);
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Soil_Moist_Sensor_grb", "1.15");
// Register all sensors to gateway (they will be created as child devices)
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
}
void loop()
{
int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
Serial.println(lightLevel);
if (lightLevel != lastLightLevel) {
gw.send(msg.set(lightLevel));
lastLightLevel = lightLevel;
}
// get the battery Voltage
int sensorValue = analogRead(BATTERY_SENSE_PIN);
Serial.println(sensorValue);
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
// 3.44/1023 = Volts per bit = 0.003363075 - changed without ref volt
float batteryV = sensorValue * 0.00305734;
int batteryPcnt = sensorValue / 10;
Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
if (oldBatteryPcnt != batteryPcnt) {
// Power up radio after sleep
gw.sendBatteryLevel(batteryPcnt);
oldBatteryPcnt = batteryPcnt;
}
gw.sleep(SLEEP_TIME);
}
Do some debug on the node and on gateway and check if data is actually sent from the node and received by gateway. Also use wait instead of sleep if you are using it as a repeater and relay actuator.