Building Connected Things with Node.js, Johnny-Five, and Microsoft Azure
Building the Thingy 4 Edison
Table of Contents
- Table of Contents
- Setting Up the Board
- Building the Application
- Run the Application
- Conclusion & Next Steps
Setting Up the Board
In this lab, you will use multiple Grove sensors and actuators to build a device with multiple inputs and outputs. You will use this device for the rest of the labs in this series.
- Connect the Grove shield to the Edison (mounted to the Arduino adapter).
- Connect the Grove Button Sensor to port D4
- Connect the LED Module to port D6, and insert an LED into the LED Module.
- Connect the RGB LCD Module to one of the I2C ports.
- Connect the Temperature Sensor (TH02) to A0 port.
Building the Application
There are three (3) steps to building the application in this lab:
- Define and install the application metadata and dependencies.
- Define the device abstractions.
- Handle the board.on(“ready”) callback.
The ThingLabs Thingy™ for Edison has the following capabilities:
- Capture the ambient temperature and display it on the LCD screen.
- Alter the color of the LCD screen based on the ambient temperature.
- Turn the LED on and off by pressing and releasing the button.
Define an Install the Application Metadata and Dependencies
Defining and installing the application metadata and dependencies works similarly to steps 1-3 in the Hello, IoT World! lab.
Start by creating a new application directory and a new package.json file.
- Using your favorite/preferred text/code editor, create a file in the directory you want to use for this lab (e.g. C:\Development\IoTLabs\MyLab) named package.json
- Add the following code…
{
"name": "myapp",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "https://github.com/ThingLabsIo/IoTLabs"
},
"bugs": {
"url": "https://github.com/ThingLabsIo/IoTLabs/issues"
},
"description": "Sample using Node.js, Johnny-Five, and the Intel Edison.",
"license": "MIT",
"dependencies": {
"johnny-five": "latest",
"edison-io": "latest"
}
}
Define the Device Abstractions
The application code resides in a JavaScript file in the same directory as the package.json file.
-
Create a file named thingy.js in your lab application directory (e.g. C:\Development\IoTLabs\MyLab).
Within the application file (thingy.js), you need to define the abstractions of the devices you will be using within the application. The variables are:
- A variable to reference the Johnny-Five framework object.
- A variable to reference to the Edison-IO plugin object.
- A variable to represent the physical board.
- A variable to represent the physical button.
- A variable to represent the physical LED.
- A variable to represent the physical RGB LED display.
- A variable to represent the physical temperature sensor.
- A set of variables for maintaining the value of the sensors.
-
Within the thingy.js file, add the following code:
'use strict';
var five = require ("johnny-five");
var Edison = require("edison-io");
// Define the sensors you will use
var button, led, lcd, temperature;
// Define some variable for holding sensor values
var tempC, tempF, humidity, r, g, b = 0;
// Define the board, which is an abstraction of the Intel Edison
var board = new five.Board({
io: new Edison()
});
In this code you define several variables that you will be working with:
five
- represents the Johnny-Five framework capabilities, which provide a type of object model for working with boards like Arduino and Edison.Edison
- a variable that represents the edison-io plugin for Johnny-Five.board
- a representation of the physical board you are using.button
- a represntation of the physical Button Sensor you are using.led
- a represntation of the physical LED Module you are using.lcd
- a represntation of the physical RGB LCD Display you are using.temperature
- a represntation of the physical Temperature Sensor you are using.tempC
- a variable to hold the most recent celsius temperature vaue.tempF
- a variable to hold the most recent fahrenheit temperature vaue.r
- a variable to hold the most recent red vaue for the RGB LCD Display.g
- a variable to hold the most recent green vaue for the RGB LCD Display.b
- a variable to hold the most recent blue vaue for the RGB LCD Display.
Handle the board.on(“ready”) Callback
By now, you should be familiar with handling the Johnny-Five board.on('ready')
callback. In the following code, you will instantiate the physical devices, and then define the callback functions for the button
and temperature
sensors.
- You will create instances of each object type (
Led
,Button
,LCD
, andTemperature
). - You will handle the
Button.on('press')
,Button.on('release')
, andTemperature.on('data')
events by defining the callback function for each. - You will change the state of the
Led
object based on theButton
state. - You will change the state of the
LCD
object based on theTemperature
state.
- Add the following code to thingy.js
// *********************************************
// The board.on() executes the anonymous
// function when the 'board' reports back that
// it is initialized and ready.
// *********************************************
board.on('ready', function() {
console.log('Board connected...');
// Plug the Temperature sensor module
// into the Grove Shield's A0 jack
// The controller defines the type of
// Temperature sensor this is.
temperature = new five.Thermometer({
controller: "GROVE",
pin: "A0"
});
// Plug the LCD module into any of the
// Grove Shield's I2C jacks.
// The controller specifies the type of LCD this is.
lcd = new five.LCD({
controller: 'JHD1313M1'
});
// Plug the LED module into the
// Grove Shield's D6 jack.
led = new five.Led(6);
// Plug the Button module into the
// Grove Shield's D4 jack.
button = new five.Button(4);
// *********************************************
// The thermometer object will invoke a callback
// everytime it reads data as fast as every 25ms
// or whatever the 'freq' argument is set to.
// *********************************************
temperature.on('data', function() {
// TODO - Add callback operation here
});
// *********************************************
// The button.on('press') invokes the anonymous
// callback when the button is pressed.
// *********************************************
button.on('press', function() {
led.on();
console.log('PRESSED');
});
// *********************************************
// The button.on('release') invokes the
// anonymous callback when the button is
// released.
// *********************************************
button.on('release', function() {
led.off();
console.log('RELEASED');
});
});
Most of the preceeding code should seem familiar to you by now. The new bit that you still need to do is handle the Multi.on('data')
callback function.
When you initialized the Temperature sensor, you specified a controller
value (GROVE
). This defines which Temperature sensor type to instantiate - basically a driver. The GROVE controller specifies the simple Grove Temperature sensor (there are others, including the popular TMP36). By specifying the GROVE controller you are telling Johnny-Five how to interact with this sensor.
The callback function for the Temperature sensor is invoked every 25ms (the default value). You can change the frequency the callback is invoked by adding a freq:
argument when the object is defined (similar to how you defined the controller
and pin
) and specifying the frequency in milliseconds (e.g. a value of 1000 would invoke the callback once per second).
- Repace the
// TODO
comment with the following code:
// Set the state of the variables based on the
// value read from the thermometer
// 'this' scope is the thermometer
tempC = this.celsius;
tempF = this.fahrenheit;
This will collect the current reading from the Temperature sensor.
- Next, use the temperature value to alter the RGB LCD display.
// Use a simple linear function to determine
// the RGB color to paint the LCD screen.
// The LCD's background will change color
// according to the temperature.
// Hot -> Moderate -> Cold
// 122°F -> 77°F -> 32°F
// 50°C -> 25°C -> 0°C
// Red -> Violet -> Blue
r = linear(0x00, 0xFF, tempC, 50);
g = linear(0x00, 0x00, tempC, 50);
b = linear(0xFF, 0x00, tempC, 50);
// Paint the LCD and print the temperture
// (rounded up to the nearest whole integer)
lcd.bgColor(r, g, b).cursor(0, 0).print('Fahrenheit: ' + Math.ceil(tempF));
lcd.bgColor(r, g, b).cursor(1, 0).print('Celsius: ' + Math.ceil(tempC));
This code creates an RGB (Red, Green, Blue) value based on the temperature. It relies on a helper function named linear()
.
- Add the linear function to the end of the thingy.js file, after the
board.on('ready')
callback is closed.
// *********************************************
// Helper method for painting the LCD.
// Linear Interpolation
// (https://en.wikipedia.org/wiki/Linear_interpolation)
// *********************************************
function linear(start, end, step, steps) {
return (end - start) * step / steps + start;
}
Run the Application
- Copy the application files to the Edison in the same way you have done in the preceeding labs.
- Install the application dependencies on the Edison (if you are using the same application directory as the preceeding labs, the dependencies should all be installed already).
- From the remote session (Command Prompt or Terminal), execute the following command in the application directory. In this lab you are specifying the JavaScript file that node.exe should execute.
node thingy.js
Once the application is running, you will see the temperature reading on the RGB LCD Display. You can press the button and see the LED light up (you will also see the PRESSED
log message in the remote session). As long as the button is pressed, the LED will remain on. When you release the button, the button.on('release')
callback is invoked and the LED turns off (you will also see the RELEASED
log message).
When you want to quit the application, press CTRL + C twice to exit the program without closing the window (you may also have to press Enter).
Conclusion & Next Steps
In this lab, you built the ThingLabs Thingy™ for Edison, which you will use in the subsequent labs.