I've expanded the type of monitoring I do on our local creeks. Initially, I started with basic water temp - see my Salmon Stream Monitor project. Then, I manually started conducting water chemistry related tests - alkalinity, pH, hardness, etc. Now, I want to start doing bacteriological monitoring - primarily E. coli and secondarily other coliform bacteria. However, in order to be able to count the bacteria, I need to incubate the samples at a temp of 29 to 37 degrees Celsius for 30 - 48 hours.
I could purchase a basic Styrofoam incubator for about $80, but they aren't "smart". For much less, I can not only make my own but also make it Internet connected. An IoT incubator could report the temperature regularly and send me email or SMS messages if something goes out of range.
The incubator is made up of a couple of heating pads, an fan, and temperature sensors all of which are controlled by a microcontroller. Everything but the microcontroller is placed in a disposable Styrofoam cooler. The microcontroller turns the heating element off/on to maintain the set temp and the fan circulates the warm air to keep the entire cooler at relatively the same temp. Temperature data and heater status (off / on) are sent to the cloud every minute. Alerts are sent to my phone from the cloud platform if something goes out of range.
For the hardware, I chose SparkFun's ESP8266 Thing Dev board. I've used it before so I not only had one on hand but also already have the Arduino IDE set up for it. The SparkFun Thing Dev has WiFi capabilities, more than enough GPIO pins, and an analog digital converter (ADC).
For temperature sensors, I mixed and matched based on what I had on hand. I used two DS18B20 temperature sensors (digital) for inside the incubator (one at the top and one at the bottom to determine if there was a large temperature variation within the incubator) and one LM35 temperature sensor (analog) for ambient temperature.
For the cloud side of things, I chose Ubidots. I liked their feature set and it was easy to integrate with their platform. They also have their own libraries for a variety of microcontrollers but I already had MQTT setup on my ESP8266 using Nick O'Leary's Arduino client for MQTT so I merely had to change the address of the MQTT server and add my Ubidot's security token to the connection string.
I wasn't sure whether I would need the fan but it turned out to be a key component. The fan serves two critical roles. First, it moves the heat from the heating pad into the incubator. Even though the surface of the heating pad can get quite warm - more than 50 degrees Celsius - the air just a few millimeters away from the heating pad remained in the high 20's. The air flow from the 30mm x 30mm fan is less than 3 cfm but it was enough to distribute the heat into the area around the heating pad. Second, the fan circulated the air through the entire incubator which results in less than a 1.5 degree difference between the bottom of the incubator and the top (12 inches away from the heating pads). I had planned to turn the fan on and off in lock step with the heater but soon realized that the fan needed to be on all the time to keep the air circulating.
I started with a single heating pad but even though the 5x10cm pad is using about 11 watts (9v and 1.2a), I couldn't get the incubator temp much over 33 degrees. Even though that could work, I added a second heating pad to give me some head room. With two heating pads, the incubator reaches operating temperature (33 degrees) in less than 10 minutes and has a max temp of 39 degrees C.
A 9v power supply is used to power the heating elements and 5v is used to power the microcontroller and the fan. Darlington transistors are used to switch the heaters on and off based on the output signal from the microcontroller's GPIO pins.
I found both types of temperature sensors easy to use. When using the LM35, the key to converting the analog signal to a temperature is knowing the analog reference of your microcontroller. The ESP8266 Thing's ARef is different that the Arduino's (which was used for most of the examples I found online) so I needed to adjust the formula accordingly. The nice thing about the DS18B20 temp sensor's is that you can run several sensors on the same GPIO pin; the 1-wire protocol required for the DS18B20 seems to be well supported across a variety of microcontrollers so that wasn't an issue.
PrerequisitesHere are some items you need to take care of before starting the project:
- Add support for SparkFun's ESP8266 Thing Dev board to the Arduino IDE.
- Add the Arduino client for MQTT library to the Arduino IDE.
- Create a free account on Ubidots.
This project isn't a getting started guide for the ESP8266; there is quite a bit of information available online about these devices and Sparkfun's tutorial for the Thing - Dev Board (the specific ESP8266 board I used for this project) is more than sufficient to get you started. The Sparkfun tutorial also has detailed instructions for adding support for ESP8266 boards to the Arduino IDE so follow those if you need help getting your development environment configured properly; I had no problem getting the SparkFun ESP8266 Thing Dev board working with the Arduino IDE version 1.6.8.
Nick O'Leary's Arduino Client for MQTT - aka PubSubClient - is available via library manager so install it that way. If you aren't familiar with the IDE's library manager, Arduino has documentation on how to use it.
Ubidots has several pricing tiers but the free tier is more than sufficient for this project. You can create an account at http://www.ubidots.com.
Build InstructionsStep 1 - Wiring the incubator
Time: 10 minutes
Wiring the incubator consists of connecting the various components - heating pads, temperature sensors, and fan - to the microcontroller. As I mentioned in the summary, I realized that I needed to keep the fan on all the time so instead of controlling it with the microcontroller, I just wired it directly to the 5v power supply. The temperature senor wiring is relatively straight forward; all the temp sensors have a 5v power and ground connection. The LM35 also has a signal connection to the microcontroller's ADC pin while the DS18B20's signal wire connects to a digital pin. Both the DS18B20 sensors can all be connected to the same pin as the 1-wire protocol is able to address each sensor individually.
The heating pads are controlled by the microcontroller but they require much greater power than the microcontroller can supply so I used Darlington transistors. The transistors enable a very low currrent signal (off/on) from the microcontroller to switch the high current to the heating pads (each pad pulls about 1.2 amps at 9v). A 1k ohm resistor connects the microcontroller's GPIO pin to the Darlington transistor's base. The transistor's emitter is connected to ground and the collector is connected to the heating pad's ground terminal. The heating pad's positive terminal is connected to the 9v rail. When a small amount of current is applied to the transistor's base, a large amount of current is allowed to flow from the emitter to the collector which turns on the heating pad.
I connected the heating pads, fan, and temp sensors with about 3 feet of wire so that I could easily place all those elements inside the incubator while keep the microcontroller outside it.
Step 2 - Setup Ubidots back end
Time - 10 minutes
I am still learning my way around Ubidots so there may be other ways to setup the backend but this is how I did it. First, I created a data source named 'incubator'. Then I added four variables to the 'incubator' data source so that I could track various aspects of my incubator - ambient temperature, bottom temperature, top temperature, and heater status. Ubidot's data source seem to be the same concept as an MQTT topic to which you publish data. And, variables are the data elements you want to track within each topic.
One thing to note is that the code references data sources and their variables using their labels - not their names. Here are the labels I set up for each element:
Element Type: Name: Label:
Data source Incubator incubator
Variable ambient temperature amb
Variable bottom temperature bot
Variable top temperature top
Variable heater status heat
In addition to viewing the data for each variable, you can create graphs on the dashboard. I created a basic line graph and plotted the bottom temperature and the top temperature so that I can easily see what's going on in the incubator.
Step 3 - Edit and Deploy the Sketch
Time - 10 minutes
You can download the sketch from the GitHub repository. Before deploying it to the ESP8266 Thing Dev board, you'll need to edit a few variables via the Arduino IDE. First, enter the connection information for your WiFi network.
char ssid[] = "<enter_network_name>"; // your network SSID
char pass[] = "<enter_password>"; // your network password
Next, enter your Ubidot's token in order to authenticate to the service. The Ubidot's token is entered as the username parameter in the connect() function - the password parameter is left blank.
if (client.connect("mqtt://things.ubidots.com", "<your_ubidots_token>", ""))
Serial.println("connected");
Finally, if you used different data source and variable labels, you will need to update the topic parameter in the publish() function and the JSON object names accordingly.
void sendToCloud()
{
// construct the JSON object
message["amb"] = lm35Temperature;
message["bot"] = temperature[0];
message["top"] = temperature[1];
if (heaterOn)
message["heat"] = 1;
else
message["heat"] = 0;
// convert JSON object to string
message.printTo(msg, sizeof(msg));
Serial.print("Publish message: ");
Serial.println(msg);
if (client.publish("/v1.6/devices/incubator", msg))
Serial.println("Publish successful");
else
Serial.println("Publush failed");
}
Once you deploy the code, open the Serial Monitor to ensure that the ESP8266 Thing Dev board successfully connects to your WiFi network and that the MQTT client successfully connects to Ubidot's MQTT server. If everything is working properly, you can go to the Ubidot's dashboard or view the data source to see your data.
Comments