How Wet Can Ya Get? Let’s Get Muddy!

Div­ing deep­er over at Meteo Sci­en­tif­ic on this plant nurs­ery project, we want­ed to blast out of the gate with some­thing we thought would be incon­tro­vert­ibly use­ful. For a nurs­ery in the coastal desert envi­ron­ment of San Diego (albeit with local microm­e­te­o­ro­log­i­cal con­di­tions), keep­ing track of soil mois­ture in all the pots seemed like a good start.

With that in mind, Dirk had found a cool soil mois­ture sen­sor over on Mak­er­Fabs that runs about $20. It’s the V3 ver­sion, which is All In One (AIO for you cool cats). That means it’s a sen­sor and a LoRa radio, not just a sen­sor which you’d have to con­nect to some­thing like a Wis­block. BFGNeil explained that one to me. 😉


  • Buy sen­sor. Geek lev­el: N/A
  • Add device (the sen­sor) to Heli­um Con­sole. Geek lev­el: Minor
  • Add bat­ter­ies (2 x AAA). Geek lev­el: N/A
  • Upload Arduino sketch to sen­sor (sig­nif­i­cant geek­ery involved, but I’ll walk you through it). Geek lev­el: High
  • Set up Home Assis­tant. Geek lev­el: High, walk through of that over here.
  • Add Soil Mois­ture sen­sor to Home Assis­tant (HA). Geek lev­el: high
  • Rejoice at suc­cess: Geek lev­el: N/A

Ok, so here’s the thing in its pack­age. Very fan­cy looking. 

Once you get it out of the pack­age, there are only 4 things in there; the device, 2 pieces of the pro­tec­tive cov­er, and a small bag of screws. It needs AAA bat­ter­ies, so make sure you have some on hand!

Oh, while you’re prep­ping, remem­ber to add the device to your Con­sole before you real­ly get start­ed. By the time you’re done fid­dling with the tiny bits it should have passed through the XOR fil­ter and be ready to roll!

Beep beep: Arduino Time!

Now that you’ve done the easy stuff, let’s get stuck into the shit­kick­er of the geek world, Arduino. If you’ve nev­er used Arduino before I’ma give you a heads up: There WILL be hic­cups. This is not plug and play stuff. Pro­fes­sion­al geeks love things that only work when you know what you’re doing. I find it both frus­trat­ing and entic­ing, which is why I write these guides. I want to help trig­ger your inner geek with­out it being too frustrating. 

Let’s go over the 30,000′ view of what we’re doing with Arduino and this sen­sor, then we’ll dive into the details.

In broad strokes, you’re load­ing a pro­gram onto this sen­sor that tells it what to do, what to send, where to send it, and how often to send it. That pro­gram uses “libraries” from the Arduino ecosys­tem. Those libraries are oth­er pro­grams that the pro­gram you’re going to load refers to. In order for this thing to work, you need every library that the pro­gram calls for installed on your computer. 

This next part will gob­s­mack you: It is NOT com­mon prac­tice amongst Arduino pro­gram­mers to let you know up front the full list of libraries you’ll need. The ones who are try­ing to be help­ful will, but usu­al­ly you’ll get a list of the spe­cial ones they used, not all libraries nec­es­sary. Typ­i­cal­ly, the way enthu­si­asts find out what libraries they’re miss­ing is to run the code and see what error mes­sages come up. 

Once you load a library on your sys­tem, it’s there, so you don’t need to load it again. That fea­ture makes it easy for some­one who’s been work­ing in Arduino for a while and already has a bunch of libraries loaded. It makes it real­ly dif­fi­cult when you’re first start­ing; you’re con­stant­ly find­ing that you need anoth­er library. It’s kind of a trea­sure hunt, which is prob­a­bly why the geeks like it; it’s pure prob­lem solving.

This whole “trea­sure hunt” style of get­ting things done is super com­mon in this world. You take a few steps for­ward, you hit a wall, you look around, you go back and look at the map, in the bot­tom right cor­ner you see the clue that’s upside down and spelled back­wards that gets you over the wall, and you repeat that until you get to where you want to go. So, with that as the back­ground, and my promise to you that I’ve found almost all of those clues and removed as much fric­tion as I can, let’s get started!

You’ll need to down­load the Arduino IDE, or Inte­grat­ed Devel­op­ment Environment. 

Let’s start with set­ting up your IDE cor­rect­ly. We’re going to tell it what kind of board you’re using. In this case the soil mois­ture devices uses an Arduino Pro or Pro Mini. You can fol­low along over on the Mak­er­Fabs page for this sen­sor, which is where some of this info comes from. This is what it may look like if you’re on a Mac.

If you don’t have that already set up, you’ll need to add the “Arduino Pro or Pro Mini” set to your app. 

Next, let’s add the libraries you’ll need. In the Arduino app, go to Tools –> Man­age Libraries, then type in the Library name you want to install. In the exam­ple, I’m using the MCCI LoRaWAN LMIC Library.

When I took the screen­shot, I’d already installed it. If you don’t have it, hit the Install but­ton and watch the mag­ic hap­pen. Here are the oth­er ones you’ll need:

If you type in a Library and it does­n’t show up in the Library man­ag­er, you can always man­u­al­ly install it by going to the link above, look­ing for the green Code but­ton, then using the drop­down to down­load the zip file. 

Once you have the zip file, in Arduino –> Sketch –> Include Library — Add .ZIP Library and fol­low the prompts.

With the right libraries installed, go to Dirk’s Github repos­i­to­ry (“repo” is what the cool kids say) and look for “HeliumMakerfabsSoilMoistureV3”. That’s the Arduino “sketch” you’re going to use.

Open it up, copy the code, then paste it into a code edi­tor. I use Sub­lime Text for my code edi­tor so I can change the DEVEUI, APPEUI, and APPKEY, and also so I have a work­ing copy on my computer.

In the sketch code, start­ing at line 74, look for where you’ll replace the APPEUI, the DEVUI, and the APPKEY. Those are nor­mal­ly pret­ty straight­for­ward, but in this case you’ll need to make one mod­i­fi­ca­tion before you copy them from the Heli­um Con­sole. You’ll need to change the for­mat to “lsb”. To do that, go to the device in Con­sole and, left to right, hit the box­es out­lined in red below. Once you have the 0xDC 0xDE etc for­mat, copy that and paste it into the sketch.

You want “lsb” for the DEVEUI and APPEUI, and “msb” for the APPKEY. Why? Because mak­ing shit com­pli­cat­ed keeps the fluff off.

With a sketch made that’s cus­tomized for your device using your DEV/APP/KEY, now you have to load it. This is the least reli­able part of the whole process; it takes me 2–20 times to get it right. Now, it’s pos­si­ble that it’s much eas­i­er with the rec­om­mend­ed USB to ser­i­al con­vert­er, but I used what I had on hand, which requires that you restart the device at exact­ly the right time while keep­ing the cables firm­ly connected. 

You’ll need to hold down the RST (reset) but­ton, press upload in Arduino IDE, wait until the sta­tus shows “upload­ing”, and with exquis­ite tim­ing, imme­di­ate­ly release the RST but­ton. Not easy, but you can do it. Just keep trying.

You’ll know your sketch is uploaded when you see the Writ­ing, Read­ing, and avrdude done print out on the Arduino app, like this:

With your sketch uploaded, watch on Heli­um Con­sole to make sure you’re get­ting a Join Accept/Request and a down­link. Once you see that, you know you’re con­nect­ed. It may take any­where from 2 to 50 attempts for that to go through. I found that hit­ting the reset but­ton the sen­sor every time it did­n’t go through sped up the process, but it was­n’t very reliable.

Now you’ll need to cal­i­brate the device at the wet and dry points. To do this, use Heli­um Con­sole’s debug­ging tool and the device’s reset but­ton. Open up the Debug tool by hit­ting the lit­tle black bug but­ton. With the unit total­ly dry or total­ly wet, hit the reset but­ton. This’ll force through a read­ing that you can get a pay­load for. Reset the Debug tool each time, then hit the Reset but­ton on the device and wait until you see a Decod­ed Pay­load, then expand Inte­gra­tion Mes­sage and look for ADC

You want the device wet right up to the line that says “Put this part to soil.” You may find if you test that you get dif­fer­ent val­ues with sat­u­rat­ed soil vs water, but water is way eas­i­er and clean­er, and the dif­fer­ence is prob­a­bly with­in the accu­ra­cy para­me­ters of the device.

I did three cycles of ful­ly wet and ful­ly dry, then aver­aged ’em out to get a high val­ue (Air Val­ue) and a low val­ue (Water Val­ue) I could enter into the sketch. 

Once you have those, update your sketch’s Air Val­ue and Water Val­ue and re-upload your updat­ed sketch to the device. 

Take a breather, you’ve come a long way! The last step here can go two ways. If you’re the only one using this data, you can push it through from Heli­um Con­sole to Home Assis­tant. That might look like this when you fin­ish up. Here are 3 plants (2 at home, 1 at the office):

Adding the data from your sen­sor to Home Assis­tant takes 3 (broad) steps. First, send the data from Heli­um Con­sole to an MQTT inte­gra­tion (details for that set­up over on this post).

Sec­ond, update your configuration.yaml file in Home Assis­tant to include the MQTT data now com­ing from the sen­sors. I’m going to copy in mine, which starts with the door open/close sen­sor from my ear­li­er blog post. That one is labeled “binary_sensor” in the yaml. You’re going to add in anoth­er one below it for the soil mois­ture device, labeled “sen­sor”. It’ll look like this. 

    - name: "Gate Sensor"
      device_class: opening
      payload_on: "1"
      payload_off: "0"
      payload_not_available: ""
      value_template: "{{ value_json.decoded.payload.DOOR_OPEN_STATUS }}"
      state_topic: "helium/xxx-YOUR-HELIUM-DEVICE-CONSOLE-ID-HERE-xxx/rx"
    - name: 'SM1 ADC'
      state_topic: "helium/xxx-YOUR-HELIUM-DEVICE-CONSOLE-ID-HERE-xxx/rx"
      state_class: measurement
      value_template: '{{ | int }}'
    - name: 'SM1 Battery'
      state_topic: "helium/helium/xxx-YOUR-HELIUM-DEVICE-CONSOLE-ID-HERE-xxx/rx"
      state_class: measurement
      device_class: voltage
      unit_of_measurement: "V"
      value_template: '{{ | float | round(2) }}'
    - name: 'SM1 Humidity'
      state_topic: "helium/helium/xxx-YOUR-HELIUM-DEVICE-CONSOLE-ID-HERE-xxx/rx"
      state_class: measurement
      device_class: humidity
      unit_of_measurement: "%"
      value_template: '{{ | float | round(1) }}'
    - name: 'SM1 Soil Moisture'
      state_topic: "helium/helium/xxx-YOUR-HELIUM-DEVICE-CONSOLE-ID-HERE-xxx/rx"
      state_class: measurement
      device_class: moisture
      unit_of_measurement: "%"
      value_template: '{{ | float | round(1) }}'
    - name: 'SM1 Temperature'
      state_topic: "helium/helium/xxx-YOUR-HELIUM-DEVICE-CONSOLE-ID-HERE-xxx/rx"
      state_class: measurement
      device_class: temperature
      unit_of_measurement: "°F"
      value_template: '{{ | float  * 9 / 5 + 32 | round(1) }}'

As you can see, you’ll need to enter in a “state_topic”. You’ll find that in Heli­um Con­sole in the Device page. It’ll look some­thing like this: 

With the yaml file updat­ed, go ahead and refresh that in Home Assis­tant. Devel­op­er Tools –> Man­u­al­ly Con­fig­ured MQTT Entities.

Ok, so now that Con­sole is send­ing it and HA is receiv­ing it, the third step is to make it vis­i­ble for ya.

Cre­ate “cards” in Home Assis­tant to show you what’s going on. Go to Overview –> 3 dot menu –> Edit Dashboard

Now hit “Add Card” (blue but­ton in bot­tom right) and search by name, then fol­low the prompts to show what you want to see. You prob­a­bly want Enti­ties or Sta­tis­tic Graph, but it’s up to you.

That’s it! You’re all done if all you want to do is see it yourself.

If you’re plan­ning on shar­ing the data with some­one else (a client, or your fel­low geeks), con­sid­er UplinkEngine, which is a com­pa­ny I invest­ed in back when it was still just HeliumVision. 

They’re cur­rent­ly doing just bespoke solu­tions that look like this. I’ve out­lined the sen­sor in red, and you can dis­play the stats how­ev­er you want, this is just what we’ve got going right now.

How­ev­er you dis­play your data, if you’ve fol­lowed this whole thing through, con­grat­u­la­tions! You’ve added one more sen­sor to the Heli­um net­work, learned a ton, and hope­ful­ly will be able to keep your plant in top hydrat­ed condition!

Rock on,


Notes & References

Work­ing instruc­tions for geeks here:

Orig­i­nal Project here:

Deni­co­la V3 decoder:

Use­ful notes spe­cif­ic to Heli­um here:

Arduino is writ­ten in C++, so if you’re look­ing at it on the Sub­lime Text app, set the View to be C++.

In Arduino sketch, line 261 is “Air Val­ue”. With the sen­sor bone dry, record the ADC dis­played in Home Assis­tant and enter that as your Air Val­ue. It’ll be close to 850.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.