Introduction: IoT Workshop: Lab 4 - Sending Data to the Cloud

About: Director, Strategic Engagements, DX-TED, Microsoft

In this lab you will build a simple ambient light detection app (similar to Lab 2) and send the data that is being collected to the Cloud. You will use Nitrogen to send data to a cloud gateway and you will be able to verify the messaging is working by logging into the Nitrogen Web Admin.

Step 1: Bill of Materials

What you will need (all the parts from the previous lessons):

*For this lesson series you are using an Arduino Yun. The reason for using this vs. other less expensive Arduino boards is because in future lessons you will make use of the fact that the Arduiono Yuin has on-board Wi-Fi and a Linux distribution. Neither of those capabilities are needed for this lesson, so if you have a different Arduino board (e.g. an Arduino Uno) you can use it. The SparkFun Inventor's Kit (for Arduino Uno) is a good kit with lots of parts (LEDs, resistors, servos, etc.), but it ships with an Arduino Uno instead of the Yun (the Uno doesn't have onboard Wi-Fi or the Linux distribution we will use in later lessons).

Step 2: Wiring the Board

This lab follows the same wiring plan as Lab 2. If your board is still wired up from Lab 2 or Lab 3, you can leave it as is and go to the next step. If not, wire it as follows.

See the breadboard image attached to this lesson):


Insert a photoresistor into the breadboard as shown in the diagram.


Connect a 10k-Ohm resistor from one side of the photoresistor across a couple of rows.


Connect the wires as shown in the diagram:


  • Connect the 5V pin to the red/positive side-rail on the breadboard.
  • Connect the red/positive side-rail to the row where the resistor lead is connected but the photoresistor is not (this is the input voltage into the static resistor part of the voltage divider).


  • Connect the green wire from the other side of the static resistor (this should be in the same row as the static resistor lead and one of the photoresistor leads) to the A0 pin on the Arduino (this is one route of the voltage divider - the other route is through the photoresistor).


  • Connect the row holding the other lead from the photoresistor to the black/negative side-rail on the breadboard. Connect the black/negative side-rail of the breadboard to the GND pin on the Arduino.

Step 3: Prepare Nitrogen

For this lab you will use the public Nitrogen sandbox. In production scenarios you would setup your own Nitrogen instance either on a local server or in Azure.

Open a command prompt (Windows) or Terminal (Mac OS) and verify your Nitrogen install is working.

n2 service show

Create a new Nitrogen user account

n2 user create

Follow the prompts to create your user identity (using your email address) and password. You can verify the account creation by listing all principal objects in your Nitrogen account (there should only be one at this point).

n2 principal ls

When your account was created an API key was also created for you. You will need this for your application (to provide the authentication credentials). You can get the API key by executing the following:

n2 apikeys ls

Again, you should only have one API key at this point. For now, copy the API key into a place you can easily reference it (such as a temporary text file).

Step 4: Update the NPM Dependencies

Since you are using Nitrogen as the agent and Cloud gateway to Azure, you need to update your dependencies to include Nitrogen. Open the package.json file you created in Lab 1 and update it to look like this:

"name": "IoT Labs",
"repository": {
"type": "git",
"url": ""
"version": "0.1.0",
"private": "true",
"dependencies": {
"johnny-five": "^0.8.0",
"nitrogen": "^0.2.0",
"nitrogen-cli": "^0.2.0",
"nitrogen-file-store": "^0.2.0"
"keywords": [
"arduino yun",

With the package.json file updated you can use NPM to pull down the necessary Node modules. Open a terminal window (Mac OS X) or Node.js command prompt (Windows) and execute the following commands (replace C:\Development\IoTLabs with the path that leads to your Workshop folder):

cd: C:\Development\IoTLabs
npm install

Step 5: Set the Objects

While this lab is similar in wiring to Lab 2, it is very different in how the code works. Not only will you read the analog input to get an ambient light reading, you will also send that data to the Cloud once per second.

Create another file in the IoTLabs directory named lab004.js. The first thing you need to do in this file is define the objects you will be working with in the application. Declare Johnny Five objects for the Johnny Five framework (five), the Arduino (board) and the sensor (photoresistor).

var five = require ("johnny-five"),
board, photoresistor;

Declare the Nitrogen objects you will need. You need to require nitrogen and the nitrogen-file-store, and declare a variable to reference the Nitrogen service and a 'lightSensor' as the Niotrogen device (this is a proxy for the photoresistor circuit you create with the Arduino).

var Store = require("nitrogen-file-store"),
nitrogen = require("nitrogen"),
service, lightSensor;

Define the Nitrogen configuration settings. Replace <YOUR API KEY HERE> with your actual API key.

var config = {
host: process.env.HOST_NAME || '',
http_port: process.env.PORT || 443,
protocol: process.env.PROTOCOL || 'https',
api_key: process.env.API_KEY || '<YOUR API KEY HERE>'

Instantiate all the objects.

board = new five.Board(); = new Store(config);
service = new nitrogen.Service(config);

Create the lightSensor device for Nitrogen.

lightSensor = new nitrogen.Device({
nickname: 'lightSensor',
name: 'Light Sensor'

Step 6: Create the Board.On() CallBack and Photoresistor Oject

Add the board.on() callback function and define the Johnny Five Sensor object for the photoresistor. The Johnny Five Sensor object (the variable you named photoresistor) has two properties you define - the pin to read data from (A0 or Analog 0) and the frequency (freq) to send the reading to a callback function (Sensor.on()). By passing 1000 to the frequency property you are instructing the Sensor to invoke the callback once per second. You will write the callback function in the next step.

board.on("ready", function() {

console.log("Board connected...");
// Create a new `photoresistor` hardware instance.
photoresistor = new five.Sensor({
pin: "A0", // Analog pin 0
freq: 1000 // Collect data once per second
// Inject the `sensor` hardware into the Repl instance's context;
// Allows direct command line access
pot: photoresistor
}); // TODO: Connect Nitrogen }

Step 7: Connect to Nitrogen and Send Data

Inside the board.on() call back (where you added the TODO comment in the previous step) you need to use the Nitrogen service object to connect to the service ( and send a Nitrogen message every time you get a reading from the photoresistor.

The Johnny Five Sensor object you created (photoresistor) will invoke a callback function (Sensor.on()) once per second and pass the reading to the function.

// Connect the lightSensor device defined above
// to the Nitrogen service instance.
service.connect(lightSensor, function(err, session, lightSensor) {
if (err) { return console.log('Failed to connect lightSensor: ' + err); }
// Define the callback function for the photoresistor reading
// The freq value used when the photoresistor was defined
// determines how often this is invoked, thus controlling
// the frequency of Nitrogen messages.
photoresistor.on('data', function() {
// Capture the ambient light level from the photoresistor
var lightLevel = this.value;
// Create a Nitrogen message
var message = new nitrogen.Message({
type: '_lightLevel',
body: {
ambientLight: lightLevel

// Log the light level value for debugging'Sending ambientLight: ' + lightLevel);
// Send the message

In this code you define a message for Nitrogen. The type definition is used to define what kind of device this message is for. By convention you use an underscore at the beginning of custom types (Nitrogen has a few predefined types, but a photoresistor is not one of them).

The body of the message is where you put the data you are tracking. In this case you are tracking ambient light using the reading coming from the photoresistor.

When you call message.send() this message is sent to the configured Nitrogen service. When you run the app, the ambient light reading will be sent to Nitrogen once per second.

Step 8: Run the App and Verify Data Is Being Sent

When you run the application is will execute on your computer, and thanks to Johnny-Five, it will connect with your board and work directly with it. Basically, instead of running this Node.js application on the Linux distribution on the board, you are running it on your computer while you test it out (don't worry, we will deploy an application onto the Linux distribution and enable your board to run without being tethered to your computer soon enough).

Open a terminal window (Mac OS X) or Node.js command prompt (Windows) and execute the following commands (replace c:\Development\IoTLabs with the path that leads to your Workshop folder):

cd C:\Development\IoTLabs node lab001.js

Once the board is initialized and the app is running you can verify the photo resistor data is being sent in two ways:

Use the Nitrogen Command Line Interface

Open a new Terminal or Command Prompt. and execute the following:

n2 messages ls

You should see several messages in the list reporting the ambientLight data.

Use the Nitrogen Web Admin

Using a browser go to

Enter the same credentials you used to create your Nitrogen user account at the beginning of this lab.

Click on the Messages menu option at the top of the page.

You should se several messages reporting ambientLight data.

Step 9: Conclusions and Next Steps

Congratulations! You have created your first internet connected Thing. Welcome to the world of IoT. In the next lab you will create a sample website which you will use to display the data that your Thing is sending into Nitrogen.

Once you've completed this lab, be sure to click the "I Made This" button at the top of the page. That helps me know how many people are working on this lab - the more people using the lab, the more lab modules I will create.

Next lab: Coming soon!