In this article, you are going to build a weather measurement station that will automatically send data to an online cloud service. To do so, we will simply use an Arduino Uno board, a WiFi module and some sensors.

Using completely free web services like Dweet.io and Freeboard.io, you will be able to build your own Internet of Things dashboard for home automation applications. Let’s dive in!

Hardware & Software Requirements

For this project, you will first need an Arduino Uno board.

For temperature and humidity measurements, you will also need a DHT11 sensor, along with a 4.7K resistor. You can also use a DHT22 sensor which is more precise, you will only have one line of code to change.

For light levels measurements, I used a photocell with a 10K Ohm resistor. This will return a signal which is proportional to the ambient light level.

Then, you need the CC3000 chip for WiFi connectivity. There are many different boards for this chip on the market. What I recommend is using the Adafruit CC3000 breakout board, which is the only one I tested that worked without a problem. It is nice and compact with an onboard antenna and voltage regulators (so you can directly connect it your Arduino board).

Finally, you need a breadboard and some jumper wires to make the connections between the different parts.

This a list of all required components for the project:

On the software side, you will need the library for the DHT sensor:

https://github.com/adafruit/DHT-sensor-library

You will also need a library for the CC3000 WiFi chip:

https://github.com/adafruit/Adafruit_CC3000_Library

To install a library, simply extract the library folder inside the /libraries folder of your main Arduino folder.

You will also need to create an account on Freeboard, as we will use this service to display the measured data. Go over to:

https://www.freeboard.io/

You will be taken to the welcome page of the Freeboard service, where you can create an account:

Create Your Internet of Things Dashboard

Hardware Configuration

The hardware connections for this project are actually quite simple. First, we have to connect the DHT11 sensor   (the part responsible for the light level measurement) to the photocell and the CC3000 WiFi chip. To help you out, the following picture summarizes the hardware connections:

Create Your Internet of Things Dashboard

First, connect the Arduino Uno +5V pin to the red rail on the breadboard, and the ground pin to the blue rail. Then, place the DHT sensor and the CC3000 breakout board on the breadboard.

After that, connect pin number 1 of the DHT11 sensor (see the schematic) to the red rail on the breadboard, and pin number 4 to the blue rail. Also, connect pin number 2 of the sensor to pin number 7 of the Arduino board. To complete the connections of the DHT11 sensor, connect the 4.7k Ohm between pin number 1 and 2 of the sensor.

For the photocell, first place the cell in series with the 10k Ohm resistor on the breadboard. Then, connect the other end of the photocell to the red rail on the breadboard, and the other end of the resistor to the ground. Finally, connect the common pin to the Arduino Uno analog pin A0.

Now, the WiFi module. First, connect the IRQ pin of the CC3000 board to pin number 3 of the Arduino board, VBAT to pin 5, and CS to pin 10. Then, you need to connect the SPI pins to the Arduino board: MOSI, MISO, and CLK go to pins 11,12, and 13, respectively. Finally, take care of the power supply: Vin goes to the Arduino 5V (red power rail), and GND to GND (blue power rail).

Testing Parts Individually

Now that the hardware of the project is fully assembled, we are going to test the different sensors on the board. And to do so, we are going to write a simple Arduino sketch. We will simply read out data from the sensors, and print this data on the Serial port.

This is the complete code for this section:

// Libraries
#include "DHT.h"

// DHT sensor
#define DHTPIN 7 
#define DHTTYPE DHT11

// DHT instance
DHT dht(DHTPIN, DHTTYPE);

void setup()
{
  // Initialize the Serial port
  Serial.begin(9600);
  
  // Init DHT
  dht.begin();
}


void loop()
{
  // Measure from DHT
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  
  // Measure light level
  float sensor_reading = analogRead(A0);
  float light = sensor_reading/1024*100;
  
  // Display temperature
  Serial.print("Temperature: ");
  Serial.print((int)temperature);
  Serial.println(" C");
  
   // Display humidity
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println("%");
  
  // Display light level
  Serial.print("Light: ");
  Serial.print(light);
  Serial.println("%");
  Serial.println("");
  
  // Wait 500 ms
  delay(500);
  
}

Let’s now see the details. It starts by importing the library for the DHT sensor:

#include "DHT.h"

And create a DHT instance:

DHT dht(DHTPIN, DHTTYPE);

In the setup() function of the sketch, we have to initialize the sensor:

dht.begin();

And the Serial port:

Serial.begin(9600);

In the loop() function, we are going to continuously read data from the sensors, and print it on the Serial port. It starts by getting data from the temperature & humidity sensor:

float temperature = dht.readTemperature();
float humidity = dht.readHumidity();

For the photocell, we first read data from the analog pin A0. This pin will return a value from 0 to 1023 as the resolution of the Analog-To-Digital converter of the Arduino Uno board is 10 bits. Thus, there are 1024 values. Then, we divide this reading by 1024 and multiply it by 100 to have the light level as a percentage:

float sensor_reading = analogRead(A0);
float light = sensor_reading/1024*100;

Then, we print these different measurements on the Serial port. First, the temperature:

Serial.print("Temperature: ");
Serial.print((int)temperature);
Serial.print((char)223);
Serial.println("C");

The humidity is exactly similar, just as the light level:

Serial.print("Light: ");
Serial.print(light);
Serial.println("%");

Finally, we introduce a delay of 500 ms between each new set of measurements:

delay(500);

Note that the complete code for this article can be found inside the GitHub repository of the article:

https://github.com/openhomeautomation/iot-dashboard

It’s now time to test this first Arduino sketch. Upload the code to the Arduino board and open the Serial monitor inside the Arduino IDE. Make sure of the Serial speed that we defined in the code.  This is what you should see:

Temperature: 25 C
Humidity: 36.00%
Light: 83.79%

If that works, congratulations, your sensors are working correctly! You can try, for example, to pass your hand in front of the photocell, and you should see that the light level is changing instantly.

In case it is not working at this point, there are several things you can check. First, make sure that you correctly downloaded and installed the required libraries for this article. Also make sure that you correctly connected the sensors to your Arduino board as defined earlier in the article. Finally, make sure that you are using the latest version of the code from the GitHub repository of the article.

Logging Data in the Cloud

We are now going to do the most important part of this chapter: upload data to the cloud via WiFi. To do so, we will use a service called dweet.io, which is a service that proposes to store your data online via a very simple API. You can check out their page at:

https://dweet.io/

The nice thing with Dweet.io is that it doesn’t require any account creation or configuration — you can upload data immediately. It is based on the principle of having objects called “things”, to which you will upload new data via HTTP requests. And if you upload data to a new thing that doesn’t exist yet, it will be created automatically.

Let’s now build the sketch that we will use to automatically make measurements, connect to the Dweet.io server, and upload the data there. This is the complete code for this section:

// Libraries
#include <Adafruit_CC3000.h>
#include <SPI.h>
#include "DHT.h"
#include <avr/wdt.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// DHT sensor
#define DHTPIN 7
#define DHTTYPE DHT11

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, 
ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
                                         
// DHT instance
DHT dht(DHTPIN, DHTTYPE);

// WLAN parameters
#define WLAN_SSID       "yourWiFiNetwork"
#define WLAN_PASS       "yourPassword"
#define WLAN_SECURITY   WLAN_SEC_WPA2

// Dweet parameters
#define thing_name  "yourThingName"

// Variables to be sent
int temperature;
int humidity;
int light;

uint32_t ip;

void setup(void)
{
  // Initialize
  Serial.begin(115200);
  
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }
 
  // Connect to WiFi network
  Serial.print(F("Connecting to WiFi network ..."));
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("done!"));
  
  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  
}

void loop(void)
{ 
  
  // Measure from DHT
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  temperature = (int)t;
  humidity = (int)h;

  // Measure light level
  float sensor_reading = analogRead(A0);
  light = (int)(sensor_reading/1024*100);
  Serial.println(F("Measurements done"));
  
  // Start watchdog 
  wdt_enable(WDTO_8S); 
  
  // Get IP
  uint32_t ip = 0;
  Serial.print(F("www.dweet.io -> "));
  while  (ip  ==  0)  {
    if  (!  cc3000.getHostByName("www.dweet.io", &ip))  {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }  
  cc3000.printIPdotsRev(ip);
  Serial.println(F(""));
  
  // Reset watchdog
  wdt_reset();
  
  // Check connection to WiFi
  Serial.print(F("Checking WiFi connection ..."));
  if(!cc3000.checkConnected()){while(1){}}
  Serial.println(F("done."));
  wdt_reset();
  
  // Send request
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
    Serial.print(F("Sending request... "));
    
    client.fastrprint(F("GET /dweet/for/"));
    client.print(thing_name);
    client.fastrprint(F("?temperature="));
    client.print(temperature);
    client.fastrprint(F("&humidity="));
    client.print(humidity);
    client.fastrprint(F("&light="));
    client.print(light);
    client.fastrprintln(F(" HTTP/1.1"));
    
    client.fastrprintln(F("Host: dweet.io"));
    client.fastrprintln(F("Connection: close"));
    client.fastrprintln(F(""));
    
    Serial.println(F("done."));
  } else {
    Serial.println(F("Connection failed"));    
    return;
  }
  
  // Reset watchdog
  wdt_reset();
  
  Serial.println(F("Reading answer..."));
  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  Serial.println(F(""));
  
  // Reset watchdog
  wdt_reset();
   
  // Close connection and disconnect
  client.close();
  Serial.println(F("Closing connection"));
  Serial.println(F(""));
  
  // Reset watchdog & disable
  wdt_reset();
  wdt_disable();
 
  // Wait 60 seconds until next update
  wait(60000);
    
}

// Wait for a given time using the watchdog
void wait(int total_delay) {
  
  int number_steps = (int)(total_delay/5000);
  wdt_enable(WDTO_8S);
  for (int i = 0; i < number_steps; i++){
    //Serial.println(F("Waiting for 5 seconds ..."));
    delay(5000);
    wdt_reset();
  }
  wdt_disable();
}

Let’s now go into the details of the code. It starts by importing the required libraries:

#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include "DHT.h"
#include <avr/wdt.h>

We then define the pins which the CC3000 module is connected to:

#define ADAFRUIT_CC3000_IRQ 3
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10

Then, we can create an instance of the CC3000 WiFi chip:

Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, <br>ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);

Now, you will need to modify the sketch to enter your own SSID network name, and the associated password. If your network is not using WPA2 authentication, you will also have to change this parameter:

#define WLAN_SSID "yourWiFiNetwork"
#define WLAN_PASS "yourPassword"
#define WLAN_SECURITY WLAN_SEC_WPA2

You will also need to give a name to your ‘thing’. Note that all the things on dweet.io are public by default. It is not a problem here as we just want to upload and monitor simple data that is not sensible at all. However, I recommend choosing a complicated name for the device so nobody else can find it. For example, you can use names like weather_station_l5ir457xda. Once you have a good name, you can enter it inside the sketch:

#define thing_name "yourThingName"

We also need to define some variables that will contain the measurements made by the project:

int temperature;
int humidity;
int light;

In the setup() function of the sketch, we initialize the CC3000 chip:

Serial.println(F("\nInitializing..."));
if (!cc3000.begin())
{
  Serial.println(F("Couldn't begin()! Check your wiring?"));
  while(1);
}

In the loop() function, we first connect the CC3000 chip to your local WiFi network:

cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);

We also need to start the watchdog. The watchdog is basically a circuit inside the Arduino microcontroller, independent from the code itself. It will reset the Arduino sketch automatically after a given time, unless we send it a reset signal. This will ensure that even if our Arduino sketch hangs for some reasons (for example, it it cannot connect to the Dweet.io servers), the Arduino sketch will just reset itself and the project will continue to work. We first need to enable the watchdog with the maximal delay of 8 seconds:

wdt_enable(WDTO_8S);

When we are connected, we perform the temperature, humidity and light level measurements:

float t = dht.readTemperature();
float h = dht.readHumidity();
temperature = (int)t;
humidity = (int)h;

float sensor_reading = analogRead(A0);
light = (int)(sensor_reading/1024*100);
Serial.println(F("Measurements done"));

Once we got the measurements, we can upload them on the Dweet.io service. To do so, we need to connect to their servers, and then send the data inside a standard HTTP GET request. This is done by the following piece of code:

Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
Serial.print(F("Sending request... "));

client.fastrprint(F("GET /dweet/for/"));
client.print(thing_name);
client.fastrprint(F("?temperature="));
client.print(temperature);
client.fastrprint(F("&humidity="));
client.print(humidity);
client.fastrprint(F("&light="));
client.print(light);
client.fastrprintln(F(" HTTP/1.1"));

client.fastrprintln(F("Host: dweet.io"));
client.fastrprintln(F("Connection: close"));
client.fastrprintln(F(""));

Serial.println(F("done."));
} else {
Serial.println(F("Connection failed"));
return;
}

We should also not forget to reset the watchdog after this long request:

wdt_reset();

After the data is sent, we read back the answer from the dweet.io server to be sure that the data was correctly received on the other end. We also close the connection and disconnect the CC3000 chip from your WiFi network, in order to save energy:

Serial.println(F("Reading answer..."));
while (client.connected()) {
  while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
}
Serial.println(F(""));

// Reset watchdog
wdt_reset();

// Close connection and disconnect
client.close();
Serial.println(F("Disconnecting"));
Serial.println(F(""));
cc3000.disconnect();

After that, we also disable the watchdog:

wdt_disable();

Finally, we repeat this loop again after 10 seconds. Note that you can customize this delay if you want less frequent measurements:

delay(10000);

Note that the complete code for this part can be found inside the GitHub repository of the article:

https://github.com/openhomeautomation/iot-dashboard

We are now going to test this code. Make sure that you entered the name of your thing inside the sketch, and that you also entered the data for your WiFi network. Then, upload the code to the Arduino board. Open the Serial monitor, and after a while you should see the answer coming back from the dweet.io server:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 174
Date: Thu, 24 Jul 2014 12:08:32 GMT
Connection: keep-alive
{“this”:”succeeded”,”by”:”dweeting”,”the”:”dweet”,”with”:
{“thing”:”yourThingName”,”created”:”2014-07-24T12:08:32.443Z”,
“content”:{“temperature”:25,”humidity”:35,”light”:59}}}

You can also check online that the data was correctly recorded. Just type in a browser:

https://dweet.io/get/dweets/for/yourThingName

Of course, you have to replace the name with the name of thing you entered in the Arduino sketch. You should see that at least one measurement was inserted for this thing. For example:

{
 "thing": "weather_station_1a2cx3s8",
 "created": "2014-07-13T12:58:10.924Z",
 "content": {
 "temperature": 26,
 "humidity": 40,
 "light": 69
 }
}

In case it is not working at this point, there are several things you can check. First, make sure that you Internet connection is up and running, and that your Arduino board is actually connecting to your WiFi network. You can also check that the answer from the Dweet.io website is correct. Finally, make sure that you correctly entered your ‘Thing’ name inside the Arduino sketch.

Displaying the Measured Data

We are now able to store data in the cloud, using the dweet.io service. Your Arduino board is now continuously sending data over there. However, even if the data it returns is human-readable, it would be much better to visualize this data graphically. This is why we created an account on Freedboard before. Go over to this website again and log in:

https://www.freeboard.io/

Inside this interface, you will be able to create a new dashboard. This will be the main interface from which you will monitor everything. Do so by entering a name for your dashboard, and click on “Create New”. Then, you have to create two things: panes and datasources.

Let’s start with the datasource, which is the source of the data that will be displayed inside the dashboard. Click on “Add” to add a new data source, and select “Dweet.io” in the menu:

Create Your Internet of Things Dashboard

Inside this box, you also need to enter a name, and the name of your thing that you defined in the Arduino sketch. Then, click on “Save”.

Now, we need to create a new pane. A pane is basically a space on the dashboard where the data is displayed graphically. Click on the button, and then click on the pane “+” icon to add a widget. These widgets will display the data itself. I created three different panes, so I can display all the recorded data at the same time. I started with text widgets:

Create Your Internet of Things Dashboard

The most important thing here is to select the “Value” field by clicking on “+ Datasource” on the right. This will directly link the widget with the data coming from dweet.io. For example, you can name your first widget ‘temperature’, and then link it to the temperature field of the datasource we defined earlier.

This is the result I got with three text widgets:

Create Your Internet of Things Dashboard

I also played with the interface, and changed these widgets for gauges widgets, but based on the same data:

Create Your Internet of Things Dashboard

You can also notice that the data is changing in live depending on the measured data. This means that you can now monitor this data from anywhere in the world, just by having the URL of your dashboard.

In case it is not working at this point, make sure that the data is correctly received by the Dweet.io website first. Also make sure that you entered the correct ‘Thing’ name inside your Freeboard.io dashboard.

How to Go Further

Let’s summarize what you have learned in this article. You just learned how to send measurements from your Arduino board to the cloud, so this data can be accessed from outside of your local WiFi network. We also saw how to monitor this data from a central online dashboard, so you can monitor it from anywhere.

You can, of course, improve this project in many ways. The first one is to add more sensors to the project, for example a wind speed sensor or a smoke sensor. You can also install many of these boards around your home, all uploading data to a different “thing” on dweet.io. Then, you can use what you learned about Freeboard to monitor all these measurements from a central place.