Soil moisture sensor


My new soil moisture sensors based on the RFM95, ATtiny84a and the capacitive SoilWatch10 soil moisture sensor.


The enclosure is 32mm pvc pipe and 3D printed parts.


The antenna is a J-Pole made from 2.5mm VD Cable.



These sensors are placed in my allotment +/- 3km outside of the city and every hour I receive their values.


With a flow in nod-RED I made the dashboard and I use WallPanel for my Android phone and a Pushover node sends a message if the plants needs water :wink:


Interesting work, but not recommended for use with TTS CE - no downlinks means no ADR.

An ATtiny3216 in SOIC format is a third of the price of an ATtiny85A and has the capacity to run the latest version of LMIC which works with TTS. You can hand solder it to your own design PCB or use one of the adapter PCB’s from the usual sources.

Yes, too bad, I still have a few of these old ones on the shelf. For those I may have inspired take a look at ATtiny3216

Hi Marco,
thanks for sharing!
I am currently looking for something similar (Soil moisture , Temp, Humidity measuring - remote location with no power supply and no Wifi nearby but TTN)
I am just starting into the TTN world :slight_smile:

Do I get this right that your link posted in the last post provides everything required but with the improved Attiny 3216?
Any reason why you did chose this specific soil moisture sensor?

Any longterm results (sensor accuracy, failures, etc)?


Hi Eckhard,

Yes, the ATTnodes are complete but with such a sensor it is recommended to use a rechargeable battery as you can see I also use an AA LifeP04 (3.2V 700mAh) battery taking into account the max. voltage of the RFM95.

The SoilWatch10 sensors are left over from another project and these are capacitive instead of resistive sensors. Capacitive are more accurate and do not suffer from corrosion.

For several years I have a sensor for temperature and humidity (BME280) in my greenhouse but that humidity sensor is actually not suitable and at the moment it is broken again.



i also use a BME280 and the humidity Sensor got problems when outside for a longer time in high humidity. Think it is a corrosion problem.
I now use the BME only for pressure and temperature - for humidity i added a GY21 Si7021. It has a build in heater that can be used a few seconds every Minute to prevent condensate.
That one is doing fine now for a long time.

1 Like

Hi Marco,
I would like to build your Device using Attnode3. Do you know where to get the PCB? As I am also not good in soldering SMDs a pre-populated PCB at least with the SMDs required would be also fine.

Thanks in advance

Have a look at . Maybe Steffen can help you.

I ordered my pcb’s from Great pcb’s and good price.

So is it ok to use the PCB layout and send it to JLCPCB (no IP issues?)? They even offer to solder SMDs on it. That would be great! I have heard about JLCPCB but not yet ordered there.


JLCPCB works great, bigger problem is that the ATTINY3216-SN is nowhere available, or anyone got a hint where to look for them (in germany, europe)?

Farnell / Element-14 have 500+

Some clarity and a reality check:

Yes, it’s a nice little node and the DIP package for the ATtiny84a is very convenient - but this node requires you to use a code base that has had changes made to fool TTS in to believing it is behaving like a compliant node. Principally, it can not handle downlinks so has to answer as if it heard them.

The ATtiny3126 is NOT a drop in replacement for the ATtiny84a - it’s just a more up to date ATmega328P - and even then would require some diligence to get the MCCI LMiC running smoothly - something I am happy to help with - but you shouldn’t have expectations of running more than a couple of I2C sensors off it.

A better alternative would be the ATmega4808 which also comes in a SOIC hand-soldering friendly package but has 48K flash(half as much again) and 6K of memory (three times more).

Either device can be programmed using the Arduino IDE but will need their own PCB.

More info on getting this design working on TTS can be found at Node adoption for The Things Stack V3 |

To be clear, as the post author suggests, some may not be happy with this implementation. I am not saying I’m unhappy but I’m not keen on it, I’m saying that buying PCB’s for this design is like buying a brand new leaded petrol only car.

I’ll look at altering my 4808+RFM95 design for hand-soldering only and sharing the PCB asap.


sounds like a plan!
I will wait for your changes.
Could you please recommend a good source to learn/understand the 4808+RFM95 solution?


GitHub - mcci-catena/arduino-lmic: LoraWAN-MAC-in-C library, adapted to run under the Arduino environment - this is the core LoRaWAN software

And this is a very fine wrapper to simplify the LMIC but hasn’t been run against a 4808 yet:

thanks for the links!

I have now made one Heltec WiFi LoRa 32 V2 running but it is to bulky in size and it sucks up the battery in two days. (Maybe someone could guide me to a link where I can find (Using Arduino IDE) instructions how to reduce power consumption). And it is kind of expensive for the solution I have in mind.

My favorite would be a Raspberry Pi Pico solution - in combination with a RFM95W (as I am a big fan of Raspberry Pi). I have seen that the LMIC is supporting it. Any thoughts on that? I am a little bit heasitating as I am new to Pico.


Yeah, I hear that, but I’m told that it is possible to get the current down. There are posts on the forum to search for that could help.

The lowest I’ve got a Pico after altering the power is 900uA which is not good, so not really a battery powered option.

I am (literally) having nightmares with a node design at present due to the world wide shortage of MCU’s and radio modules. When (if) I come to any conclusions I’ll repost.

I finally got the Raspberry Pi Pico running but due to the decision to use CircuitPython the deep sleep mode is not (not yet, acc. to Adafruit) available. As Nick also stated, 900uA might be still to high for a battery powered node.

I also got a ready made unit from a friend of mine to get it up and running:
A Lora Soil Moisture Sensor from Makerfabs Link
It runs on a Atmega328P in combination with RFM95W.
I got it running with their firmware: Lora-Soil-Moisture-Sensor/LoraTransmitterADCAHT10 at master · Makerfabs/Lora-Soil-Moisture-Sensor · GitHub
but without connection to TTS

with the LMIC-node (My first experience with platformio :slight_smile: )
with OTAA connection established to TTS !

My challenge now is to get them both together.
I have tried to extend the LMIC-node.cpp but I was not successful

Any thoughts / hints / helpful examples to get this done?


We could suggest, but it would be simpler if you told us what you tried just in case you had a near miss.

Fundamentally you need to fish out the sensor reading bits from the first sketch and drop that in to the LMIC-node.

I have taken this from the Makerfabs Code and put it into the first USER CODE section:

#include <SPI.h>
#include "I2C_AHT10.h"
#include <Wire.h>
AHT10 humiditySensor;

int sensorPin = A2;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
int sensorPowerCtrlPin = 5;

void sensorPowerOn(void)
  digitalWrite(sensorPowerCtrlPin, HIGH);//Sensor power on 
void sensorPowerOff(void)
  digitalWrite(sensorPowerCtrlPin, LOW);//Sensor power on 

The next USER CODE Section seems to be my Problem Child. I don’t know how to get the Sensor data collected and prepared to be uploaded to the TTS:

// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
//float humidity = 6.18;//dht.readHumidity();
// Read temperature as Celsius (the default)

sensorValue = analogRead(sensorPin);

if (humiditySensor.available() == true)
    //Get the new temperature and humidity value
    temperature = humiditySensor.getTemperature();
    humidity = humiditySensor.getHumidity();

    //Print the results
    Serial.print("Temperature: ");
    Serial.print(temperature, 2);
    Serial.print(" C\t");
    Serial.print("Humidity: ");
    Serial.print(humidity, 2);
    Serial.println("% RH");

    // Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(temperature)) {
    Serial.println(F("Failed to read from AHT sensor!"));


Serial.print(F("Moisture ADC : "));

//Serial.print(F("Humidity: "));
//Serial.print(F("%  Temperature: "));
//Serial.println("Humidity is " + (String)humidity);
//Serial.println("Temperature is " + (String)temperature);

String message = "#"+(String)packetnum+" Humidity:"+(String)humidity+"% Temperature:"+(String)temperature+"C"+" ADC:"+(String)sensorValue;
    Serial.println("Transmit: Sending to rf95_server");

// Send a message to rf95_server

uint8_t radioPacket[message.length()+1];
message.toCharArray(radioPacket, message.length()+1);

radioPacket[message.length()+1]= '\0';

The last USER CODE portion (Init section) is:

  //digitalWrite(sensorPowerCtrlPin, LOW);//Sensor power on 
    Wire.begin(); //Join I2C bus
    //Check if the AHT10 will acknowledge
    if (humiditySensor.begin() == false)
        Serial.println("AHT10 not detected. Please check wiring. Freezing.");
        //while (1);
        Serial.println("AHT10 acknowledged.");

Platformio seems not have a loop section where I could put the respective code and LMIC seems to arrange the data for sending different than Radiohead.
So my data I am looking for is in the variables

  • SensorValue
  • humidity
  • temperature

And the update is done by (I assume):

  • temperature = humiditySensor.getTemperature();
  • humidity = humiditySensor.getHumidity();
  • sensorValue = analogRead(sensorPin);

Any thoughts?

Read this:

and look the code related to the payloadBuffer: