Fig 1. "Peak of Expected Inflated Expectations" |
I wanted to learn more about the IoT technology and do some concrete experiments to better understand what IoT can offer. I found the Particle Photon board that is a small $19 Arduino compatible U.S. quarter size board with WiFi enabled Internet connectivity very suitable for prototyping some IoT ideas. See fig 2. below to get a sense of the size of this tiny board. I ordered two of these just to play a bit and try to build something useful out of these.
Fig 2. Particle Photon board with and without breadboard headers |
HUMIDITY CONTROLLER EXPERIMENT
I already have some previous experience working with Arduino compatible boards such as Arduino Pro Mini that is physically almost the same size of Particle Photon. In fact I used that board to build a simple humidity controller in our bathroom. This was a quick weekend project where I prototyped on a breadboard a simple circuit with a humidity sensor, a LED indicator and a relay driver to turn the bathroom fan on and off. I assembled the prototype parts including the breadboard, sensor, relay unit and 12v/5V power supply inside an Apple mouse plastic enclosure. See Fig 3.Fig 3. Arduino based humidity controller prototype. |
With a few holes drilled on this plastic enclosure to allow air to flow over the sensor I was able to fit the whole controller inside an existing vent box, see Fig 4. below.
Fig 4. Humidity controller installed inside the vent box. |
However, I did have a problem with this simple controller. The few lines of software that I wrote in winter time when relative humidity is normally quite low worked very well for many months but during summer months when relative humidity is much higher the software didn't work that well. Debugging this kind of embedded software is not that easy. I disassembled the prototype for 3 times uploading yet another software version but the damn thing kept starting the vent fan in the middle of night or at some random time.
INTERNET ENABLED HUMIDITY CONTROLLER
I had to find a solution to this problem so when I learned about the Particle Photon board I knew that this might just be the solution. After reading some of the documentation I was pretty sure that having Internet connection would not only help me to debug the problem but also saves me a lot of trouble, as Particle Photon allows you to install the new firmware over the air. So I wouldn't have the get the vent box open, remove all wires, flash the Arduino board with new software and assemble everything back together. After connecting the Particle Photon board to my Wifi and adding the device on Particle.io web IDE, I used Particle.io web based software development environment (see Fig 5. below) to edit and debug the humidity controller software. I could just simply edit, compile new code, press a button and install firmware almost instantly over the Internet using the WiFi connection on this Photon board.
How cool is this?
Fig 5. Web based software development environment |
Particle.io provides also excellent API that have simple to use Internet enabled functions that you can incorporate in your own software. In my case I wanted to debug how the humidity sensor behaves when you have a transient increase in relative humidity when taking a shower. I used the HTU21D sensor from Sparkfun. Easy way to debug is to publish your sensor data to the Internet using a simple function like Spark.publish("RH_temp",str,60,PRIVATE);
You can use the Particle Dashboard to view the sensor data in near real time. This was almost too easy to describe on a blog like this.
Fig 6. Particle Dashboard |
You can use of course use your own web or mobile applications to read and write data as well as control the input/output pins on the Photon board.
I used a simple API command line call to capture the sensor data for plotting:
curl -k https://api.particle.io/v1/devices/<your device id>\/events/?access_token\=<your access token> >photon_data.txt
Figure 7. below shows the relative humidity transient after taking a shower and then the decline as the vent fan is running. You can also see the small temperature increase when the hot water is running. When looking at the data I realized that my RH% threshold had been too small. When I increased the threshold value the controller started working much better. Being able to extract the sensor data and publish it over the Internet made a big difference in debugging the original problem.
Fig 7. RH% delta and Temperature over time |
PLOTTING
In order to collect more data and have a dashboard to plot and review the measurements I signed up for a free account at ThingSpeak. You get an API key and channel number. With these you can plot the values with a simple API call:ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
Fig 7 and 8 below show the sensor data plot. Relative humidity peaks at 100% when taking a shower but since the fan is turned on almost instantly the humidity starts to drop quickly back to normal. You can see also a small increase in temperature at the same time. The drop in temperature is due to A/C that turns on at 6:00 AM.
Fig 7. Relative Humidity plot showing a peak |
Fig 8. Temperature plot |
CONCLUSIONS
My quick foray into the world of "Internet of Things" took me about 2 hours on a Sunday afternoon. Using the latest Particle.io Photon board and the web based IDE I was able to convert my existing Arduino based humidity controller to an Internet enabled controller that is publishing sensor data in near real time and allows me to update the software over the air.This whole project felt like too easy - I expected that building IoT prototypes would be much harder but at least for this simple use case it took a novice like myself only a short time to solve a real world problem. Now the bathroom vent works as expected and humidity is under control.
APPENDIX - SOFTWARE
The current software version is listed below. As you can see this is not rocket science - a few lines of code and you have an Internet connected sensor / controller. // This #include statement was automatically added by the Particle IDE.
#include "HTU21D/HTU21D.h"
#include "application.h"
/*
HTU21D Humidity Controller
By: Mauri Niininen (c) Innomore LLC
Date: Aug 30, 2015
Uses the HTU21D library to control humidity using a fan.
Hardware Connections (Breakout board to Photon)
-VIN = 5.3 V
-VCC = 3.3 V
-GND = GND
-SDA = D0 (use inline 330 ohm resistor if your board is 5V)
-SCL = D1 (use inline 330 ohm resistor if your board is 5V)
-RLY = D3 relay board
*/
#define HOUR 3600/10 // 1 HOUR in seconds - divide by loop delay 10 secs
#define HRS_24 24 // 24 hours of history
// define class for 24 hr relative humidity
class RH24 {
private:
float rh24[HRS_24]; // Keep last 24 hours of humidity
int counter;
int index;
public:
void init(float RH);
void update_h(float RH);
float avg(float RH);
};
//Create an instance of the objects
HTU21D mh;
RH24 rh;
// for time sync
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();
void setup()
{
pinMode(D7, OUTPUT);
pinMode(D3, OUTPUT);
while (! mh.begin()){
digitalWrite(D7,HIGH);
delay(200);
digitalWrite(D7,LOW);
delay(200);
}
// turn on the fan
digitalWrite(D3,HIGH);
// initialize sensor
rh.init(mh.readHumidity());
delay(5000);
// turn off the fan
digitalWrite(D3,LOW);
}
// MAIN PROGRAM LOOP
void loop()
{
// read sensor humidity and temperature
float humd = mh.readHumidity();
float temp = mh.readTemperature();
float avg = rh.avg(humd);
float delta = humd - avg;
// convert data to string
String h_str = String(humd,2);
String t_str = String(temp,2);
String d_str = String(delta,2);
String avg_str = String(avg,2);
String tm_str = String(millis());
String str = String(h_str+":"+t_str+":"+d_str+":"+avg_str+":"+tm_str);
// if relative humidity increases over 12% vs. 24 hour average, turn on the fan
if (humd - avg > 12.0) {
digitalWrite(D7,HIGH);
digitalWrite(D3,HIGH);
Spark.publish("RH_temp","ON",60,PRIVATE);
}
else {
digitalWrite(D7,LOW);
digitalWrite(D3,LOW);
}
// time sync over Internet once a day
if (millis() - lastSync > ONE_DAY_MILLIS) {
// Request time synchronization from the Particle Cloud
Spark.syncTime();
lastSync = millis();
}
// Send a published string to your devices...
Spark.publish("RH_temp",str,60,PRIVATE);
delay(10000);
}
void RH24::init(float RH){
counter = 0;
index = 0;
for (int i = 0; i < HRS_24; i++)
rh24[i] = RH;
}
void RH24::update_h(float RH) {
counter += 1;
if (counter > HOUR) {
counter = 0;
rh24[index] = RH;
index += 1;
if (index >=HRS_24)
index = 0;
}
}
float RH24::avg(float RH) {
update_h(RH);
float sum = 0.0;
for (int i = 0; i < HRS_24; i++)
sum += rh24[i];
return (sum/HRS_24);
}
No comments:
Post a Comment