Introduction: Compost Sensor


This is a tutorial on building a Compost Temperature monitoring system. It details how to build a web connected wireless sensor network and shows one possible way it could be constructed.

A Medium level of knowledge and skills are required. Basic knowledge of soldering and breadboarding will be very useful. I will assume that you know enough Arduino code to understand what a Function is, how a Library is useful, and why Serial Communication is important. And you will need to know enough electronics to understand what I mean with terms like Voltage, Current, Resistance, etc. A (very) basic knowledge of how radio works would also be useful for understanding the concepts, but not essential for following along. This is not advanced by any means and I will attempt to always reference materials that will cover these concepts in greater detail.

This tutorial is not about building a polished final product. I am going to assume that you are accompanied by some basic fabrication skills and are capable of doing some problem solving in this area. I will show an example of my project at the end, but I will not be talking extensively on housing design or fabrication. This will be purely about the code and electronics to get up and running with the various communication types, sensors, and data storage. That being said, by the end of this tutorial you will have a web connected sensor network working on your breadboard. Putting it into a housing will be easy after that.

Why Measure the Temperature of Compost?

"Composting is the biological decomposition of organic matter under aerobic conditions." Micro-organisms consume organic material and oxygen and create heat as a waste product. By measuring this heat you can predict decomposition rate, oxygen content (loosely), and the overall health and efficiency of your composting operation. It helps to predict when the pile needs to be turned to introduce more oxygen, when the pile is finished with its hot cook cycle, and if you have effectively killed any pathogens or weed seeds that might be present in the feed stocks. Monitoring is an important aspect to streamlining and creating a stable process and workflow to get a predictable and consistent result through each cook, improving the overall efficiency in the operation.


This project uses short range Radio and Cellular communication to get sensor data from individual probes in the compost to an online database. The hardware will be built on the Arduino platform using the Moteino wireless boards. We will be using thermistors for our temperature sensing, an Adafruit FONA cellular module for our cellular communication and the Sparkfun Data Service for our online database.

Parts List

Note: You will need an ftdi board to upload code to the Moteino's.

Sensor Node (per node):

Cellular Gateway

  • Moteino w/RFM69HW
    • This should be the same part as the Sensor nodes.
  • FONA GSM Board
    • You will also need an antennae, depending on which type of FONA board you get, either will work. I like the low profile antennae. Just make sure the Antenna you get matches the connector on the FONA you have.
  • Lithium Ion Battery
    • This can be a big or small battery depending on your design. Also might be worth considering solar charging. Voltaic Systems makes nice stuff. I used one of their products in my system.
  • SIM Card
  • Breadboard


Take a look at these before starting off.

Step 1: The Sensor Node

Building the Sensor Node

We're going to start this project off by building our Sensor Node. We'll put together the Temperature Sensor first, and then once we've tested that and it's working we'll incorporate the wireless communication. The First step is to make sure you have the all the Libraries installed.

The two you need are here:

Install those and make sure you have an FTDI adapter and the drivers are correctly installed.

Once that is done you should read this quick start guide to the Moteino, there is some helpful information there.

Once that is done, solder the header pins onto the Moteino board because we will be plugging it directly into a breadboard, and cut a piece of wire 6.83 in (743mm) long to use as our antenna. Solder it to the antenna hole on the Moteino. See the images on this page and the Moteino website for reference. Once those are soldered and you've successfully interfaced with the Moteino (try uploading the Blink sketch with the LED pin set to 9), plug it into the breadboard, connect the power and ground to the breadboard buses and we can get started sensing.


Please reference sender-temp.ino file which has the code for this part

For the temperature sensor, we are using a Thermistor. It is a simple, inexpensive and fairly accurate piece of solid state hardware. We are going to be sticking this sensor into a hot, humid, and fairly caustic environment so it is important that it is able to withstand these environmental factors.

The sensor we are using is a 10kOhm Epoxy sealed Thermistor from Adafruit, which they have excellent documentation for. The code I am using is a slightly modified version of theirs. There is no point in re-inventing the wheel, so please read through their documentation in addition to this tutorial for more information about this sensor.

The Hookup is super simple, see the schematic and images attached to this page. We'll be using Analog Input 0.

The code itself consists mostly of math that you don't need to worry about. The math part is cordoned off in its own function because it's better not to look at it. The code takes 5 readings from the Analog Input over a short amount of time and averages them to get a more stable reading (these sensors can be noisy). It then does some magic to convert that resistance into temperature which we print out the Serial Monitor.

Radio Communication

Please reference sender-node.ino which has the code for this part.

Once your temperatures are reading correctly, we will need a way of sending them to the Receiver. To do that, we are using the RFM69 Radio module, that green thing soldered to the back of your Moteino. First thing, make sure you have an antenna soldered to the antenna port of the Moteino board. Without the antenna, the range of this radio is a few inches instead of a few hundred meters. Information about the Antenna's and range can be found on the Moteino Site. All of the connections are already made for us, so we can just initialize the Library and start using it. To get started, I would suggest looking at Andy Sigler's excellent code for some super simple send/receive examples.

Getting Started

In the code so far, we sensing the temperature. What we need to do is to take the sensor value and send it across to another Moteino which will be listening for radio messages. We do that by bundling up this piece of data in a little packet and passing it over the air. This packet is called 'payload'. Once the 'payload' reaches the Receiver, the Receiver will send a quick message back saying "Got your packet, everything looks OK". This is called an acknowledgment (shorthanded to ACK in the code). If an acknowledgment isn't received by the Sender, it will wait a little while and try sending it again. If it tries 5 times and fails, it will give up. This is a really important way of creating stability and accountability in our wireless communication because we need to know if our messages are being received.

Powering it

To power the Moteino without the computer we will be using a 9 volt battery attached to the VIN pin of the Moteino. This pin sends power to the voltage regulator, which steps it down to 3.3v for use on the board.

Power Consumption

Because these sensor nodes are battery powered, power consumption is a really important factor to take into consideration. This is a a bit beyond the scope of this tutorial, but I am going to discuss broadly here. The existing circuit, as you will see should work fine as is, but there is room for optimizations. Each different component consumes some amount of power. I did some current measurements really quickly with a 9V battery powering the Moteino.

  • a blank sketch:
    • 24mA * 9V = 0.216 watts
  • with the microcontroller sleeping (and the radio on):
    • 16mA * 9V = 0.144 watts
  • with the radio sleeping (and the µC on):
    • 7.5mA * 9V = 0.0675 watts
  • with both radio and µC sleeping:
    • 4µA * 9V = 0.036 milliwatts
  • with both sleeping and the thermistor plugged in:
    • 0.16mA * 9V = 1.44 milliwatts

You can see here that the biggest hogs of power are the microcontroller and the radio (obviously). Both of those we can put to sleep and reduce the power consumption dramatically. We are unfortunately stuck with the Thermistor consumption without some more advanced circuitry. We use the library made by jeelabs which has a great function called Sleepy. I use it so much I extracted it and made my own library so that I can use just that one function without any of the other stuff. It is here in my github. Sleepy basically just replaces the delay() function.

In the end we are left with a circuit which consumes a nominal ~ 1.5 mW at 9v. A typical 9 volt battery alkaline battery has a capacity of 565mAh, which is 5 watt hours. Our sensor consumes at a rate of 0.0015 watt hours. A good rule of thumb with batteries is that only 50% of their rated capacity is actually usable. That leaves us with 2.5 watt hours of available capacity. From these estimates, we should expect a lifespan of about 1600 hours, or about 2 months, which is completely reasonable for the scope of this project. This, of course, is not taking into consideration the self-discharge rate of the battery.

Now that we have a sensor that can live on its own for a length of time, it's time to build something that receives its messages.

Step 2: Building the Reciever

Building The Receiver

Please reference receiver-node.ino which has the code for this part.

The receiver code will look very similar to the Sender code. Many of the same variables are used. The one primary difference between the receiver and the sender is that the receiver spends all of its time listening. Because of this it will consume more power. It also is connected to a GSM Module, which is pretty power hungry, but more on that later. First we will get the two radios talking.

Radio Receive

The radio is initialized, and then it starts listening. If any messages are received, it will get them and check to make sure the packet is exactly what is expected. If the packet is good, it saves the values out to global variables and Serial.println()'s them.

Upload this code and open the Serial Monitor and then power on the sender-node which you've already built. You should see the messages as they come in.

Step 3: Online Database

Setting up the Database

For the data storage, we are going to be creating an online database using the Sparkfun Data Service. This is a pretty easy process which is documented in the images. In the end we will have a place online to store our data which we can reference from different places on the internet (for building visualizations), or just to download. Take a look at the notated images in this step to get started.

We are setting up a database with three values, Temp, Heartbeat, and ID, mirroring the three values we are getting from our sensors. To input these data into the database, we simply send a URL in this format:[publicKey]?private_key=[privateKey]&heartbeat=[value]&id=[value]&temp=[value]

The values in the URL will be input and stored in the appropriate columns. We can send this URL from any device that is internet connected, like a computer or a wireless Cellular Module somewhere in the world. It doesn't matter where it is, only that there is reliable cell service. That's pretty neat, right?

So get your data service set up and test it out by putting that URL with the values filled into your web browser and trying to go to it. You should get a response that says: "1 success". Now look at the[publicKey] page and you'll see the numbers you inputted there.

We now have a place to put our data. Next we will set-up the GSM Module and start sending data wirelessly.

Step 4: Cellular: Part 1

Setting up the GSM:

In this section we will take the information that we are collecting from our sensors, store it temporarily in the Moteino using an array, and then uploading that array of data to the database over our cellular GSM connection.

Disclaimer: This GSM stuff can get a little complex and overwhelming at times, especially if things stop working exactly like they should. I've done my best to make it as simple a process as possible but please take a break and come back to it if stuff stops working right.

The GSM module we are using is the Adafruit FONA board, which has some pretty good documentation on the Adafruit website as well. I wrote another Instructable which uses a lot of the the same technologies about making a location logger using the FONA and the Sparkfun Data Service, which might be useful to look at as well. I will try not to repeat too much information, as much of this process is very similar.

I use a Serial Monitor called Cool Term, which is a better way of talking to the FONA. Using the Arduino IDE can cause mystery trouble sometimes when communicating with GSM modules. Sparkfun wrote a great tutorial on how to use it, so I won't repeat the information. Just please make sure Line Mode is enabled, it will make your life better.

Setting up the FONA

The first step is to setup the FONA on the breadboard and connect it to the Moteino. The connections here are slightly different from Adafruit's, so keep that in mind while looking across documentation and code.

The connections are as follows. Also reference the included image and the schematic.

  • Vio connects to 3.3v
  • GND connects to GND
  • RX connects to digital 3
  • TX connects to digital 4
  • RST connects to digital 5
  • Key connects to digital 6
  • PS connects to digital 7

Powering it up

Once all of the breadboard connections are made, insert your sim card, plug in the battery, plug the FONA into the breadboard and press and hold the little button until the blue light comes on. After it powers on, there should be a red light that blinks about once every second. This means there is a good cell connection and the Module is powered up and ready to receive commands.

Testing the connections

Please reference receiver-FONASerialTest.ino which has the code for this part.

The FONA communicates via a Serial Connection. Because we need the hardware Serial port to communicate between the Moteino and the computer, we will have to use the Software Serial Library to create a new software Serial port on the Moteino.

The included code will allow you to test the Serial Connection with the FONA. All it does is translate all characters between the hardware Serial ports (Computer <--> Moteino) and the Software Serial Ports (Fona <--> Moteino). This allows us to send messages from the Computer to the FONA through the Moteino.

Upload the code and then connect CoolTerm to the Moteino.

Try typing:


into the CoolTerm command line and press enter. It should respond back with a message that says:


Once you get an OK, you know that all of the wiring is correct and we are ready to go onto the next step. If you don't receive an OK, make sure all of the connections are correct and the FONA is on.

What is an AT Command?

The GSM Module (FONA) responds to what are known as AT Commands, which are text commands that initialize certain functions within the GSM Module. The module is a little computer in itself that can do a lot on its own.

The command syntax is like this:

  • Test Command: AT+=?
    • returns a list of parameters or value ranges that you can set with the command
  • Read Command: AT+?
    • Returns the current set value of the parameters of that command
  • Write Command: AT+=<....>
    • This command sets user definable parameter values
  • Execution Command: AT+
    • Executes a command without user definable parameter values
  • For a short list of useful commands you can reference the Adafruit page on the FONA.
    • Try out all of these commands. It’s pretty cool! Try making a phone call or sending a text!
  • For a compendium of all the commands the datasheet is here.
    • get your IMEI number: AT+CCID
    • get your signal strength: AT+CSQ
    • get your subscriber info: AT+COPS?

To Make a GET Request...

To make a GET request you will need to execute this following commands in this order.

  • First we setup the GPRS: NOTE: You will need to have your APN for you cell plan at this point, please reference the SIM you got for this project.
    • AT+CMGF=1
    • AT+CGATT=1
    • AT+SAPBR=3,1,"APN","your apn here"
    • AT+SAPBR=1,1
  • The we setup HTTP and make the request: NOTE: you will be using the Sparkfun URL ([publicKey]?private_key=[privateKey]&heartbeat=[value]&id=[value]&temp=[value]), you can just input any random values for the data for now. The HTTPREAD command should come back with a message of 1 success if it is correctly formatted and goes through and you should be able to check the website and see that it has been updated.
    • AT+HTTPPARA="URL","your url here"
  • Then we close the HTTP and the GPRS
    • AT+SAPBR=0,1

Try doing this a couple times. Make sure it works every time. Getting this process as foolproof is possible will make the next steps much easier and straight forward. Debugging the GSM commands in code is an eternally frustrating process.

Step 5: Cellular: Step 2

Step 2: Automating the process

Putting it into code

Please reference receiver-gateway.ino which has the code for this part.

We have connected the FONA to the Moteino, tested the connections between those two, and also tested the GSM connection by manually making a GET request from the Serial Monitor. The next step is to automate that process from turning on the FONA, to making the requests, to turning off the FONA. The automated power-on/power-off is really important because the FONA consumes a lot of power in standby, and as with our sensor nodes, if it doesn't need to be on, it shouldn't be. To turn on/off the FONA we can use the KEY pin. If we pull it low for 2 seconds, it will turn on/off the module.

How it works

The Moteino is always listening for incoming packets from the sensors. When the Receiver receives a packet from a Sender, the Receiver stores the values into an Array. Each Sender has its own array which is overwritten each time sensor data is received from the Sender. While this receiving is happening, the Receiver is keeping time. Once a predetermined amount of time (15 minutes) has passed, the Receiver stops listening for radio messages and starts the process of uploading the data its collected.

The Moteino turns the FONA on, waits till it is powered up, sends all of the AT commands to initialize a GET request, assembles and sends a GET request for each Sender which has sent data to the Receiver. Once that is done, the Receiver shuts down the FONA, turns it off, and then goes back to listening for Radio messages. While the Receiver is sending data to the database, it will not receive radio messages or acknowledgments. This is why the Sender ACK time is set to approximately how long it takes the Receiver to do the full sequence of events with the FONA.

Upload the code and test

Now comes the big moment. Set the timing variables to be what you want in the code included with this section and upload it to the Moteino. Plug in one of your Sender nodes so that it is sending data and connect the Serial Monitor to monitor the process. For each successful recieved message from the sender the values should be printed out. When the FONA turns on after 15 minutes (or whatever it is set to) it should print its status as it goes. There should not be any errors. When it's done, check your sparkfun data stream and make sure it went through ok.

If it did, it's time for celebration because all of the hard parts are done.

Powering it

So far, we've been powering the Receiver with a USB cable and a battery plugged directly into the FONA board. This isn't going to work if we were to deploy this in the field, but there are other options. You'll notice that there is a BAT pin on the FONA, which is a direct tap to the Battery Connection. This means that if there is a battery plugged into the FONA, you'll be able to get a direct connection to the battery to power other things, such as the Moteino. In addition, you could plug a battery into that pin instead of using the connector on the FONA board.

In my build of this project, I used a (slightly modified(improved)) Voltaic Battery and Solar Panel to power the Receiver unit. Because the Receiver does consume more power than the Sender/sensor nodes it will need both a bigger battery and way of recharging it for long term use. I show some pictures and talk more about this modification in the next section.

Step 6: Final Steps

Final Steps


The final steps for this project is to make a housing for it, which I am not going to comment on too much. The housing is fully up to the builder with a couple of caveats. Radio signals do not travel well through metal, so the housings should not be metal. The thermistor is dipped in epoxy, so it is well protected. You could easily extend the wires, and staple the thermistor on the end of a stick and it would probably be fine. The battery and Moteino should be protected from the weather in some sort of plastic housing. A tupperware would work, so would PVC plumbing parts, as would a small dry-box. As for the receiver, I used a small pelican case and it was perfect. It highly depends on what climate it is going to live in and how protected it will be.

Look at the next step where I document my build to give you inspiration for the housings.

Web App

I am not a web developer, but I was able to build a rudimentary set of graphs to display this data. I follows this tutorial. Explaining how all of this works is way beyond my skill level. My visualization is on this webpage, and all of the code is on my github.

Step 7: Epilogue


My build

This Instructable came about from my thesis project at ITP. I quickly prototyped it using this exact system but went on to design and fabricate my own circuits and circuit boards and do some other custom fabrication that is out of the scope of this tutorial. I also added some additional features to the Gateway, such as a screen, a button interface, and a way of monitoring the battery voltage. Most of these added unnecessary complication and never really worked right, except the battery voltage monitoring, which was actually very helpful.

My sensors

For the sensor probes, I designed a simple Arduino clone using an at328 microcontroller. It is very similar to the Moteino, only with an onboard boost regulator and a couple custom touches. It was powered by two AA batteries and a boost regulator I designed. The sensor I ended up using was not a thermistor, but a Sensirion SHT21 which is a Temperature and Relative Humidity sensor. I was interested in getting moisture readings in addition to temperature. The housings I made from pvc plumbing pipe with a couple custom made parts.

The Cellular Gateway

For the gateway, I added a screen so the sensor data could be viewed at the composting site and a button to interact with the screen. For power, I used a Voltaic solar panel and battery. I modified the battery slightly, opening it up and attaching a wire directly to the battery to power the FONA board (because it needs a direct Li-Ion cell to power it), and then using the 5v output to power the rest of the circuit. Doing this worked GREAT and I highly recommend it.


There were a few main challenges to this design. The major one was the moisture sensor. It is a relative humidity sensor, so it measures moisture in the air and can't just be shoved into the dirt like a thermistor could be. Designing a way of protecting it from contaminates proved to be challenging, and I ended up placing the sensor inside of the pvc tube, drilling a hole in the tube and covering it with a Tyvek membrane. Tyvek is vapor-permeable, but durable and almost waterproof. If I did this again, I would just use a thermistor and not try to be fancy. This whole system would work just as well with a thermistor on a stick and you wouldn't have to worry about protecting a delicate sensor. The other challenge was calculating the power consumption of the gateway circuit and getting a battery and solar panel big enough to power it. I'm using a 4000mAh battery and a 3Watt panel, and the system can run for 4-5 days without direct sunlight and will charge 25% of its capacity with only 2 hours of direct sunlight. This is great for the intermittent weather of NYC. If this system was to be built in a more consistently overcast area, the builder would need to getting a bigger solar panel.

My Github has all of my circuit designs and code here.

A full explanation and project description is on my website.

Please contact me either via email or through the comments below if you have questions or concerns about this design or project or if you would like consolation or consultation for building your own system.