The web page consists of two files: index.html and sketch.js which contains the code which will detect a click and then send a message to the MQTT broker. The index.html file is quite trivial; it loads two libraries (p5.js and an MQTT library) and the sketch.js JavaScript code (which does all the work), enclosed by the appropriate html tags:
Example 10-3.
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
<script src="sketch.js"></script>
</head>
<body>
</body>
</html>
The JavaScript code, which does all the work, is below. Again, the code is commented fairly heavily. p5.js is similar to the Arduino language in that there is a setup()
function which runs once, and then a draw()
function which runs continuously thereafter. The setup()
function does the following:
- Create the MQTT object, which will be used to communicate with the MQTT library
- Set the callback functions, which will be called a connection to the MQTT broker is established or lost, and when a message arrives
- Creates elements on the web page for displaying different types of messages
- Set the background colour of the canvas
The draw()
function does nothing, because everything happens in the callback functions
Most of the interesting work happens in the mousePressed()
and mouseReleased()
callback functions. These events are detected by the p5.js system, and when they occur these functions are called, if they exist:
- The
mousePressed()
function sends a message (using the helper functionsendMqttMessage()
) to move the fist forward to create the “fistbump”, and also changes the canvas color to provide some visual feedback that a mouse button has been clicked - The
mouseReleased()
function sends a message to retract the fist, and returns the canvas to the original color.
The MQTT callback functions are detected and called by the MQTT library:
- The
onConnect()
function subscribes to our topic - The
onConnectionLost()
function only reports when a connection is lost - The
onMessageArrived()
function prints out any messages that are received
/*
* This web page is an example to be paired with a servo motor
* and an MQTT client subscribed to the same topic. When this web
* page is clicked, a message is sent via an MQTT broker. The subscribed
* client, when it receives the message, will move the servo motor to the
* position indicated in the message. The purpose is to deliver a remote
* physical "fistbump" to an individual located elsewhere in the world
* but on the internet.
*
* This sketch uses https://shiftr.io/ as the MQTT broker.
*
* This code uses the Eclipse Paho MQTT client library:
* https://www.eclipse.org/paho/clients/js/
*
* 20 May 2021 - Created by Michael Shiloh
* Based almost entirely on MqttClientButtonLed by Tom Igoe
* See https://tigoe.github.io/mqtt-examples/
*/
/*
* Although this is a comment, it tells Glitch that there are
* globally available functions and objects. This prevents Glitch
* from complaining about the MQTT and p5.js objects and functions
*/
/* global Vue, VueLocalStorage */
// MQTT client details:
let broker = {
hostname: 'public.cloud.shiftr.io',
port: 443
};
// MQTT client:
let client;
// client credentials:
// For shiftr.io, use public for both username and password
// unless you have an account on the site.
let creds = {
clientID: 'GSWA4E_ARM_Demo_webPage',
userName: 'public',
password: 'public'
};
// topic to subscribe to when you connect
// For shiftr.io, use whatever word you want for the topic
// unless you have an account on the site.
let topic = 'fistbump';
// HTML divs for messages
let localDiv; // local messages
let remoteDiv; // remote messages
let statusDiv; // debugging info
let instructionsDiv; // instructions
function setup() {
createCanvas(windowWidth, windowHeight);
// Create an MQTT client:
client = new Paho.MQTT.Client(broker.hostname, broker.port, creds.clientID);
// set callback handlers for the client:
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect to the MQTT broker:
client.connect(
{
onSuccess: onConnect, // callback function for when you connect
userName: creds.userName, // username
password: creds.password, // password
useSSL: true // use SSL
}
);
// create a div for the instructions
instructionsDiv = createDiv('Click anywhere to send a fistbump');
instructionsDiv.position(20, 20); // coordinates for the div
// create a div for local messages:
localDiv = createDiv('local messages will go here');
localDiv.position(20, 50);
// create a div for the response:
remoteDiv = createDiv('waiting for messages');
remoteDiv.position(20, 80);
// create a div for status messages:
statusDiv = createDiv('status messages will go here');
statusDiv.position(20, 110);
// Set the canvas color
background(240); // very light grey
}
function draw() {
// Nothing to do in draw() because all functionality is
// event driven via callback functions
}
/*
* Callback functions
*/
/* Callback functions for events that are detected by the
* p5.js system
*/
// Clicking the mouse anywhere in the canvas will send the MQTT
// message '170', which causes the servo motor to move to position
// 170 degrees, and the canvas color changes to medium grey.
function mousePressed() {
sendMqttMessage('170' );
background(220); // medium grey
localDiv.html('I sent a fistbump!');
}
// When a mouse button is released anywhere in the canvas send the MQTT
// message '10', which causes the servo motor to move to position
// 10 degrees, and the canvas returns to light grey.
function mouseReleased(){
sendMqttMessage('10');
background(240); // very light grey
localDiv.html('I withdrew my fist');
}
/* Callback functions that were set in the MQTT object.
* The MQTT library detects these events, and when they
* occur, the user supplied callback function are called.
*/
// called when the client connects
function onConnect() {
localDiv.html('client is connected');
remoteDiv.html('topic is ' + topic);
client.subscribe(topic);
}
// called when the client loses its connection
function onConnectionLost(response) {
if (response.errorCode !== 0) {
localDiv.html('onConnectionLost:' + response.errorMessage);
}
}
// called when a message arrives
function onMessageArrived(message) {
remoteDiv.html('I received a message:' + message.payloadString);
}
/*
* End of callback functions
*/
// Helper function which is called in order to send a message:
function sendMqttMessage(msg) {
// if the client is connected to the MQTT broker:
if (client.isConnected()) {
// start an MQTT message:
message = new Paho.MQTT.Message(msg);
// choose the destination topic:
message.destinationName = topic;
// send it:
client.send(message);
// print what you sent:
// statusDiv.html('I sent: ' + message.payloadString);
}
}
Now we need a place on the internet to serve this web page. There are many services for this, both paid and unpaid. We will use a service called glitch.com:
- Visit the website glitch.com
- Click on “Log In”
- Create an account, or sign in using one of the listed accounts you already may have.
- (Alternately, if you don’t want to create an account, you can click on “Email Magic Link”, enter your email address, and click on the link sent to your email address. This will give you an anonymous project.)
- You will be presented with the “Manage Your Projects” page and shown a variety of possible website types.
- Click on “Remix” button in the “Hello Webpage” box, which creates a new project with 4 default files: README.md, index.html, script.js, and style.css. We only need two of these, but the other two won’t bother us so you can leave them.
- Click on the “index.html” file and you will be presented with a simple editing screen. Delete everything there and paste in the contents shown above.
- Click on the “script.js” file and paste in the contents shown above for this file.
- Change the name of the file “script.js” to “sketch.js”, which is the convention for a p5 script file and is also the name we used in “index.html”
- Create a new file called “.eslintrc.json”. For the contents of this file just put in “{}”
- You may notice red dots on some lines (those containing calls to the MQTT and p5.js libraries). You can get rid of these by creating an empty file called “.eslintrc.json”, opening the terminal (available in the “tools” menu near the bottom left), typing “refresh” and pressing “enter”.
You can test the web page right there in the project. Near the top left corner you will see a pair of glasses and the word “Show”. Click on this and select one of the two options. I usually prefer “Next to The Code”. You will see our web page which consists of four lines, the first of which says “Click anywhere to send a fistbump”. If you click on this page you should see your servo motor move.
Once you have this all working properly, you can provide the URL to your friends around the world. To get this URL, click on the “Change URL” button above the window on the right, and copy the first line, which is the URL of your project. Glitch.com automatically assigns a new random URL to every project. Send this URL to your friends, and they can send you a fistbump!
Leave a Reply