Project 1 Due: 11:59 PM, Wednesday, June 9, 2021
🏁 Submit to Canvas a single .pdf file named Your_Last_Name_First_Name_Project1.pdf. This single pdf will contain your responses to the questions marked with a checkered flag. It is important that you clearly label each answer with the project part number and that you provide your name and email address at the top of the .pdf.
Part 1: Programming a Particle Argon to report heartbeats to the Particle cloud and Node-RED
Start up items
In order to quickly build web sites, we will use Node.js and Express.
In order to route and process IoT messages, we will use Node-RED.
The selected microcontroller that we will use is the Particle Argon. It has the ability to communicate via Bluetooth LE and Wi-Fi. We need to initialize the Argon and establish credentials at Particle. We will use the Particle cloud’s over the air (OTA) update capability to flash firmware to the Argon.
• Follow these directions and install Node.js.
• The node package manager (npm) was installed as part of node.js in step 0. Next, use npm to install Node-RED locally on your laptop or desktop machine.
On Mac OSX, run the shell command:
sudo npm install -g –unsafe-perm node-red
On Windows, run the shell command:
npm install -g –unsafe-perm node-red
• Execute Node-RED with the shell command:
node-red
• Test a running instance of Node-Red. Use a browser and visit the localhost URL:
http://127.0.0.1:1880/
Argon Setup, Particle IDE, and Particle CLI
We will be programming the Argon microcontroller by developing our firmware code in C++, compiling to machine code, and downloading to the device via Particle’s over the air (OTA) update.
• Establish credentials at Particle.io
• Install the Particle Command Line Interface (CLI) by following these directions.
• Set up your Particle Argon. It is recommended that you complete this tutorial. That is, blink an LED on your microcontroller as per the instructions in the Argon Quickstart. In addition, carefully read over the documentation in the firmware.
Publish heartbeat messages to the Particle console
• Use the code below to publish heartbeat messages to the Particle console.
/*
Author: mm6 with various code snippets taken from Particle.io.
This firmware generates periodic heartbeats from an Argon to
the Particle cloud using Particle.publish(string name,string value).
The first argument will be the name of the event. The event name is
‘heartbeat’. The second argument will be a JSON string holding
the device ID.
*/
// Setting DEBUG == true generates debugging output to a shell.
// To view these messages, install the Particle CLI and enter the command:
// particle serial monitor
boolean DEBUG = true;
// Establish the number of seconds to wait until calling the server.
int NUMSECONDS = 10;
// The variable timeCtr will be used to hold the current time in milliseconds.
int timeCtr = 0;
// The device ID will be stored here after being retrieved from the device.
// This is a unique, 96 bit identifier.
// This looks like the following: 0x3d002d000cf7353536383631.
String deviceID = “”;
// buf will hold the JSON string
char buf[80];
// This class makes handling JSON data easy.
// Associate it with the buf array of char.
JSONBufferWriter writer(buf, sizeof(buf));
void setup() {
// to allow for debug using the CLI
Serial.begin(9600);
// get the unique id of this device as 24 hex characters
deviceID = System.deviceID().c_str();
// display the id to the command line interface
if (DEBUG) Serial.println(deviceID);
// establish the JSON string that we will send
writer.beginObject();
writer.name(“deviceID”).value(deviceID);
writer.endObject();
// The JSON is now available through the buf array.
}
// Event name to send to the server at Particle
String name = “heartbeat”;
void loop() {
// If timeCtr is above the current time wait until the current time catches up.
// Initially, timeCtr is 0. It is then set to the current time plus 10 seconds.
// millis() returns an updated time.
if (timeCtr <= millis()) {
// publish to Particle the event name and the JSON string
Particle.publish(name,String(buf));
// display a status report if DEBUG is true
if (DEBUG) Serial.println("Heartbeat sent to Particle");
// set timeCtr to current time plus NUMSECONDS seconds
timeCtr = millis() + (NUMSECONDS * 1000);
}
}
• Study the code above. After compiling and deploying the code to your Argon, use a shell and check if the CLI is working properly.
• The following are useful CLI commands.
$particle login Login to Particle
$particle serial monitor Listen for Serial.print
$particle update-cli Update the CLI
There are plenty of additional CLI commands.
• Using the Particle console, verify that it is receiving the heartbearts from the Argon.
Using Node-RED, subscribe to the heartbeat messages that are being published to particle.
• Our goal is for Node-RED to subscribe to and receive messages from the Particle console. These messages are being published to the Particle console by our Argon. We want Node-RED to hear about the heart beats. This article introduces you to Node-RED and the "The Particle Nodes" section specifically is where the reader learns how to connect the Argon to Node-RED. Read about Node-RED and integrate Node-RED with the Particle console.
• After completing the work in step 11, you should have a Node-RED platform receiving messages from your Argon every 10 seconds or so. Each message should contain a JSON string with the device ID. Each message should appear in the right pane of the Node-RED UI. The Node-RED palette should have a subscribe node wired to a debug node.
🏁Take a screenshot showing the Node-RED palette. The debug panel on the right will show several JSON strings that have arrived from the Argon. Name your screenshot Project1Part1.png.
Part 2: Node-RED Programming
Working with flows
• The objective of this part is to gain skills in the creation and execution of Node-RED flows. We will work with the heartbeat data that we are receiving from our Particle Argon. This is a continuation from our work in Part 1. Follow this link for a good place to learn about Node-RED and its capabilities.
• Wire a function node in between your subscribe node and your debug node. The function node will add a timestamp to the incoming message. Study this code and use it in your function node:
// The message has arrived in the msg object.
// Create a javascript object using the JSON message payload.
var newMessage = JSON.parse(msg.payload);
// Add a time field to the new object.
// Use the current date and time.
newMessage.time = new Date();
// Represent the new object as JSON.
msg.payload = JSON.stringify(newMessage);
// pass it on to the next node
return msg;
• Add another function node that checks the timestamp. If the current message arrived late (after 12 seconds) then set a variable named "onTime" to false, otherwise set the "onTime" variable to true. Include the new "onTime" field and its value in the json message that leaves this node. Note: the very first message to arrive is never late. You can test this flow by unplugging your USB for 10 seconds or so and rebooting your Argon. You will need to think a bit about how to do this programming. Javascript is good at handling dates and it is easy to subtract one date from another. But you will need to research this a bit. Here is another resource that you might find helpful.
🏁Take a screenshot showing the Node-RED palette. The debug panel on the right will show several JSON strings that have arrived from the Argon. The debug panel should show messages that were on time and some that were not on time. Name your screenshot Project1Part2.png.
Part 3: Build a web site using Node.js
In this Part you will build as simple web server using Node.js.
• We need to store our web artifacts in an empty directory. Create an empty directory named Project1_Part3.
• Within the directory, create a file named ViewSimpleMessage.js with the following content:
// ViewSimpleMessage.js
// Display a simple message on a browser
const http = require("http");
const host = 'localhost';
const port = 8000;
// The req variable will hold request information from the browser.
// The res variable is used to send results back to the browser.
const simpleListener = function (req, res) {
res.writeHead(200);
res.end("A simple text message on a browser");
};
// Associate the server with the listener
const server = http.createServer(simpleListener);
// Begin handling browser visits
server.listen(port, host, () => {
// runs when listening begins
console.log(`Server is running on http://${host}:${port}`);
});
• Run the server from the shell with the command:
node ViewSimpleMessage.js
• Test by using a browser to visit http://localhost:8000.
• Create a file named index.html with the following code: