50 |
51 | {% if site.google_analytics %}
52 |
60 | {% endif %}
61 |
62 |
--------------------------------------------------------------------------------
/arduino-clients/ArduinoMqttClient/ArduinoMqttClient.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client sender/receiver
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and both listens for messages on that topic and sends messages to it, a random number between 0 and 255.
6 | When the client receives a message, it parses it, and PWMs the built-in LED.
7 |
8 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
9 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
10 |
11 | Libraries used:
12 | * http://librarymanager/All#WiFiNINA or
13 | * http://librarymanager/All#WiFi101
14 | * http://librarymanager/All#WiFiS3
15 | * http://librarymanager/All#ArduinoMqttClient
16 |
17 | the arduino_secrets.h file:
18 | #define SECRET_SSID "" // network name
19 | #define SECRET_PASS "" // network password
20 | #define SECRET_MQTT_USER "public" // broker username
21 | #define SECRET_MQTT_PASS "public" // broker password
22 |
23 | created 11 June 2020
24 | updated 25 Feb 2025
25 | by Tom Igoe
26 | */
27 |
28 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
29 | // #include // use this for MKR1000
30 | // #include // use this for Uno R4 WiFi
31 | // #include // use this for ESP8266-based boards
32 | #include
33 | #include "arduino_secrets.h"
34 |
35 | // initialize WiFi connection. If the broker is using
36 | // encrypted mqtts, use SSL like so:
37 | // WiFiSSLClient wifi;
38 | // if the broker is not using mqtts, connect without SSL like so:
39 | WiFiClient wifi;
40 | MqttClient mqttClient(wifi);
41 |
42 | // details for MQTT client:
43 | char broker[] = "public.cloud.shiftr.io";
44 | int port = 1883;
45 | char topic[] = "aardvarks";
46 | String clientID = "tigoeClient";
47 |
48 | // last time the client sent a message, in ms:
49 | long lastTimeSent = 0;
50 | // message sending interval:
51 | int interval = 10 * 1000;
52 |
53 | void setup() {
54 | // initialize serial:
55 | Serial.begin(9600);
56 | // wait for serial monitor to open:
57 | if (!Serial) delay(3000);
58 | pinMode(LED_BUILTIN, OUTPUT);
59 | // connect to WiFi:
60 | connectToNetwork();
61 | // make the clientID unique by adding the last three digits of the MAC address:
62 | byte mac[6];
63 | WiFi.macAddress(mac);
64 | for (int i = 0; i < 3; i++) {
65 | clientID += String(mac[i], HEX);
66 | }
67 | // set the credentials for the MQTT client:
68 | mqttClient.setId(clientID);
69 | // if needed, login to the broker with a username and password:
70 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
71 | }
72 |
73 | void loop() {
74 | // if you disconnected from the network, reconnect:
75 | if (WiFi.status() != WL_CONNECTED) {
76 | connectToNetwork();
77 | // skip the rest of the loop until you are connected:
78 | return;
79 | }
80 |
81 | // if not connected to the broker, try to connect:
82 | if (!mqttClient.connected()) {
83 | Serial.println("attempting to connect to broker");
84 | connectToBroker();
85 | }
86 | // poll for new messages from the broker:
87 | mqttClient.poll();
88 |
89 | // once every interval, send a message:
90 | if (millis() - lastTimeSent > interval) {
91 | // get a random analog reading, divide by 4 to set range to 0-255:
92 | int sensorReading = analogRead(A0) / 4;
93 | if (mqttClient.connected()) {
94 | // start a new message on the topic:
95 | mqttClient.beginMessage(topic);
96 | // print the body of the message:
97 | mqttClient.print(sensorReading);
98 | // send the message:
99 | mqttClient.endMessage();
100 | // send a serial notification:
101 | Serial.print("published a message: ");
102 | Serial.println(sensorReading);
103 | // timestamp this message:
104 | lastTimeSent = millis();
105 | }
106 | }
107 | }
108 |
109 | boolean connectToBroker() {
110 | // if the MQTT client is not connected:
111 | if (!mqttClient.connect(broker, port)) {
112 | // print out the error message:
113 | Serial.print("MOTT connection failed. Error no: ");
114 | Serial.println(mqttClient.connectError());
115 | // return that you're not connected:
116 | return false;
117 | }
118 |
119 | // set the message receive callback:
120 | mqttClient.onMessage(onMqttMessage);
121 | // subscribe to a topic:
122 | Serial.print("Subscribing to topic: ");
123 | Serial.println(topic);
124 | mqttClient.subscribe(topic);
125 |
126 | // once you're connected, you
127 | // return that you're connected:
128 | return true;
129 | }
130 |
131 | void onMqttMessage(int messageSize) {
132 | // we received a message, print out the topic and contents
133 | Serial.println("Received a message with topic ");
134 | Serial.print(mqttClient.messageTopic());
135 | Serial.print(", length ");
136 | Serial.print(messageSize);
137 | Serial.println(" bytes:");
138 | String incoming = "";
139 | // use the Stream interface to print the contents
140 | while (mqttClient.available()) {
141 | incoming += (char)mqttClient.read();
142 | }
143 | // convert the incoming string to an int so you can use it:
144 | int result = incoming.toInt();
145 | // use the result to dim the builtin LED:
146 | if (result > 0) {
147 | analogWrite(LED_BUILTIN, result);
148 | }
149 | // print the result:
150 | Serial.println(result);
151 | delay(100);
152 | }
153 |
154 | void connectToNetwork() {
155 | // try to connect to the network:
156 | while (WiFi.status() != WL_CONNECTED) {
157 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
158 | //Connect to WPA / WPA2 network:
159 | WiFi.begin(SECRET_SSID, SECRET_PASS);
160 | delay(2000);
161 | }
162 |
163 | // print IP address once connected:
164 | Serial.print("Connected. My IP address: ");
165 | Serial.println(WiFi.localIP());
166 |
167 | digitalWrite(LED_BUILTIN, HIGH);
168 | }
--------------------------------------------------------------------------------
/arduino-clients/ArduinoMqttClientESP32_Eduroam/ArduinoMqttClientESP32_Eduroam.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client sender/receiver using on Nano ESP32
3 | on WPA2-enterprise on on Eduroam
4 |
5 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
6 | and both listens for messages on that topic and sends messages to it, an analog reading.
7 | When the client receives a message, it prints it.
8 |
9 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
10 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
11 |
12 | Here's what your arduino_secrets.h file should look like:
13 | #define EAP_IDENTITY "" // use identity@institution.domain in for most institutions
14 | #define EAP_USERNAME "" // usually just a repeat of the identity
15 | #define EAP_PASSWORD "" // your password
16 | #define SECRET_SSID "eduroam" // eduroam SSID
17 | #define SECRET_MQTT_USER "public" // MQTT broker username
18 | #define SECRET_MQTT_PASS "public" // MQTT broker password
19 |
20 | Libraries used:
21 | * http://librarymanager/All#WiFi // for Nano ESP32 WiFi
22 | * esp_wpa2.h for Nano ESP23 WiFi WPA2-enterprise
23 | * http://librarymanager/All#ArduinoMqttClient
24 |
25 | the arduino_secrets.h file:
26 | #define EAP_IDENTITY "" // use identity@institution.domain in for most institutions
27 | #define EAP_USERNAME "" // usually just a repeat of the identity
28 | #define EAP_PASSWORD "" // your password
29 | #define SECRET_SSID "eduroam" // eduroam SSID
30 | #define SECRET_MQTT_USER "public" // broker username
31 | #define SECRET_MQTT_PASS "public" // broker password
32 |
33 | created 4 Mar 2024
34 | modified 14 Feb 2025
35 | by Tom Igoe
36 | */
37 |
38 | #include // use this for Nano ESP32
39 | #include "esp_wpa2.h" //wpa2 library for connections to Enterprise networks
40 | #include
41 | #include "arduino_secrets.h"
42 |
43 | // initialize WiFi connection as SSL:
44 | WiFiClient wifi;
45 | MqttClient mqttClient(wifi);
46 |
47 | // details for MQTT client:
48 | char broker[] = "public.cloud.shiftr.io";
49 | int port = 1883;
50 | char topic[] = "aardvarks";
51 | String clientID = "nanoESPClient-";
52 |
53 | // sending interval:
54 | const long interval = 120 * 1000;
55 | // last time you sent a reading:
56 | int lastTimeSent = 0;
57 |
58 | void setup() {
59 | // initialize serial:
60 | Serial.begin(9600);
61 | // wait for serial monitor to open:
62 | if (!Serial) delay(3000);
63 | pinMode(LED_BUILTIN, OUTPUT);
64 | // connect to WiFi:
65 | connectToNetwork();
66 | // make the clientID unique by adding the last three digits of the MAC address:
67 | byte mac[6];
68 | WiFi.macAddress(mac);
69 | // add the mac address to the clientID for a unique username:
70 | for (int i = 0; i < 3; i++) {
71 | clientID += String(mac[i], HEX);
72 | }
73 | // set the credentials for the MQTT client:
74 | mqttClient.setId(clientID);
75 | Serial.println("client ID:" + clientID);
76 | // if needed, login to the broker with a username and password:
77 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
78 | }
79 |
80 | void loop() {
81 | // if you disconnected from the network, reconnect:
82 | if (WiFi.status() != WL_CONNECTED) {
83 | connectToNetwork();
84 | // skip the rest of the loop until you are connected:
85 | return;
86 | }
87 |
88 | // if not connected to the broker, try to connect:
89 | if (!mqttClient.connected()) {
90 | Serial.println("attempting to connect to broker");
91 | connectToBroker();
92 | }
93 | // poll for new messages from the broker:
94 | mqttClient.poll();
95 | if (millis() - lastTimeSent < interval && lastTimeSent != 0) return;
96 | // read analog in on pin A0:
97 | int sensor = analogRead(A0);
98 |
99 | // if the client's connected:
100 | if (mqttClient.connected()) {
101 | // start a new message on the topic:
102 | mqttClient.beginMessage(topic);
103 | // print the body of the message:
104 | mqttClient.print(sensor);
105 | // send the message:
106 | mqttClient.endMessage();
107 | // send a serial notification:
108 | Serial.print("published a message: ");
109 | Serial.println(sensor);
110 | lastTimeSent = millis();
111 | }
112 | }
113 |
114 | boolean connectToBroker() {
115 | // if the MQTT client is not connected:
116 | if (!mqttClient.connect(broker, port)) {
117 | // print out the error message:
118 | Serial.print("MOTT connection failed. Error no: ");
119 | Serial.println(mqttClient.connectError());
120 | // return that you're not connected:
121 | return false;
122 | }
123 |
124 | // set the message receive callback:
125 | mqttClient.onMessage(onMqttMessage);
126 | // subscribe to a topic:
127 | Serial.print("Subscribing to topic: ");
128 | Serial.println(topic);
129 | mqttClient.subscribe(topic);
130 |
131 | // once you're connected, you
132 | // return that you're connected:
133 | return true;
134 | }
135 |
136 | void onMqttMessage(int messageSize) {
137 | // we received a message, print out the topic and contents
138 | Serial.println("Received a message with topic ");
139 | Serial.print(mqttClient.messageTopic());
140 | Serial.print(", length ");
141 | Serial.print(messageSize);
142 | Serial.println(" bytes:");
143 | String incoming = "";
144 | // use the Stream interface to print the contents
145 | while (mqttClient.available()) {
146 | incoming += (char)mqttClient.read();
147 | }
148 | // convert the incoming string to an int so you can use it:
149 | int result = incoming.toInt();
150 | // use the result to dim the builtin LED:
151 | if (result > 0) {
152 | analogWrite(LED_BUILTIN, result);
153 | }
154 | // print the result:
155 | Serial.println(result);
156 | delay(100);
157 | }
158 |
159 | void connectToNetwork() {
160 | // try to connect to the network:
161 | while (WiFi.status() != WL_CONNECTED) {
162 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
163 | //Connect to WPA / WPA2 network:
164 | WiFi.begin(SECRET_SSID, WPA2_AUTH_PEAP, EAP_IDENTITY, EAP_USERNAME, EAP_PASSWORD);
165 | delay(2000);
166 | }
167 |
168 | // print IP address once connected:
169 | Serial.print("Connected. My IP address: ");
170 | Serial.println(WiFi.localIP());
171 | }
--------------------------------------------------------------------------------
/arduino-clients/ArduinoMqttClientLamp/ArduinoMqttClientLamp.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client Lamp sender/receiver
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and both listens for messages on that topic and sends messages to it, a random number between 0 and 255.
6 | When the client receives a message, it parses it, and PWMs an LED on pin 6.
7 |
8 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
9 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
10 |
11 | Libraries used:
12 | * http://librarymanager/All#WiFiNINA or
13 | * http://librarymanager/All#WiFi101
14 | * http://librarymanager/All#WiFiS3
15 | * http://librarymanager/All#ArduinoMqttClient
16 |
17 | the arduino_secrets.h file:
18 | #define SECRET_SSID "" // network name
19 | #define SECRET_PASS "" // network password
20 | #define SECRET_MQTT_USER "public" // broker username
21 | #define SECRET_MQTT_PASS "public" // broker password
22 |
23 | created 11 June 2020
24 | updated 7 Nov 2024
25 | by Tom Igoe
26 | */
27 |
28 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
29 | // #include // use this for MKR1000
30 | // #include // use this for Uno R4 WiFi
31 | // #include // use this for ESP8266-based boards
32 | #include
33 | #include "arduino_secrets.h"
34 |
35 | // initialize WiFi connection as SSL:
36 | WiFiClient wifi;
37 | MqttClient mqttClient(wifi);
38 |
39 | // details for MQTT client:
40 | char broker[] = "yoursite.com";
41 | int port = 1883;
42 | char topic[] = "lamp/brightness";
43 | String clientID = "lightClient-";
44 |
45 | // last time the client sent a message, in ms:
46 | long lastSensorReading = 0;
47 | int threshold = 4;
48 |
49 | void setup() {
50 | // initialize serial:
51 | Serial.begin(9600);
52 | // wait for serial monitor to open:
53 | if (!Serial) delay(3000);
54 | pinMode(6, OUTPUT);
55 | // connect to WiFi:
56 | connectToNetwork();
57 | // make the clientID unique by adding the last three digits of the MAC address:
58 | byte mac[6];
59 | WiFi.macAddress(mac);
60 | for (int i = 0; i < 3; i++) {
61 | clientID += String(mac[i], HEX);
62 | }
63 | // set the credentials for the MQTT client:
64 | mqttClient.setId(clientID);
65 | // if needed, login to the broker with a username and password:
66 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
67 | }
68 |
69 | void loop() {
70 | // if you disconnected from the network, reconnect:
71 | if (WiFi.status() != WL_CONNECTED) {
72 | connectToNetwork();
73 | // skip the rest of the loop until you are connected:
74 | return;
75 | }
76 |
77 | // if not connected to the broker, try to connect:
78 | if (!mqttClient.connected()) {
79 | Serial.println("attempting to connect to broker");
80 | connectToBroker();
81 | }
82 | // poll for new messages from the broker:
83 | mqttClient.poll();
84 | // get an analog reading, divide by 4 to set range to 0-255:
85 |
86 | int sensorReading = analogRead(A0) / 4;
87 |
88 | // once every interval, send a message:
89 | if (abs(sensorReading - lastSensorReading) > threshold) {
90 | if (mqttClient.connected()) {
91 | // start a new message on the topic:
92 | mqttClient.beginMessage("lamp/knob");
93 | // print the body of the message:
94 | mqttClient.print(sensorReading);
95 | // send the message:
96 | mqttClient.endMessage();
97 | // send a serial notification:
98 | Serial.print("published a message: ");
99 | Serial.println(sensorReading);
100 | // save reading for next time:
101 | lastSensorReading = sensorReading;
102 | }
103 | }
104 | }
105 |
106 | boolean connectToBroker() {
107 | // if the MQTT client is not connected:
108 | if (!mqttClient.connect(broker, port)) {
109 | // print out the error message:
110 | Serial.print("MOTT connection failed. Error no: ");
111 | Serial.println(mqttClient.connectError());
112 | // return that you're not connected:
113 | return false;
114 | }
115 |
116 | // set the message receive callback:
117 | mqttClient.onMessage(onMqttMessage);
118 | // subscribe to a topic:
119 | Serial.print("Subscribing to topic: ");
120 | Serial.println(topic);
121 | mqttClient.subscribe(topic);
122 |
123 | // once you're connected, you
124 | // return that you're connected:
125 | return true;
126 | }
127 |
128 | void onMqttMessage(int messageSize) {
129 | // we received a message, print out the topic and contents
130 | Serial.println("Received a message with topic ");
131 | Serial.print(mqttClient.messageTopic());
132 | Serial.print(", length ");
133 | Serial.print(messageSize);
134 | Serial.println(" bytes:");
135 | String incoming = "";
136 | // use the Stream interface to print the contents
137 | while (mqttClient.available()) {
138 | incoming += (char)mqttClient.read();
139 | }
140 | // convert the incoming string to an int so you can use it:
141 | int result = incoming.toInt();
142 | // use the result to dim the builtin LED:
143 | if (result > 0) {
144 | analogWrite(6, result);
145 | }
146 | // print the result:
147 | Serial.println(result);
148 | delay(100);
149 | }
150 |
151 | void connectToNetwork() {
152 | // try to connect to the network:
153 | while (WiFi.status() != WL_CONNECTED) {
154 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
155 | //Connect to WPA / WPA2 network:
156 | WiFi.begin(SECRET_SSID, SECRET_PASS);
157 | delay(2000);
158 | }
159 |
160 | // print IP address once connected:
161 | Serial.print("Connected. My IP address: ");
162 | Serial.println(WiFi.localIP());
163 | }
--------------------------------------------------------------------------------
/arduino-clients/ArduinoMqttClientTouchReadESP32/ArduinoMqttClientTouchReadESP32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client sender/receiver using touchRead on Nano ESP32
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and both listens for messages on that topic and sends messages to it, a random number between 0 and 255.
6 | When the client receives a message, it prints it.
7 |
8 | Reads the capacitive touch reading on the Nano ESP32. The touch and release algorithm here
9 | could use some tuning, it's not perfect.
10 |
11 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
12 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
13 |
14 | Libraries used:
15 | * http://librarymanager/All#WiFi // for Nano ESP32 WiFi
16 | * http://librarymanager/All#ArduinoMqttClient
17 |
18 | the arduino_secrets.h file:
19 | #define SECRET_SSID "" // network name
20 | #define SECRET_PASS "" // network password
21 | #define SECRET_MQTT_USER "public" // broker username
22 | #define SECRET_MQTT_PASS "public" // broker password
23 |
24 | created 4 Mar 2024
25 | by Tom Igoe
26 | Thanks to Alyshia Bustos for the reason to try touchRead on the ESP32
27 | */
28 |
29 | #include // use this for Nano ESP32
30 | #include
31 | #include "arduino_secrets.h"
32 |
33 | // initialize WiFi connection as SSL:
34 | WiFiClient wifi;
35 | MqttClient mqttClient(wifi);
36 |
37 | // details for MQTT client:
38 | char broker[] = "public.cloud.shiftr.io";
39 | int port = 1883;
40 | char topic[] = "touchSensor";
41 | String clientID = "touchMqttClient-";
42 |
43 | // threshold for sensor change (discovered through experiment, yours may differ):
44 | int touchThreshold = 36000;
45 | // last sensor reading:
46 | int lastSensorRead = 0;
47 |
48 | void setup() {
49 | // initialize serial:
50 | Serial.begin(9600);
51 | // wait for serial monitor to open:
52 | if (!Serial) delay(3000);
53 | pinMode(LED_BUILTIN, OUTPUT);
54 | // connect to WiFi:
55 | connectToNetwork();
56 | // make the clientID unique by adding the last three digits of the MAC address:
57 | byte mac[6];
58 | WiFi.macAddress(mac);
59 | // add the mac address to the clientID for a unique username:
60 | for (int i = 0; i < 3; i++) {
61 | clientID += String(mac[i], HEX);
62 | }
63 | // set the credentials for the MQTT client:
64 | mqttClient.setId(clientID);
65 | Serial.println("client ID:" + clientID);
66 | // if needed, login to the broker with a username and password:
67 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
68 | }
69 |
70 | void loop() {
71 | // if you disconnected from the network, reconnect:
72 | if (WiFi.status() != WL_CONNECTED) {
73 | connectToNetwork();
74 | // skip the rest of the loop until you are connected:
75 | return;
76 | }
77 |
78 | // if not connected to the broker, try to connect:
79 | if (!mqttClient.connected()) {
80 | Serial.println("attempting to connect to broker");
81 | connectToBroker();
82 | }
83 | // poll for new messages from the broker:
84 | mqttClient.poll();
85 | String msg = "";
86 | // read capacitive touch on pin A0:
87 | int touchSensor = touchRead(A0);
88 | // if it crossed the threshold going up, there's a touch:
89 | if (touchSensor > touchThreshold && lastSensorRead < touchThreshold) {
90 | msg = "touched";
91 | }
92 | // if it crossed the threshold going down, there's a release:
93 | if (touchSensor < touchThreshold && lastSensorRead > touchThreshold) {
94 | msg = "released";
95 | }
96 | // save the sensor reading for comparison next time:
97 | lastSensorRead = touchSensor;
98 | // if the client's connected:
99 | if (mqttClient.connected()) {
100 | // if there's a message to send:
101 | if (msg != "") {
102 | // start a new message on the topic:
103 | mqttClient.beginMessage(topic);
104 | // print the body of the message:
105 | mqttClient.print(msg);
106 | // send the message:
107 | mqttClient.endMessage();
108 | // send a serial notification:
109 | Serial.print("published a message: ");
110 | Serial.println(msg);
111 | }
112 | }
113 | }
114 |
115 | boolean connectToBroker() {
116 | // if the MQTT client is not connected:
117 | if (!mqttClient.connect(broker, port)) {
118 | // print out the error message:
119 | Serial.print("MOTT connection failed. Error no: ");
120 | Serial.println(mqttClient.connectError());
121 | // return that you're not connected:
122 | return false;
123 | }
124 |
125 | // set the message receive callback:
126 | mqttClient.onMessage(onMqttMessage);
127 | // subscribe to a topic:
128 | Serial.print("Subscribing to topic: ");
129 | Serial.println(topic);
130 | mqttClient.subscribe(topic);
131 |
132 | // once you're connected, you
133 | // return that you're connected:
134 | return true;
135 | }
136 |
137 | void onMqttMessage(int messageSize) {
138 | // we received a message, print out the topic and contents
139 | Serial.println("Received a message with topic ");
140 | Serial.print(mqttClient.messageTopic());
141 | Serial.print(", length ");
142 | Serial.print(messageSize);
143 | Serial.println(" bytes:");
144 | String incoming = "";
145 | // use the Stream interface to print the contents
146 | while (mqttClient.available()) {
147 | incoming += (char)mqttClient.read();
148 | }
149 | // convert the incoming string to an int so you can use it:
150 | int result = incoming.toInt();
151 | // use the result to dim the builtin LED:
152 | if (result > 0) {
153 | analogWrite(LED_BUILTIN, result);
154 | }
155 | // print the result:
156 | Serial.println(result);
157 | delay(100);
158 | }
159 |
160 | void connectToNetwork() {
161 | // try to connect to the network:
162 | while (WiFi.status() != WL_CONNECTED) {
163 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
164 | //Connect to WPA / WPA2 network:
165 | WiFi.begin(SECRET_SSID, SECRET_PASS);
166 | delay(2000);
167 | }
168 |
169 | // print IP address once connected:
170 | Serial.print("Connected. My IP address: ");
171 | Serial.println(WiFi.localIP());
172 | }
--------------------------------------------------------------------------------
/arduino-clients/ArduinoMqttClientWithWill/ArduinoMqttClientWithWill.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client sender/receiver with will
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and both listens for messages on that topic and sends messages to it, a random number between 0 and 255.
6 | When the client receives a message, it parses it, and PWMs the built-in LED.
7 | This client also has a last will and testament property. with each reading sent,
8 | it also updates the will topic with the current date and time. If another
9 | reading does not show up within the keepAlive interval, the broker
10 | will publish the will topic.
11 |
12 | Because this uses the SAMD chip's internal realtime clock (RTC),
13 | it will only run on the Nano 33 IoT and MKR boards or other SAMD boards.
14 |
15 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
16 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
17 |
18 | Libraries used:
19 | * http://librarymanager/All#WiFiNINA or
20 | * http://librarymanager/All#WiFi101
21 | * http://librarymanager/All#ArduinoMqttClient
22 | * http://librarymanager/All#RTCZero
23 |
24 | the arduino_secrets.h file:
25 | #define SECRET_SSID "" // network name
26 | #define SECRET_PASS "" // network password
27 | #define SECRET_MQTT_USER "public" // broker username
28 | #define SECRET_MQTT_PASS "public" // broker password
29 |
30 | created 28 Mar 2023
31 | by Tom Igoe
32 | */
33 |
34 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
35 | // #include // use this for MKR1000
36 | #include
37 | #include
38 | #include "arduino_secrets.h"
39 |
40 | // initialize WiFi connection as SSL:
41 | WiFiSSLClient wifi;
42 | MqttClient mqttClient(wifi);
43 | // initialize realtime clock
44 | RTCZero rtc;
45 |
46 | // details for MQTT client:
47 | char broker[] = "public.cloud.shiftr.io";
48 | int port = 8883;
49 | char topic[] = "aardvarks";
50 | String clientID = "arduinoMqttClient-";
51 | // properties for the MQTT last will and testament:
52 | String willPayload = "offline";
53 | bool willRetain = true;
54 | int willQos = 1;
55 | String willTopic = String(topic) + "/last_seen";
56 |
57 | // last time the client sent a message, in ms:
58 | long lastTimeSent = 0;
59 | // message sending interval:
60 | int interval = 10 * 1000;
61 | // keepAlive interval for the will:
62 | int keepAliveInterval = 60 * 1000;
63 | // connection timeout:
64 | int connectionTimeout = 30 * 1000;
65 |
66 | void setup() {
67 | // initialize serial:
68 | Serial.begin(9600);
69 | // wait for serial monitor to open:
70 | if (!Serial) delay(3000);
71 | // initialize realtime clock:
72 | rtc.begin();
73 | pinMode(LED_BUILTIN, OUTPUT);
74 | // connect to WiFi:
75 | connectToNetwork();
76 | // make the clientID unique by adding the last three digits of the MAC address:
77 | byte mac[6];
78 | WiFi.macAddress(mac);
79 | for (int i = 0; i < 3; i++) {
80 | clientID += String(mac[i], HEX);
81 | }
82 | // set the credentials for the MQTT client:
83 | mqttClient.setId(clientID);
84 | // if needed, login to the broker with a username and password:
85 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
86 | // after keepAliveInterval, the broker will publish the will:
87 | mqttClient.setKeepAliveInterval(keepAliveInterval);
88 | // after connectionTimeout the client will produce a connection error:
89 | mqttClient.setConnectionTimeout(connectionTimeout);
90 | }
91 |
92 | void loop() {
93 | // if you disconnected from the network, reconnect:
94 | if (WiFi.status() != WL_CONNECTED) {
95 | connectToNetwork();
96 | // skip the rest of the loop until you are connected:
97 | return;
98 | }
99 |
100 | // if not connected to the broker, try to connect:
101 | if (!mqttClient.connected()) {
102 | Serial.println("attempting to connect to broker");
103 | connectToBroker();
104 | }
105 |
106 | // poll for new messages from the broker:
107 | mqttClient.poll();
108 |
109 | // once every interval, send a message:
110 | if (millis() - lastTimeSent > interval) {
111 | // get a random analog reading, divide by 4 to set range to 0-255:
112 | int sensorReading = analogRead(A0) / 4;
113 | if (mqttClient.connected()) {
114 | // start a new message on the topic:
115 | mqttClient.beginMessage(topic);
116 | // print the body of the message:
117 | mqttClient.print(sensorReading);
118 | // send the message:
119 | mqttClient.endMessage();
120 | // update the will topic with the last successful timestamp:
121 | updateWill();
122 |
123 | // send a serial notification:
124 | Serial.print("published a message: ");
125 | Serial.println(sensorReading);
126 | // timestamp this message:
127 | lastTimeSent = millis();
128 | }
129 | }
130 | }
131 |
132 | boolean connectToBroker() {
133 | // update the will topic with the last successful timestamp:
134 | updateWill();
135 | // if the MQTT client is not connected:
136 | if (!mqttClient.connect(broker, port)) {
137 | // print out the error message:
138 | Serial.print("MOTT connection failed. Error no: ");
139 | Serial.println(mqttClient.connectError());
140 | // return that you're not connected:
141 | return false;
142 | }
143 |
144 | // set the message receive callback:
145 | mqttClient.onMessage(onMqttMessage);
146 | // subscribe to a topic:
147 | Serial.print("Subscribing to topic: ");
148 | Serial.println(topic);
149 | mqttClient.subscribe(topic);
150 |
151 | // once you're connected, you
152 | // return that you're connected:
153 | return true;
154 | }
155 |
156 |
157 | void updateWill() {
158 | if (mqttClient.connected()) {
159 | // make an ISO8601 string with the current RTC time:
160 | willPayload = getISOString();
161 | // set the will value:
162 | mqttClient.beginWill(willTopic, willPayload.length(), willRetain, willQos);
163 | // send it to the broker:
164 | mqttClient.print(willPayload);
165 | // close the connection:
166 | mqttClient.endWill();
167 | }
168 | }
169 |
170 | void onMqttMessage(int messageSize) {
171 | // we received a message, print out the topic and contents
172 | Serial.println("Received a message with topic ");
173 | Serial.print(mqttClient.messageTopic());
174 | Serial.print(", length ");
175 | Serial.print(messageSize);
176 | Serial.println(" bytes:");
177 | String incoming = "";
178 | // use the Stream interface to print the contents
179 | while (mqttClient.available()) {
180 | incoming += (char)mqttClient.read();
181 | }
182 | // convert the incoming string to an int so you can use it:
183 | int result = incoming.toInt();
184 | // use the result to dim the builtin LED:
185 | if (result > 0) {
186 | analogWrite(LED_BUILTIN, result);
187 | }
188 | // print the result:
189 | Serial.println(result);
190 | }
191 |
192 | void connectToNetwork() {
193 | // try to connect to the network:
194 | while (WiFi.status() != WL_CONNECTED) {
195 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
196 | //Connect to WPA / WPA2 network:
197 | WiFi.begin(SECRET_SSID, SECRET_PASS);
198 | delay(2000);
199 | }
200 | // get the current time from the network:
201 | long epoch = 0;
202 | while (epoch == 0) {
203 | epoch = WiFi.getTime();
204 | }
205 | rtc.setEpoch(epoch);
206 | // print current time:
207 | Serial.println(getISOString());
208 |
209 | // print IP address once connected:
210 | Serial.print("Connected. My IP address: ");
211 | Serial.println(WiFi.localIP());
212 | }
213 |
214 | // make an ISO8601 string from the current time. It would look like this:
215 | // YYYY-MM-DDThh:mm:ssZ
216 | String getISOString() {
217 | // start with the century:
218 | String result = "20";
219 | // add the year:
220 | int year = rtc.getYear();
221 | // leading 0 for nubmers less than 10:
222 | if (year < 10) result += "0";
223 | result += String(year);
224 | result += "-";
225 | // add the month:
226 | int month = rtc.getMonth();
227 | if (month < 10) result += "0";
228 | result += String(month);
229 | result += "-";
230 | // add the day:
231 | int day = rtc.getDay();
232 | if (day < 10) result += "0";
233 | result += String(day);
234 | result += "T";
235 | // add the hours:
236 | int hour = rtc.getHours();
237 | if (hour < 10) result += "0";
238 | result += String(hour);
239 | result += ":";
240 | // add the minutes:
241 | int minute = rtc.getMinutes();
242 | if (minute < 10) result += "0";
243 | result += String(minute);
244 | result += ":";
245 | // add the seconds:
246 | int second = rtc.getSeconds();
247 | if (second < 10) result += "0";
248 | result += String(second);
249 | // add the closing character:
250 | result += "Z";
251 | // return the string:
252 | return result;
253 | }
254 |
--------------------------------------------------------------------------------
/arduino-clients/MqttClientHueControl/MqttClientHueControl.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client with a Philips Hue Client
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subsrcibes to a topic,
5 | listens for messages on that topic and uses them to control a Philips Hue light
6 | using the ArduinoHttpClient library.
7 |
8 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
9 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
10 |
11 | Libraries used:
12 | * http://librarymanager/All#WiFiNINA or
13 | * http://librarymanager/All#WiFi101
14 | * http://librarymanager/All#ArduinoMqttClient
15 | * http://librarymanager/All#ArduinoHttpClient
16 |
17 | the arduino_secrets.h file:
18 | #define SECRET_SSID "" // network name
19 | #define SECRET_PASS "" // network password
20 | #define SECRET_MQTT_USER "public" // broker username
21 | #define SECRET_MQTT_PASS "public" // broker password
22 |
23 | created 27 Sep 2020
24 | updated 25 Feb 2023
25 | by Tom Igoe
26 | */
27 |
28 | #include
29 | #include
30 | #include
31 | #include "arduino_secrets.h"
32 |
33 | // initialize WiFi connection as SSL:
34 | WiFiSSLClient wifi;
35 | MqttClient mqttClient(wifi);
36 |
37 | // details for MQTT client:
38 | char broker[] = "public.cloud.shiftr.io";
39 | int port = 8883;
40 | char topic[] = "lights";
41 | String clientID = "arduinoHueClient-";
42 |
43 | // properties of the Hue light:
44 | int intensity = 0;
45 | int lastIntensity = 0;
46 | int lightNumber = 3;
47 |
48 | // fill in IP address of the HUE bridge
49 | char hueHubIP[] = "192.168.0.3";
50 | String hueUserName = "huebridgeusername"; // fill in hue bridge username
51 | HttpClient httpClient = HttpClient(wifi, hueHubIP);
52 |
53 | void setup() {
54 | // initialize serial:
55 | Serial.begin(9600);
56 | // wait for serial monitor to open:
57 | if (!Serial) delay(3000);
58 | pinMode(LED_BUILTIN, OUTPUT);
59 | // connect to WiFi:
60 | connectToNetwork();
61 | // make the clientID unique by adding the last three digits of the MAC address:
62 | byte mac[6];
63 | WiFi.macAddress(mac);
64 | for (int i = 0; i < 3; i++) {
65 | clientID += String(mac[i], HEX);
66 | }
67 | // set the credentials for the MQTT client:
68 | mqttClient.setId(clientID);
69 | // if needed, login to the broker with a username and password:
70 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
71 | }
72 |
73 | void loop() {
74 | // turn on built-in LED when you are connected to WiFi:
75 | digitalWrite(LED_BUILTIN, WiFi.status());
76 | //if you disconnected from the network, reconnect:
77 | if (WiFi.status() != WL_CONNECTED) {
78 | connectToNetwork();
79 | // skip the rest of the loop until you are connected:
80 | return;
81 | }
82 |
83 | // if not connected to the broker, try to connect:
84 | if (!mqttClient.connected()) {
85 | Serial.println("attempting to connect to broker");
86 | connectToBroker();
87 | }
88 | // poll for new messages from the broker:
89 | mqttClient.poll();
90 |
91 | // if the LED is on:
92 | if (intensity != lastIntensity) {
93 | sendRequest(lightNumber, "bri", intensity); // turn light on
94 | lastIntensity = intensity;
95 | }
96 | }
97 |
98 |
99 | void onMqttMessage(int messageSize) {
100 | // we received a message, print out the topic and contents
101 | Serial.println("Received a message with topic ");
102 | Serial.print(mqttClient.messageTopic());
103 | Serial.print(", length ");
104 | Serial.print(messageSize);
105 | Serial.println(" bytes:");
106 |
107 | // read the message:
108 | while (mqttClient.available()) {
109 | // convert numeric string to an int:
110 | int message = mqttClient.parseInt();
111 | Serial.println(message);
112 | // if the message matches client's number, set the LED to full intensity:
113 | if (message > 0 && message < 255) {
114 | intensity = message;
115 | }
116 | }
117 | }
118 |
119 | void sendRequest(int light, String cmd, int value) {
120 | // make a String for the HTTP request path:
121 | String request = "/api/" + hueUserName;
122 | request += "/lights/";
123 | request += light;
124 | request += "/state/";
125 |
126 | String contentType = "application/json";
127 |
128 | // make a string for the JSON command:
129 | String hueCmd = "{\"" + cmd;
130 | hueCmd += "\":";
131 | hueCmd += String(value);
132 | hueCmd += "}";
133 | // see what you assembled to send:
134 | Serial.print("PUT request to server: ");
135 | Serial.println(request);
136 | Serial.print("JSON command to server: ");
137 |
138 | // make the PUT request to the hub:
139 | httpClient.put(request, contentType, hueCmd);
140 |
141 | // read the status code and body of the response
142 | int statusCode = httpClient.responseStatusCode();
143 | String response = httpClient.responseBody();
144 |
145 | Serial.println(hueCmd);
146 | Serial.print("Status code from server: ");
147 | Serial.println(statusCode);
148 | Serial.print("Server response: ");
149 | Serial.println(response);
150 | Serial.println();
151 | }
152 |
153 |
154 | boolean connectToBroker() {
155 | // if the MQTT client is not connected:
156 | if (!mqttClient.connect(broker, port)) {
157 | // print out the error message:
158 | Serial.print("MOTT connection failed. Error no: ");
159 | Serial.println(mqttClient.connectError());
160 | // return that you're not connected:
161 | return false;
162 | }
163 |
164 | // set the message receive callback:
165 | mqttClient.onMessage(onMqttMessage);
166 | // subscribe to a topic:
167 | Serial.print("Subscribing to topic: ");
168 | Serial.println(topic);
169 | mqttClient.subscribe(topic);
170 |
171 | // once you're connected
172 | // return that you're connected:
173 | return true;
174 | }
175 |
176 | void connectToNetwork() {
177 | // try to connect to the network:
178 | while (WiFi.status() != WL_CONNECTED) {
179 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
180 | //Connect to WPA / WPA2 network:
181 | WiFi.begin(SECRET_SSID, SECRET_PASS);
182 | delay(2000);
183 | }
184 |
185 | // print IP address once connected:
186 | Serial.print("Connected. My IP address: ");
187 | Serial.println(WiFi.localIP());
188 | }
189 |
--------------------------------------------------------------------------------
/arduino-clients/MqttClientMIDIController/MqttClientMIDIController.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client that sends MIDI
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and sends messages on that topic. The messages are three-byte arrays that are MIDI
6 | noteon and noteoff messages.
7 |
8 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
9 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
10 |
11 | Libraries used:
12 | * http://librarymanager/All#WiFiNINA or
13 | * http://librarymanager/All#WiFi101
14 | * http://librarymanager/All#ArduinoMqttClient
15 |
16 | the arduino_secrets.h file:
17 | #define SECRET_SSID "" // network name
18 | #define SECRET_PASS "" // network password
19 | #define SECRET_MQTT_USER "public" // broker username
20 | #define SECRET_MQTT_PASS "public" // broker password
21 |
22 | created 24 Nov 2020
23 | modified 5 Jan 2023
24 | by Tom Igoe
25 | */
26 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
27 | // #include // use this for MKR1000
28 | #include
29 | #include "arduino_secrets.h"
30 |
31 | // initialize WiFi connection:
32 | WiFiSSLClient wifi;
33 | MqttClient mqttClient(wifi);
34 | const int buttonPin = 4;
35 |
36 |
37 | // details for MQTT client:
38 | char broker[] = "public.cloud.shiftr.io";
39 | int port = 8883;
40 | char topic[] = "midi";
41 | String clientID = "arduinoMidiControllerClient-";
42 |
43 | // musical items:
44 | int major[] = { 2, 2, 1, 2, 2, 2, 1 };
45 | // an array to hold the final notes of the scale:
46 | int scale[8];
47 |
48 | // start with middle C:
49 | int tonic = 48; // MIDI note value for middle C
50 | // note to play:
51 | int noteValue = tonic;
52 |
53 | // previous state of the button:
54 | int lastButtonState = LOW;
55 | void setup() {
56 | pinMode(buttonPin, INPUT_PULLUP);
57 |
58 | // initialize serial:
59 | Serial.begin(9600);
60 | // wait for serial monitor to open:
61 | if (!Serial) delay(3000);
62 | pinMode(LED_BUILTIN, OUTPUT);
63 | // connect to WiFi:
64 | connectToNetwork();
65 | // make the clientID unique by adding the last three digits of the MAC address:
66 | byte mac[6];
67 | WiFi.macAddress(mac);
68 | for (int i = 0; i < 3; i++) {
69 | clientID += String(mac[i], HEX);
70 | }
71 | // set the credentials for the MQTT client:
72 | mqttClient.setId(clientID);
73 | // if needed, login to the broker with a username and password:
74 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
75 |
76 | // fill the scale array with the scale you want:
77 | // start with the initial note:
78 | scale[0] = tonic;
79 | int note = scale[0];
80 | // iterate over the intervals, adding each to the next note
81 | // in the scale. You can change major to naturalMinor
82 | // if you want that kind of scale instead:
83 | for (int n = 0; n < 7; n++) {
84 | note = note + major[n];
85 | scale[n + 1] = note;
86 | }
87 | }
88 |
89 | void loop() {
90 | // if you disconnected from the network, reconnect:
91 | if (WiFi.status() != WL_CONNECTED) {
92 | connectToNetwork();
93 | // skip the rest of the loop until you are connected:
94 | return;
95 | }
96 |
97 | // if not connected to the broker, try to connect:
98 | if (!mqttClient.connected()) {
99 | Serial.println("attempting to connect to broker");
100 | connectToBroker();
101 | }
102 | // poll for new messages from the broker:
103 | mqttClient.poll();
104 |
105 | // read the pushbutton:
106 | int buttonState = digitalRead(buttonPin);
107 | // compare its state to the previous state:
108 | if (buttonState != lastButtonState) {
109 | // debounce delay:
110 | delay(5);
111 | // if the button's changed and it's pressed:
112 | if (buttonState == LOW) {
113 | // pick a random note in the scale:
114 | noteValue = scale[random(8)];
115 | // play it:
116 | sendMqttMessage(0x90, noteValue, 0x7F);
117 | } else {
118 | // turn the note off:
119 | sendMqttMessage(0x80, noteValue, 0);
120 | }
121 | // save the button state for comparison next time through:
122 | lastButtonState = buttonState;
123 | }
124 | }
125 |
126 | void onMqttMessage(int messageSize) {
127 | // we received a message, print out the topic and contents
128 | Serial.println("Received a message with topic ");
129 | Serial.print(mqttClient.messageTopic());
130 | Serial.print(", length ");
131 | Serial.print(messageSize);
132 | Serial.println(" bytes:");
133 |
134 | if (messageSize > 0) {
135 | // set up an array for the MIDI bytes:
136 | byte message[messageSize];
137 |
138 | // message byte counter:
139 | int i = 0;
140 | // read the message:
141 | while (mqttClient.available()) {
142 | // convert numeric string to an int:
143 | message[i] = mqttClient.read();
144 | Serial.print(message[i], HEX);
145 | Serial.print(" ");
146 | i++;
147 | }
148 | Serial.println();
149 | }
150 | }
151 |
152 | boolean connectToBroker() {
153 | // if the MQTT client is not connected:
154 | if (!mqttClient.connect(broker, port)) {
155 | // print out the error message:
156 | Serial.print("MOTT connection failed. Error no: ");
157 | Serial.println(mqttClient.connectError());
158 | // return that you're not connected:
159 | return false;
160 | }
161 |
162 | // set the message receive callback:
163 | mqttClient.onMessage(onMqttMessage);
164 | // subscribe to a topic:
165 | Serial.print("Subscribing to topic: ");
166 | Serial.println(topic);
167 | mqttClient.subscribe(topic);
168 |
169 | // once you're connected, you
170 | // return that you're connected:
171 | return true;
172 | }
173 |
174 | void sendMqttMessage(byte cmd, byte data1, byte data2) {
175 | mqttClient.beginMessage(topic);
176 | mqttClient.write(cmd);
177 | mqttClient.write(data1);
178 | mqttClient.write(data2);
179 | // send the message:
180 | mqttClient.endMessage();
181 | }
182 |
183 | void connectToNetwork() {
184 | // try to connect to the network:
185 | while (WiFi.status() != WL_CONNECTED) {
186 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
187 | //Connect to WPA / WPA2 network:
188 | WiFi.begin(SECRET_SSID, SECRET_PASS);
189 | delay(2000);
190 | }
191 |
192 | // print IP address once connected:
193 | Serial.print("Connected. My IP address: ");
194 | Serial.println(WiFi.localIP());
195 | }
196 |
--------------------------------------------------------------------------------
/arduino-clients/MqttClientMIDIPlayer/MqttClientMIDIPlayer.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client that plays MIDI
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and listens for messages on that topic. When it receives a three-byte message,
6 | it uses it to send out a MIDI note via MIDIUSB. It doesn't attempt to interpret
7 | the MIDI message, it just plays it
8 |
9 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
10 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
11 |
12 | Libraries used:
13 | * http://librarymanager/All#WiFiNINA or
14 | * http://librarymanager/All#WiFi101
15 | * http://librarymanager/All#ArduinoMqttClient
16 | * http://librarymanager/All#MIDIUSB
17 |
18 | the arduino_secrets.h file:
19 | #define SECRET_SSID "" // network name
20 | #define SECRET_PASS "" // network password
21 | #define SECRET_MQTT_USER "public" // broker username
22 | #define SECRET_MQTT_PASS "public" // broker password
23 |
24 | created 11 June 2020
25 | modified 5 Jan 2023
26 | by Tom Igoe
27 | */
28 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
29 | // #include // use this for MKR1000
30 | #include
31 | #include
32 | #include "arduino_secrets.h"
33 |
34 | // initialize WiFi connection:
35 | WiFiSSLClient wifi;
36 | MqttClient mqttClient(wifi);
37 |
38 | // details for MQTT client:
39 | char broker[] = "public.cloud.shiftr.io";
40 | int port = 8883;
41 | char topic[] = "midi";
42 | String clientID = "arduinoMidiClient-";
43 |
44 | void setup() {
45 | // initialize serial:
46 | Serial.begin(9600);
47 | // wait for serial monitor to open:
48 | if (!Serial) delay(3000);
49 | pinMode(LED_BUILTIN, OUTPUT);
50 | // connect to WiFi:
51 | connectToNetwork();
52 | // make the clientID unique by adding the last three digits of the MAC address:
53 | byte mac[6];
54 | WiFi.macAddress(mac);
55 | for (int i = 0; i < 3; i++) {
56 | clientID += String(mac[i], HEX);
57 | }
58 | // set the credentials for the MQTT client:
59 | mqttClient.setId(clientID);
60 | // if needed, login to the broker with a username and password:
61 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
62 | }
63 |
64 | void loop() {
65 | // if you disconnected from the network, reconnect:
66 | if (WiFi.status() != WL_CONNECTED) {
67 | connectToNetwork();
68 | // skip the rest of the loop until you are connected:
69 | return;
70 | }
71 |
72 | // if not connected to the broker, try to connect:
73 | if (!mqttClient.connected()) {
74 | Serial.println("attempting to connect to broker");
75 | connectToBroker();
76 | }
77 | // poll for new messages from the broker:
78 | mqttClient.poll();
79 | }
80 |
81 | void onMqttMessage(int messageSize) {
82 | // set up an array for the MIDI bytes:
83 | byte message[messageSize];
84 | Serial.print("Got a message on topic: ");
85 | Serial.println(mqttClient.messageTopic());
86 | // message byte counter:
87 | int i = 0;
88 | // read the message:
89 | while (mqttClient.available()) {
90 | // convert numeric string to an int:
91 | message[i] = mqttClient.read();
92 | Serial.print(message[i], HEX);
93 | Serial.print(" ");
94 | i++;
95 | }
96 | Serial.println();
97 | // play a note:
98 | midiCommand(message[0], message[1], message[2]);
99 | }
100 |
101 |
102 | boolean connectToBroker() {
103 | // if the MQTT client is not connected:
104 | if (!mqttClient.connect(broker, port)) {
105 | // print out the error message:
106 | Serial.print("MOTT connection failed. Error no: ");
107 | Serial.println(mqttClient.connectError());
108 | // return that you're not connected:
109 | return false;
110 | }
111 |
112 | // set the message receive callback:
113 | mqttClient.onMessage(onMqttMessage);
114 | // subscribe to a topic:
115 | Serial.print("Subscribing to topic: ");
116 | Serial.println(topic);
117 | mqttClient.subscribe(topic);
118 |
119 | // once you're connected, you
120 | // return that you're connected:
121 | return true;
122 | }
123 |
124 | // send a 3-byte midi message
125 | void midiCommand(byte cmd, byte data1, byte data2) {
126 | // First parameter is the event type (top 4 bits of the command byte).
127 | // Second parameter is command byte combined with the channel.
128 | // Third parameter is the first data byte
129 | // Fourth parameter second data byte
130 |
131 | midiEventPacket_t midiMsg = { cmd >> 4, cmd, data1, data2 };
132 | MidiUSB.sendMIDI(midiMsg);
133 | }
134 |
135 |
136 | void connectToNetwork() {
137 | // try to connect to the network:
138 | while (WiFi.status() != WL_CONNECTED) {
139 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
140 | //Connect to WPA / WPA2 network:
141 | WiFi.begin(SECRET_SSID, SECRET_PASS);
142 | delay(2000);
143 | }
144 |
145 | // print IP address once connected:
146 | Serial.print("Connected. My IP address: ");
147 | Serial.println(WiFi.localIP());
148 | }
149 |
--------------------------------------------------------------------------------
/arduino-clients/MqttClientNeoPixel/MqttClientNeoPixel.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT NeoPixel Client
3 |
4 | This sketch shows how to control NeoPixels with MQTT.
5 | It expects a comma-separated string of values for red, green, and blue
6 | in the incoming topic. When it gets that, it uses the values to
7 | change the color of the strip.
8 |
9 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
10 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
11 |
12 | The circuit:
13 | * NeoPixels attached to pin 5
14 |
15 | Libraries used:
16 | * http://librarymanager/All#WiFiNINA or
17 | * http://librarymanager/All#WiFi101
18 | * http://librarymanager/All#ArduinoMqttClient
19 | * http://librarymanager/All#Adafruit_NeoPixel
20 |
21 | the arduino_secrets.h file:
22 | #define SECRET_SSID "" // network name
23 | #define SECRET_PASS "" // network password
24 | #define SECRET_MQTT_USER "public" // broker username
25 | #define SECRET_MQTT_PASS "public" // broker password
26 |
27 | created 11 June 2020
28 | updated 25 Feb 2023
29 | by Tom Igoe
30 | */
31 |
32 |
33 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
34 | // #include // use this for MKR1000
35 | #include
36 | #include
37 | #include "arduino_secrets.h"
38 |
39 | // initialize WiFi connection as SSL:
40 | WiFiSSLClient wifi;
41 | MqttClient mqttClient(wifi);
42 |
43 | const int neoPixelPin = 5; // control pin
44 | const int pixelCount = 7; // number of pixels
45 |
46 | // set up NeoPixels:
47 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(pixelCount, neoPixelPin, NEO_GRBW + NEO_KHZ800);
48 |
49 | // details for MQTT client:
50 | char broker[] = "public.cloud.shiftr.io";
51 | int port = 8883;
52 | char topic[] = "color";
53 | String clientID = "neoPixelClient-";
54 |
55 | // intensity of LED:
56 | int intensity = 0;
57 |
58 | void setup() {
59 | // initialize serial:
60 | Serial.begin(9600);
61 | // wait for serial monitor to open:
62 | if (!Serial) delay(3000);
63 | // connect to WiFi:
64 | connectToNetwork();
65 | // make the clientID unique by adding the last three digits of the MAC address:
66 | byte mac[6];
67 | WiFi.macAddress(mac);
68 | for (int i = 0; i < 3; i++) {
69 | clientID += String(mac[i], HEX);
70 | }
71 | // set the credentials for the MQTT client:
72 | mqttClient.setId(clientID);
73 | // if needed, login to the broker with a username and password:
74 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
75 | // initialize the NeoPixels:
76 | strip.begin();
77 | }
78 |
79 | void loop() {
80 | //if you disconnected from the network, reconnect:
81 | if (WiFi.status() != WL_CONNECTED) {
82 | connectToNetwork();
83 | // skip the rest of the loop until you are connected:
84 | return;
85 | }
86 |
87 | // if not connected to the broker, try to connect:
88 | if (!mqttClient.connected()) {
89 | Serial.println("attempting to connect to broker");
90 | connectToBroker();
91 | }
92 | // poll for new messages from the broker:
93 | mqttClient.poll();
94 | }
95 |
96 | boolean connectToBroker() {
97 | // if the MQTT client is not connected:
98 | if (!mqttClient.connect(broker, port)) {
99 | // print out the error message:
100 | Serial.print("MOTT connection failed. Error no: ");
101 | Serial.println(mqttClient.connectError());
102 | // return that you're not connected:
103 | return false;
104 | }
105 |
106 | // set the message receive callback:
107 | mqttClient.onMessage(onMqttMessage);
108 | // subscribe to a topic and all subtopics:
109 | Serial.print("Subscribing to topic: ");
110 | Serial.println(topic);
111 | mqttClient.subscribe(topic);
112 |
113 | // once you're connected, you
114 | // return that you're connected:
115 | return true;
116 | }
117 |
118 | void onMqttMessage(int messageSize) {
119 | // initialize variables for red, green, blue:
120 | int r, g, b = 0;
121 | // we received a message, print out the topic and contents
122 | Serial.println("Received a message with topic ");
123 | Serial.println(mqttClient.messageTopic());
124 | Serial.print(" values: ");
125 | // read the incoming message as a comma-separated string of values:
126 | while (mqttClient.available()) {
127 | int r = mqttClient.parseInt();
128 | int g = mqttClient.parseInt();
129 | int b = mqttClient.parseInt();
130 | Serial.print(r);
131 | Serial.print(",");
132 | Serial.print(g);
133 | Serial.print(",");
134 | Serial.println(b);
135 | // fill the strip with color:
136 | strip.fill(r, g, b);
137 | // update the strip:
138 | strip.show();
139 | }
140 | }
141 |
142 | void connectToNetwork() {
143 | // try to connect to the network:
144 | while (WiFi.status() != WL_CONNECTED) {
145 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
146 | //Connect to WPA / WPA2 network:
147 | WiFi.begin(SECRET_SSID, SECRET_PASS);
148 | delay(2000);
149 | }
150 | // print IP address once connected:
151 | Serial.print("Connected. My IP address: ");
152 | Serial.println(WiFi.localIP());
153 | }
--------------------------------------------------------------------------------
/arduino-clients/MqttClientSubTopics/MqttClientSubTopics.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client Property Changer using subtopics
3 |
4 | This sketch shows how to use MQTT subtopics to get and set
5 | properties of a microcontroller's program.
6 | The microcontroller has two blinking LEDs and an analog sensor attached.
7 | You can change the behavior of the LEDs remotely by publishing
8 | to the subtopics `/brightness` and `/blinkInterval` and change
9 | the sensor update rate by publishing to `/sendInterval`.
10 |
11 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
12 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
13 |
14 | The circuit:
15 | * any analog input on pin A0;
16 | * LED on digital pin 2;
17 | * built-in LED on pin LED_BUILTIN
18 |
19 | Libraries used:
20 | * http://librarymanager/All#WiFiNINA or
21 | * http://librarymanager/All#WiFi101
22 | * http://librarymanager/All#ArduinoMqttClient
23 |
24 | the arduino_secrets.h file:
25 | #define SECRET_SSID "" // network name
26 | #define SECRET_PASS "" // network password
27 | #define SECRET_MQTT_USER "public" // broker username
28 | #define SECRET_MQTT_PASS "public" // broker password
29 |
30 | created 5 Jan 2023
31 | by Tom Igoe
32 | */
33 |
34 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
35 | // #include // use this for MKR1000
36 | #include
37 | #include "arduino_secrets.h"
38 |
39 | // initialize WiFi connection as SSL:
40 | WiFiSSLClient wifi;
41 | MqttClient mqttClient(wifi);
42 |
43 | // an LED to dim is on pin 2:
44 | const int ledPin = 2;
45 |
46 | // details for MQTT client:
47 | char broker[] = "public.cloud.shiftr.io";
48 | int port = 8883;
49 | String topic = "ocelots";
50 | String clientID = "arduinoMqttClient-";
51 |
52 | // last time the client sent a message, in ms:
53 | long lastTimeSent = 0;
54 | // message sending interval:
55 | int sendInterval = 10 * 1000;
56 | // built-in LED blink interval:
57 | int blinkInterval = 1000;
58 | int lastBlink = 0;
59 |
60 | // properties for the LED on pin 2:
61 | int brightness = 0;
62 | int lastBrightness = brightness;
63 | // property for built-in LED:
64 | int status = HIGH;
65 |
66 | void setup() {
67 | // initialize serial:
68 | Serial.begin(9600);
69 | // wait for serial monitor to open:
70 | if (!Serial) delay(3000);
71 |
72 | pinMode(LED_BUILTIN, OUTPUT);
73 | pinMode(ledPin, OUTPUT);
74 | // connect to WiFi:
75 | connectToNetwork();
76 |
77 | // make the clientID unique by adding the last three digits of the MAC address:
78 | byte mac[6];
79 | WiFi.macAddress(mac);
80 | for (int i = 0; i < 3; i++) {
81 | clientID += String(mac[i], HEX);
82 | }
83 | // set the credentials for the MQTT client:
84 | mqttClient.setId(clientID);
85 | // if needed, login to the broker with a username and password:
86 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
87 | }
88 |
89 | void loop() {
90 | //if you disconnected from the network, reconnect:
91 | if (WiFi.status() != WL_CONNECTED) {
92 | connectToNetwork();
93 | // skip the rest of the loop until you are connected:
94 | return;
95 | }
96 |
97 | // if not connected to the broker, try to connect:
98 | if (!mqttClient.connected()) {
99 | Serial.println("attempting to connect to broker");
100 | connectToBroker();
101 | }
102 | // poll for new messages from the broker:
103 | mqttClient.poll();
104 |
105 | // once every interval, read the sensor and publish.
106 | // also publish sendInterval, brightness and blinkInterval:
107 | if (millis() - lastTimeSent > sendInterval) {
108 | // get an analog reading:
109 | int sensorReading = analogRead(A0);
110 | // make a subtopic for it:
111 | String subTopic = topic + String("/sensor");
112 | mqttUpdate(subTopic, String(sensorReading));
113 | // make a subtopic for the other variables too:
114 | subTopic = topic + String("/sendInterval");
115 | mqttUpdate(subTopic, String(sendInterval));
116 | subTopic = topic + String("/brightness");
117 | mqttUpdate(subTopic, String(brightness));
118 | subTopic = topic + String("/blinkInterval");
119 | mqttUpdate(subTopic, String(blinkInterval));
120 | lastTimeSent = millis();
121 | }
122 | // if brightness has changed, change the dimming LED:
123 | if (brightness != lastBrightness) {
124 | analogWrite(ledPin, brightness);
125 | lastBrightness = brightness;
126 | }
127 | // if blinkInterval has passed, change the state of the blinking LED:
128 | if (millis() - lastTimeSent > blinkInterval) {
129 | digitalWrite(LED_BUILTIN, status);
130 | status = !status;
131 | lastBlink = millis();
132 | }
133 | }
134 | // publish a message to a topic:
135 | void mqttUpdate(String thisTopic, String message) {
136 | if (mqttClient.connected()) {
137 | // start a new message on the topic:
138 | mqttClient.beginMessage(thisTopic);
139 | // print the body of the message:
140 | mqttClient.print(message);
141 | // send the message:
142 | mqttClient.endMessage();
143 | // send a serial notification:
144 | Serial.print("published to: ");
145 | Serial.print(thisTopic);
146 | Serial.print(", message: ");
147 | Serial.println(message);
148 | // timestamp this message:
149 | lastTimeSent = millis();
150 | }
151 | }
152 |
153 | boolean connectToBroker() {
154 | // if the MQTT client is not connected:
155 | if (!mqttClient.connect(broker, port)) {
156 | // print out the error message:
157 | Serial.print("MOTT connection failed. Error no: ");
158 | Serial.println(mqttClient.connectError());
159 | // return that you're not connected:
160 | return false;
161 | }
162 |
163 | // set the message receive callback:
164 | mqttClient.onMessage(onMqttMessage);
165 | // subscribe to a topic and all subtopics:
166 | Serial.print("Subscribing to topic: ");
167 | Serial.println(topic + "/#");
168 | mqttClient.subscribe(topic + "/#");
169 |
170 | // once you're connected, you
171 | // return that you're connected:
172 | return true;
173 | }
174 |
175 | void onMqttMessage(int messageSize) {
176 | // we received a message, print out the topic and contents
177 | Serial.println("Received a message with topic ");
178 | Serial.print(mqttClient.messageTopic());
179 | Serial.print(", length ");
180 | Serial.print(messageSize);
181 | Serial.println(" bytes:");
182 | // get the subtopic. Assumes the messageTopic is "topic/" then something:
183 | String subTopic = mqttClient.messageTopic().substring(topic.length() + 1);
184 | // an empty string to read the result
185 | String incoming = "";
186 | // read the contensts into the string:
187 | while (mqttClient.available()) {
188 | incoming += (char)mqttClient.read();
189 | }
190 | Serial.println(incoming);
191 |
192 | // change the appropriate variable depending on the subTopic:
193 | if (subTopic == "sendInterval") {
194 | sendInterval = incoming.toInt();
195 | }
196 | if (subTopic == "brightness") {
197 | brightness = incoming.toInt();
198 | }
199 | if (subTopic == "blinkInterval") {
200 | blinkInterval = incoming.toInt();
201 | }
202 | }
203 |
204 | void connectToNetwork() {
205 | // try to connect to the network:
206 | while (WiFi.status() != WL_CONNECTED) {
207 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
208 | //Connect to WPA / WPA2 network:
209 | WiFi.begin(SECRET_SSID, SECRET_PASS);
210 | delay(2000);
211 | }
212 | // print IP address once connected:
213 | Serial.print("Connected. My IP address: ");
214 | Serial.println(WiFi.localIP());
215 | }
216 |
--------------------------------------------------------------------------------
/arduino-clients/MqttClient_SensorCombinedAQISender/MqttClient_SensorCombinedAQISender.ino:
--------------------------------------------------------------------------------
1 | /*
2 | This sketch demonstrates an MQTT client that connects to a broker,
3 | and publishes messages to it from an ENS160 AQI sensor and
4 | an SHTC3 Temperature and rH sensor. Uses the temp/humidity
5 | sensor to provide compensation for the AQI sensor, Shows how to
6 | send JSON strings with just the String object.
7 |
8 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
9 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
10 |
11 | Libraries used:
12 | * http://librarymanager/All#WiFiNINA or
13 | * http://librarymanager/All#WiFi101
14 | * http://librarymanager/All#ArduinoMqttClient
15 | * http://librarymanager/All#SparkFun_ENS160
16 | * http://librarymanager/All#SparkFun_SHTC3
17 |
18 | the circuit:
19 | - SHTC3 sensor and ENS160 sensor attached to SDA and SCL of the Arduino
20 |
21 | the arduino_secrets.h file:
22 | #define SECRET_SSID "" // network name
23 | #define SECRET_PASS "" // network password
24 | #define SECRET_MQTT_USER "public" // broker username
25 | #define SECRET_MQTT_PASS "public" // broker password
26 |
27 | created 11 June 2020
28 | updated 25 Feb 2023
29 | by Tom Igoe
30 | */
31 |
32 | #include
33 | #include
34 | #include
35 | #include "SparkFun_ENS160.h"
36 | #include "SparkFun_SHTC3.h"
37 | #include "arduino_secrets.h"
38 |
39 | // initialize WiFi connection as SSL:
40 | WiFiSSLClient wifi;
41 | MqttClient mqttClient(wifi);
42 |
43 | // details for MQTT client:
44 | char broker[] = "public.cloud.shiftr.io";
45 | int port = 8883;
46 | char topic[] = "AQISensor";
47 | String clientID = "CombinedSensorClient-";
48 |
49 | // last time the client sent a message, in ms:
50 | long lastTimeSent = 0;
51 | // message sending interval:
52 | int interval = 10 * 1000;
53 |
54 | // instance of the ENS160 sensor library:
55 | SparkFun_ENS160 AQISensor;
56 | SHTC3 temp_rHSensor;
57 |
58 | void setup() {
59 | // initialize serial:
60 | Serial.begin(9600);
61 | // wait for serial monitor to open:
62 | if (!Serial) delay(3000);
63 |
64 | // initialize WiFi, if not connected:
65 | while (WiFi.status() != WL_CONNECTED) {
66 | Serial.print("Connecting to ");
67 | Serial.println(SECRET_SSID);
68 | WiFi.begin(SECRET_SSID, SECRET_PASS);
69 | delay(2000);
70 | }
71 | // print IP address once connected:
72 | Serial.print("Connected. My IP address: ");
73 | Serial.println(WiFi.localIP());
74 | // make the clientID unique by adding the last three digits of the MAC address:
75 | byte mac[6];
76 | WiFi.macAddress(mac);
77 | for (int i = 0; i < 3; i++) {
78 | clientID += String(mac[i], HEX);
79 | }
80 | // set the credentials for the MQTT client:
81 | mqttClient.setId(clientID);
82 | // if needed, login to the broker with a username and password:
83 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
84 |
85 | // attempt to start the sensor:
86 | Wire.begin();
87 | if (!AQISensor.begin(0x53)) {
88 | Serial.println("Sensor is not responding. Check wiring.");
89 | // stop the program here if the sensor didn't respond:
90 | while (true)
91 | ;
92 | }
93 |
94 | if (temp_rHSensor.begin() != SHTC3_Status_Nominal) {
95 | Serial.println("Temp & Humidity Sensor is not responding. Check wiring.");
96 | while (true)
97 | ;
98 | }
99 |
100 | if (!AQISensor.setOperatingMode(SFE_ENS160_RESET)) {
101 | while (true)
102 | ;
103 | }
104 | // Device needs to be set to idle to apply any settings.
105 | AQISensor.setOperatingMode(SFE_ENS160_IDLE);
106 | // get an update from the temp/rH sensor:
107 | temp_rHSensor.update();
108 | // wait until sensor returns a value:
109 | while (temp_rHSensor.lastStatus != SHTC3_Status_Nominal) {
110 | Serial.println("Humidity and Temperature Sensor is not ready.");
111 | }
112 | // read temp and rH:
113 | float rh = temp_rHSensor.toPercent();
114 | float tempC = temp_rHSensor.toDegC();
115 |
116 | // Give values to AQI sensor:
117 | AQISensor.setTempCompensationCelsius(tempC);
118 | AQISensor.setRHCompensationFloat(rh);
119 | // delay to make sure updates are written:
120 | delay(500);
121 | // Set AQI to standard operation:
122 | AQISensor.setOperatingMode(SFE_ENS160_STANDARD);
123 | }
124 |
125 | void loop() {
126 | // if not connected to the broker, try to connect:
127 | if (!mqttClient.connected()) {
128 | Serial.println("attempting to connect to broker");
129 | connectToBroker();
130 | }
131 |
132 | // once every interval, send a message:
133 | if (millis() - lastTimeSent > interval) {
134 | // if the AQI sensor is ready:
135 | // ask for a reading:
136 | temp_rHSensor.update();
137 | // read the results:
138 | float tempC = AQISensor.getTempCelsius();
139 | float rh = AQISensor.getRH();
140 |
141 | // the sensor can have four possible states:
142 | // 0 - Operating ok: Standard Opepration
143 | // 1 - Warm-up: occurs for 3 minutes after power-on.
144 | // 2 - Initial Start-up: Occurs for the first hour of operation.
145 | // and only once in sensor's lifetime.
146 | // 3 - No Valid Output
147 | int ensStatus = AQISensor.getFlags();
148 | // if the sensor's ready to read, read it:
149 | if (AQISensor.checkDataStatus()) {
150 | int aqi = AQISensor.getAQI();
151 | int tvoc = AQISensor.getTVOC();
152 | int eCO2 = AQISensor.getECO2();
153 |
154 | // put them into a JSON String:
155 | String payload = "{\"sensor\": \"SGP30 and ENS160\",";
156 | payload += "\"aqi\": AQI, \"tvoc\": TVOC, \"eCO2\": ECO2,";
157 | payload += "\"status\": STATUS, \"temp\": TEMP, \"humidity\": RH}";
158 | // replace the value substrings with actual values:
159 | payload.replace("AQI", String(aqi));
160 | payload.replace("TVOC", String(tvoc));
161 | payload.replace("ECO2", String(eCO2));
162 | payload.replace("STATUS", String(ensStatus));
163 | payload.replace("TEMP", String(tempC));
164 | payload.replace("RH", String(rh));
165 |
166 | // start a new message on the topic:
167 | mqttClient.beginMessage(topic);
168 | // print the payload of the message:
169 | mqttClient.println(payload);
170 | // send the message:
171 | mqttClient.endMessage();
172 | // send a serial notification:
173 | Serial.print("published: ");
174 | Serial.println(payload);
175 | // timestamp this message:
176 | lastTimeSent = millis();
177 | }
178 | }
179 | }
180 |
181 | boolean connectToBroker() {
182 | // if the MQTT client is not connected:
183 | if (!mqttClient.connect(broker, port)) {
184 | // print out the error message:
185 | Serial.print("MOTT connection failed. Error no: ");
186 | Serial.println(mqttClient.connectError());
187 | // return that you're not connected:
188 | return false;
189 | }
190 | // once you're connected, you
191 | // return that you're connected:
192 | return true;
193 | }
--------------------------------------------------------------------------------
/arduino-clients/MqttClient_SensorENS160Sender/MqttClient_SensorENS160Sender.ino:
--------------------------------------------------------------------------------
1 | /*
2 | This sketch demonstrates an MQTT client that connects to a broker,
3 | and publishes messages to it from an ENS160 AQI sensor. Shows how to
4 | send JSON strings with just the String object.
5 |
6 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
7 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
8 |
9 | Libraries used:
10 | * http://librarymanager/All#WiFiNINA or
11 | * http://librarymanager/All#WiFi101
12 | * http://librarymanager/All#ArduinoMqttClient
13 | * http://librarymanager/All#SparkFun_ENS160
14 |
15 | the circuit:
16 | - ENS160 sensor attached to SDA and SCL of the Arduino
17 |
18 | the arduino_secrets.h file:
19 | #define SECRET_SSID "" // network name
20 | #define SECRET_PASS "" // network password
21 | #define SECRET_MQTT_USER "public" // broker username
22 | #define SECRET_MQTT_PASS "public" // broker password
23 |
24 | created 11 June 2020
25 | updated 25 Feb 2023
26 | by Tom Igoe
27 | */
28 |
29 | #include
30 | #include
31 | #include
32 | #include "SparkFun_ENS160.h"
33 | #include "arduino_secrets.h"
34 |
35 | // initialize WiFi connection as SSL:
36 | WiFiSSLClient wifi;
37 | MqttClient mqttClient(wifi);
38 |
39 | // details for MQTT client:
40 | char broker[] = "public.cloud.shiftr.io";
41 | int port = 8883;
42 | char topic[] = "AQISensor";
43 | String clientID = "AQISensorClient-";
44 |
45 | // last time the client sent a message, in ms:
46 | long lastTimeSent = 0;
47 | // message sending interval:
48 | int interval = 10 * 1000;
49 |
50 | // instance of the ENS160 sensor library:
51 | SparkFun_ENS160 AQISensor;
52 |
53 | void setup() {
54 | // initialize serial:
55 | Serial.begin(9600);
56 | // wait for serial monitor to open:
57 | if (!Serial) delay(3000);
58 |
59 | // initialize WiFi, if not connected:
60 | while (WiFi.status() != WL_CONNECTED) {
61 | Serial.print("Connecting to ");
62 | Serial.println(SECRET_SSID);
63 | WiFi.begin(SECRET_SSID, SECRET_PASS);
64 | delay(2000);
65 | }
66 | // print IP address once connected:
67 | Serial.print("Connected. My IP address: ");
68 | Serial.println(WiFi.localIP());
69 | // make the clientID unique by adding the last three digits of the MAC address:
70 | byte mac[6];
71 | WiFi.macAddress(mac);
72 | for (int i = 0; i < 3; i++) {
73 | clientID += String(mac[i], HEX);
74 | }
75 | // set the credentials for the MQTT client:
76 | mqttClient.setId(clientID);
77 | // if needed, login to the broker with a username and password:
78 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
79 |
80 | // attempt to start the sensor:
81 | Wire.begin();
82 | if (!AQISensor.begin(0x53)) {
83 | Serial.println("Sensor is not responding. Check wiring.");
84 | // stop the program here if the sensor didn't respond:
85 | while (true)
86 | ;
87 | }
88 |
89 | // Reset the indoor air quality sensor's settings:
90 | if (AQISensor.setOperatingMode(SFE_ENS160_RESET)) {
91 | Serial.println("Ready.");
92 | }
93 | delay(100);
94 | // Set to standard operation:
95 | AQISensor.setOperatingMode(SFE_ENS160_STANDARD);
96 | }
97 |
98 | void loop() {
99 | // if not connected to the broker, try to connect:
100 | if (!mqttClient.connected()) {
101 | Serial.println("attempting to connect to broker");
102 | connectToBroker();
103 | }
104 |
105 | // once every interval, send a message:
106 | if (millis() - lastTimeSent > interval) {
107 |
108 | // the sensor can have four possible states:
109 | // 0 - Operating ok: Standard Opepration
110 | // 1 - Warm-up: occurs for 3 minutes after power-on.
111 | // 2 - Initial Start-up: Occurs for the first hour of operation.
112 | // and only once in sensor's lifetime.
113 | // 3 - No Valid Output
114 | int ensStatus = AQISensor.getFlags();
115 | // if the sensor's ready to read, read it:
116 | if (AQISensor.checkDataStatus()) {
117 | int aqi = AQISensor.getAQI();
118 | int tvoc = AQISensor.getTVOC();
119 | int eCO2 = AQISensor.getECO2();
120 |
121 | // put them into a JSON String:
122 | String payload = "{\"sensor\": \"ENS160\",";
123 | payload += "\"aqi\": AQI, \"tvoc\": TVOC, \"eCO2\": ECO2, \"status\": STATUS}";
124 | // replace the value substrings with actual values:
125 | payload.replace("AQI", String(aqi));
126 | payload.replace("TVOC", String(tvoc));
127 | payload.replace("ECO2", String(eCO2));
128 | payload.replace("STATUS", String(ensStatus));
129 |
130 | // start a new message on the topic:
131 | mqttClient.beginMessage(topic);
132 | // print the payload of the message:
133 | mqttClient.println(payload);
134 | // send the message:
135 | mqttClient.endMessage();
136 | // timestamp this message:
137 | lastTimeSent = millis();
138 | }
139 | }
140 | }
141 |
142 | boolean connectToBroker() {
143 | // if the MQTT client is not connected:
144 | if (!mqttClient.connect(broker, port)) {
145 | // print out the error message:
146 | Serial.print("MOTT connection failed. Error no: ");
147 | Serial.println(mqttClient.connectError());
148 | // return that you're not connected:
149 | return false;
150 | }
151 | // once you're connected, you
152 | // return that you're connected:
153 | return true;
154 | }
--------------------------------------------------------------------------------
/arduino-clients/MqttClient_SensorTCS34725Sender/MqttClient_SensorTCS34725Sender.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client Light sensor sender/receiver
3 |
4 | This sketch demonstrates an MQTT client that connects to a broker, subscribes to a topic,
5 | and both listens for messages on that topic and sends messages to it.
6 |
7 | Uses a TCS34725 light sensor to read lux and color temperature
8 |
9 | This sketch uses https://public.cloud.shiftr.io as the MQTT broker, but others will work as well.
10 | See https://tigoe.github.io/mqtt-examples/#broker-client-settings for connection details.
11 |
12 | Libraries used:
13 | * http://librarymanager/All#WiFiNINA or
14 | * http://librarymanager/All#WiFi101
15 | * http://librarymanager/All#ArduinoMqttClient
16 | * http://librarymanager/All#Adafruit_TCS34725 (for the sensor)
17 |
18 | the arduino_secrets.h file:
19 | #define SECRET_SSID "" // network name
20 | #define SECRET_PASS "" // network password
21 | #define SECRET_MQTT_USER "public" // broker username
22 | #define SECRET_MQTT_PASS "public" // broker password
23 |
24 | created 11 June 2020
25 | updated 28 Feb 2023
26 | by Tom Igoe
27 | */
28 |
29 | #include // use this for Nano 33 IoT, MKR1010, Uno WiFi
30 | // #include // use this for MKR1000
31 | #include
32 | #include
33 | #include
34 | #include "arduino_secrets.h"
35 |
36 | // initialize WiFi connection as SSL:
37 | WiFiSSLClient wifi;
38 | MqttClient mqttClient(wifi);
39 |
40 | // details for MQTT client:
41 | char broker[] = "public.cloud.shiftr.io";
42 | int port = 8883;
43 | char topic[] = "conndev/tigoe";
44 | String clientID = "light-client-";
45 |
46 | // last time the client sent a message, in ms:
47 | long lastTimeSent = 0;
48 | // message sending interval:
49 | int interval = 60 * 1000;
50 |
51 | // initialize the light sensor:
52 | Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_600MS, TCS34725_GAIN_1X);
53 | // string for the MAC address:
54 | String macAddr;
55 |
56 | void setup() {
57 | // initialize serial:
58 | Serial.begin(9600);
59 | // wait for serial monitor to open:
60 | if (!Serial) delay(3000);
61 |
62 | // get MAC address:
63 | byte mac[6];
64 | WiFi.macAddress(mac);
65 | // put it in a string:
66 | for (int i = 5; i >= 0; i--) {
67 | if (mac[i] < 16) macAddr += "0";
68 | macAddr += String(mac[i], HEX);
69 | }
70 |
71 | // set the credentials for the MQTT client:
72 | mqttClient.setId(clientID);
73 | // add mac address to make the clientID unique:
74 | clientID += macAddr;
75 | // if needed, login to the broker with a username and password:
76 | mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
77 | }
78 |
79 | void loop() {
80 | //if you disconnected from the network, reconnect:
81 | if (WiFi.status() != WL_CONNECTED) {
82 | connectToNetwork();
83 | // skip the rest of the loop until you are connected:
84 | return;
85 | }
86 |
87 | // if not connected to the broker, try to connect:
88 | if (!mqttClient.connected()) {
89 | Serial.println("attempting to connect to broker");
90 | connectToBroker();
91 | }
92 | // poll for new messages from the broker:
93 | mqttClient.poll();
94 |
95 | // once every interval, send a message:
96 | if (millis() - lastTimeSent > interval) {
97 | // read the sensor
98 | // get lux and color temperature from sensor:
99 | uint16_t r, g, b, c, colorTemp, lux;
100 | tcs.getRawData(&r, &g, &b, &c);
101 | colorTemp = tcs.calculateColorTemperature_dn40(r, g, b, c);
102 | lux = tcs.calculateLux(r, g, b);
103 |
104 | if (mqttClient.connected()) {
105 | // start a new message on the topic:
106 | mqttClient.beginMessage(topic + String("/lux"));
107 | // print the body of the message:
108 | mqttClient.print(lux);
109 | // send the message:
110 | mqttClient.endMessage();
111 | // same pattern for other subtopics:
112 | mqttClient.beginMessage(topic + String("/ct"));
113 | mqttClient.print(colorTemp);
114 | mqttClient.endMessage();
115 | // include MAC address as an ID for this device:
116 | mqttClient.beginMessage(topic + String("/id"));
117 | mqttClient.print(macAddr);
118 | mqttClient.endMessage();
119 | // send a serial notification:
120 | Serial.print("published a set of readings: \nlux: ");
121 | Serial.print(lux);
122 | Serial.print(", ct: ");
123 | Serial.print(colorTemp);
124 | Serial.print(", id: ");
125 | Serial.println(macAddr);
126 | // timestamp this message:
127 | lastTimeSent = millis();
128 | }
129 | }
130 | }
131 |
132 | boolean connectToBroker() {
133 | // if the MQTT client is not connected:
134 | if (!mqttClient.connect(broker, port)) {
135 | // print out the error message:
136 | Serial.print("MOTT connection failed. Error no: ");
137 | Serial.println(mqttClient.connectError());
138 | // return that you're not connected:
139 | return false;
140 | }
141 |
142 | // set the message receive callback:
143 | mqttClient.onMessage(onMqttMessage);
144 | // subscribe to a topic:
145 | Serial.print("Subscribing to topic: ");
146 | Serial.println(topic);
147 | mqttClient.subscribe(topic);
148 |
149 | // once you're connected, you
150 | // return that you're connected:
151 | return true;
152 | }
153 |
154 | void onMqttMessage(int messageSize) {
155 | // we received a message, print out the topic and contents
156 | Serial.println("Received a message with topic ");
157 | Serial.print(mqttClient.messageTopic());
158 | Serial.print(", length ");
159 | Serial.print(messageSize);
160 | Serial.println(" bytes:");
161 | String incoming = "";
162 | // use the Stream interface to print the contents
163 | while (mqttClient.available()) {
164 | incoming += (char)mqttClient.read();
165 | }
166 |
167 | // print the incoming message:
168 | Serial.println(incoming);
169 | }
170 |
171 | void connectToNetwork() {
172 | // try to connect to the network:
173 | while (WiFi.status() != WL_CONNECTED) {
174 | Serial.println("Attempting to connect to: " + String(SECRET_SSID));
175 | //Connect to WPA / WPA2 network:
176 | WiFi.begin(SECRET_SSID, SECRET_PASS);
177 | delay(2000);
178 | }
179 | // print IP address once connected:
180 | Serial.print("Connected. My IP address: ");
181 | Serial.println(WiFi.localIP());
182 | }
183 |
--------------------------------------------------------------------------------
/arduino-clients/readme.md:
--------------------------------------------------------------------------------
1 | # Arduino MQTT Clients
2 | The [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient) library makes it easy to send and receive MQTT messages using WiFi-enabled Arduino models such as the Nano 33 IoT, MKR1010, MKR1000, or other third-party devices with compatible WiFi libraries. This repository contains examples using this library. All of these will work with the basic MQTT client examples in the [JavaScript Clients]({{site.baseurl}}/#javascript-clients) section of the repository, if you match up the public brokers they are all using.
3 |
4 | ## Installing the library and Board Definitions
5 |
6 | If you've never used one of the WiFi-capable Arduino boards, you'll need to install the board definition. When you plug the board in, the Arduino IDE should pop up a message asking if you want to install the board definition. If not, click the Tools Menu --> Boards... --> Board Manager, and search for the board you're using. When you find it, click Install. The Nano 33 IoT, the MKR 1010 and the Uno WiFi all use the WiFiNINA library, and the MKR1000 uses the WiFi101 library. These two libraries have identical APIs.
7 |
8 | To install the [ArduinoMqttClient](https://www.arduino.cc/reference/en/libraries/arduinomqttclient/) library, click the Sketch Menu --> Include Library --> Manage Libraries, and search for ArduinoMqttClient. When you find it, click Install. Then do the same for the [WiFiNINA](https://www.arduino.cc/reference/en/libraries/wifinina/) library (if you're using a Nano 33 IoT or MKR 1010) or the [WiFi101](https://www.arduino.cc/reference/en/libraries/wifi101/) library (if you're using a MKR1000).
9 |
10 |
11 | All of the Arduino examples in this repository require an extra file to be included to the sketch. Use command-shift-N on MacOS or or control-shift-N on Windows, then name the file `arduino_secrets.h` The following credentials should be included in that file:
12 |
13 | ````
14 | #define SECRET_SSID "" // add your network SSID here
15 | #define SECRET_PASS "" // add your netork password here
16 | #define SECRET_MQTT_USER "public" // broker username for shiftr.io
17 | #define SECRET_MQTT_PASS "public" // broker password for shiftr.io
18 | ````
19 |
20 | Note: this assumes you're on a network with WPA2 encryption, which is what most people are using at home these days. If you're not, check the [WiFiNINA library documentation](https://www.arduino.cc/reference/en/libraries/wifinina/) for how to configure your sketches for other network types.
21 |
22 | ## ArduinoMqttClient
23 |
24 | [See the source code]({{site.codeurl}}/arduino-clients/ArduinoMqttClient/ArduinoMqttClient.ino)
25 |
26 | This is a basic client example for the ArduinoMqttClient library. The global variables define the broker and credentials. In the setup, the Arduino connects to WiFi and sets the MQTT client ID and other pre-connect characteristics, including the `onMessage` handler. In the loop, it continually attempts to connect to WiFi if it's not connected using the custom `connectToNetwork()` function; attempts to connect to the broker if not connected using the custom `connectToBroker()` function; then polls for any incoming MQTT messages using the `onMqttMessage()` handler. Then, once every interval, it reads a sensor and publishes the value as an MQTT message on the topic.
27 |
28 | The other Arduino examples in this repository follow more or less the same structure.
29 |
30 | ## ArduinoMqttClientWithWill
31 |
32 | This client shows how to use the keepAliveInterval, the connectionTimeout, and the last will and testament features of MQTT. When a will topic is set, the MQTT client can send it to the broker, but the broker won't publish it unless the client doesn't publish anything before its keepAliveInterval expires. If that happens, the broker assumes that the client has gone offline, and publishes the will topic.
33 |
34 | This example also uses the [RTCZero library](https://www.arduino.cc/reference/en/libraries/rtczero/) which implements the SAMD processor's real-time clock. It will wokr on the Nano 33 IoT and the MKR line of processors. It gets the time from the network every time it connects to WiFi, and publishes the time as the will topic, so that if it goes offline, the broker publishes the last known time that it was online as an [ISO8601](https://www.iso.org/iso-8601-date-and-time-format.html) string.
35 |
36 | ## Sensor Clients
37 |
38 | There are a couple sensor clients in this repository, to show how to read and publish sensors of differing values.
39 |
40 | ### MqttClient_SensorTCS34725Sender
41 |
42 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClient_SensorTCS34725Sender/MqttClient_SensorTCS34725Sender.ino)
43 |
44 | This example reads lux and color temperature levels from an AMS [TCS34725 light and color sensor](https://ams.com/en/tcs34725) using Adafruit's Adafruit_TCS34725 library. It also reads the MAC address of the WIFi radio and uses it as a unique ID to send in the MQTT message. It follows the same structure as the basic example described above. This example also shows how to send JSON strings with just the String object.
45 |
46 | ### MqttClient_SensorENS160Sender
47 |
48 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClient_SensorENS160Sender/MqttClient_SensorENS160Sender.ino)
49 |
50 | This example reads a [Sciosense ENS160 AQI sensor](https://www.sciosense.com/products/environmental-sensors/digital-multi-gas-sensor/), which calculates CO2-equivalent (eCO2), Total Volatile Organic Compounds (TVOC) and, air quality index (AQI). Breakout boards from both Sparkfun and Adafruit were used in the testing and both work well. The example uses Sparkfun's SparkFun_ENS160 library. This example also shows how to send JSON strings with just the String object.
51 |
52 | ### MqttClient_SensorCombinedAQISender
53 |
54 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClient_SensorCombinedAQISender/MqttClient_SensorCombinedAQISender.ino)
55 |
56 | This example reads temperature and humidity levels from an [Sensiron SHTC3 Temperature and Relative Humidity (rH) sensor](https://sensirion.com/products/catalog/SHTC3/) and uses those values to provide temp. and rH compensation for a [Sciosense ENS160 AQI sensor](https://www.sciosense.com/products/environmental-sensors/digital-multi-gas-sensor/), as seen in the previous example. It uses Sparkfun's SparkFun_ENS160 and SparkFun_SHTC3 libraries. This example also shows how to send JSON strings with just the String object.
57 |
58 | ## MqttClientSubTopics
59 |
60 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClientSubTopics/MqttClientSubTopics.ino)
61 |
62 | This example shows how to use MQTT to get and set the properties of a microcontroller's program. The microcontroller has two blinking LEDs and an analog sensor attached. You can change the behavior of the LEDs remotely by publishing to the subtopics `/brightness` and `/blinkInterval` and change the sensor update rate by publishing to `/sendInterval`.
63 |
64 | ## MqttClientNeoPixel
65 |
66 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClientNeoPixel/MqttClientNeoPixel.ino)
67 |
68 | This example shows how to use MQTT subtopics to set the color of a strip of WorldSemi [WS2812 addressable LEDs (NeoPixels)](https://tigoe.github.io/LightProjects/addressable-leds). The microcontroller subscribes to a topic called `color` and looks for a comma-separated string of values, r, g, and b. When it gets these, it uses them to update the NeoPixel's colors.
69 |
70 | ## MqttClientHueControl
71 |
72 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClientHueControl/MqttClientHueControl.ino)
73 |
74 | This example shows how to use MQTT to set the brightness of a Philips Hue light through a Hue hub. It does so by making HTTP requests to the Hue hub. For more on controlling the Philips Hue, see [this repository](https://tigoe.github.io/hue-control/). It can work with the Eclipse PAHO and p5.js example called [EclipsePahoHueLightControl]({{site.codeurl}}/browser-clients/eclipse-pahojs/eclipse-pahojs/EclipsePahoHueLightControl)
75 |
76 |
77 | ## MIDI examples
78 |
79 | These MIDI examples will work well with the [WebMIDI browser clients]({{site.baseurl}}/browser-clients/eclipse-pahojs/#web-midi-clients).
80 |
81 | ### MqttClientMIDIController
82 |
83 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClientMIDIController/MqttClientMIDIController.ino)
84 |
85 | This sketch is an MQTT client that connects to a broker, subscribes to a topic, and sends messages on that topic. The messages are three-byte arrays that can be read as MIDI noteon and noteoff messages.
86 |
87 | ### MqttClientMIDIController
88 |
89 | [See the source code]({{site.codeurl}}/arduino-clients/MqttClientMIDIPlayer/MqttClientMIDIPlayer.ino)
90 |
91 | This sketch is an MQTT client that connects to a broker, subscribes to a topic, and listens for messages on that topic. When it receives a three-byte message, it uses it to send out a MIDI note via MIDIUSB. It doesn't attempt to interpret the MIDI message, it just sends it.
92 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoClientSimple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | public
6 |
7 |
8 |
9 |
10 |
Eclipse Paho JS basic example
11 |
12 | Click here for the source code
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoClientSimple/script.js:
--------------------------------------------------------------------------------
1 | /*
2 | Bare minimum client example for Eclipse PAHO JS library
3 |
4 | On document load, this script gets two divs from the HTML
5 | for local and remote messages. Then it attempts
6 | to connect to the broker. Once every two seconds,
7 | it sends the local time if it's connected.
8 | The publish button allows you to turn on and off publishing status.
9 |
10 | created 31 Dec 2022
11 | by Tom Igoe
12 | */
13 |
14 | // All these brokers work with this code.
15 | // Uncomment the one you want to use.
16 |
17 | ////// emqx. Works in both basic WS and SSL WS:
18 | // const broker = 'broker.emqx.io'
19 | // const port = 8083; // no SSL
20 | // const broker = 'broker.emqx.io'
21 | // const port = 8084; // SSL
22 |
23 | //////// shiftr.io desktop client.
24 | // Fill in your desktop URL for localhost:
25 | // const broker = 'localhost';
26 | // const port = 1884; // no SSL
27 |
28 | //////// shiftr.io, requires username and password
29 | // (see options variable below):
30 | const broker = 'public.cloud.shiftr.io';
31 | const port = 443;
32 |
33 | //////// test.mosquitto.org, uses no username and password:
34 | // const broker = 'test.mosquitto.org';
35 | // const port = 8081;
36 |
37 | // MQTT client:
38 | let client;
39 | // client credentials:
40 | let clientID = 'EclipsePahoClient';
41 |
42 | let options = {
43 | // Clean session
44 | cleanSession: true,
45 | // connect timeout in seconds:
46 | timeout: 10,
47 | // callback function for when you connect:
48 | onSuccess: onConnect,
49 | // username & password:
50 | userName: 'public',
51 | password: 'public',
52 | // use SSL
53 | useSSL: true
54 | };
55 |
56 | // topic to subscribe to when you connect:
57 | let topic = 'aardvarks';
58 | // divs to show messages:
59 | let localDiv, remoteDiv;
60 | // whether the client should be publishing or not:
61 | let publishing = true;
62 |
63 | function setup() {
64 | // put the divs in variables for ease of use:
65 | localDiv = document.getElementById('local');
66 | remoteDiv = document.getElementById('remote');
67 |
68 | // set text of localDiv:
69 | localDiv.innerHTML = 'trying to connect';
70 | // Create an MQTT client:
71 | client = new Paho.MQTT.Client(broker, port, clientID);
72 | // set callback handlers for the client:
73 | client.onConnectionLost = onDisconnect;
74 | client.onMessageArrived = onMessage;
75 | // connect to the MQTT broker:
76 | client.connect(options);
77 | }
78 |
79 | function loop() {
80 | if (client.isConnected() && publishing) {
81 | // make a message with a random number from 0-255
82 | let payload = Math.floor(Math.random() * 255).toString();
83 | // publish to broker:
84 | let message = new Paho.MQTT.Message(payload);
85 | // // choose the destination topic:
86 | message.destinationName = topic;
87 | // send it:
88 | client.send(message);
89 | // update localDiv text:
90 | localDiv.innerHTML = 'published ' + message.payloadString + ' to broker.'
91 | }
92 | }
93 |
94 | // changes the status of the publishing variable
95 | // on a click of the publishStatus button:
96 | function changeSendStatus(target) {
97 | // change the publishing status:
98 | publishing = !publishing;
99 | // set the html of the button accordingly:
100 | if (publishing) {
101 | target.innerHTML = 'stop publishing';
102 | } else {
103 | target.innerHTML = 'start publishing';
104 | }
105 | }
106 |
107 | // handler for mqtt connect event:
108 | function onConnect() {
109 | // update localDiv text:
110 | localDiv.innerHTML = 'connected to broker. Subscribing...'
111 | // subscribe to the topic:
112 | client.subscribe(topic, {onSuccess: onSubscribe});
113 | }
114 |
115 | // handler for mqtt disconnect event:
116 | function onDisconnect(response) {
117 | // update localDiv text:
118 | if (response.errorCode !== 0) {
119 | localDiv.innerHTML = 'disconnected from broker: ' + response.errorMessage;
120 | }
121 | }
122 |
123 | // handler for mqtt subscribe event:
124 | function onSubscribe(response) {
125 | // update localDiv text:
126 | localDiv.innerHTML = JSON.stringify(response)
127 | +' Subscribed to ' + topic;
128 | }
129 |
130 | // handler for mqtt message received event:
131 | function onMessage(message) {
132 | let result = 'received a message: \n
';
133 | // message is a Buffer, so convert to a string:
134 | result += '
';
141 | // update the remote div text:
142 | remoteDiv.innerHTML = result;
143 | }
144 |
145 | // on page load, call the setup function:
146 | document.addEventListener('DOMContentLoaded', setup);
147 | // run a loop every 2 seconds:
148 | setInterval(loop, 2000);
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoHueLightControl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | public
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoHueLightControl/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | Hue Hub light control over MQTT
3 |
4 | This example will change the brightness of a light
5 | on a local hub when you change the slider, and will
6 | send an MQTT message with the value of the slider
7 | when you press the button. If it receives an MQTT message
8 | on the `lights` topic, it uses that value to change the
9 | brightness of the light. So you can use this
10 | to change the brightness of a local hub, or of a
11 | friend's hub on a remote network if you are both connected
12 | to the same broker.
13 |
14 | created 23 July 2020
15 | modified 5 Jan 2023
16 | by Tom Igoe
17 | */
18 | // Fill in your hue hub IP credentials here:
19 | let url = '192.168.0.8';
20 | let username = 'xxxxxxxx-xxxxxxxxx';
21 | // slider for dimming the lights:
22 | let dimmer;
23 | // the number of the light in the hub:
24 | let lightNumber = 3;
25 | // The light state:
26 | let lightState = {
27 | bri: 0,
28 | on: false
29 | }
30 |
31 | // All these brokers work with this code.
32 | // Uncomment the one you want to use.
33 |
34 | ////// emqx. Works in both basic WS and SSL WS:
35 | // const broker = 'broker.emqx.io'
36 | // const port = 8083; // no SSL
37 | // const broker = 'broker.emqx.io'
38 | // const port = 8084; // SSL
39 |
40 | //////// shiftr.io desktop client.
41 | // Fill in your desktop URL for localhost:
42 | // const broker = 'localhost';
43 | // const port = 1884; // no SSL
44 |
45 | //////// shiftr.io, requires username and password
46 | // (see options variable below):
47 | const broker = 'public.cloud.shiftr.io';
48 | const port = 443;
49 |
50 | //////// test.mosquitto.org, uses no username and password:
51 | // const broker = 'test.mosquitto.org';
52 | // const port = 8081;
53 |
54 | // MQTT client:
55 | let client;
56 | // client credentials:
57 | let clientID = 'p5HueClient';
58 |
59 | let options = {
60 | // Clean session
61 | cleanSession: true,
62 | // connect timeout in seconds:
63 | timeout: 10,
64 | // callback function for when you connect:
65 | onSuccess: onConnect,
66 | // username & password:
67 | userName: 'public',
68 | password: 'public',
69 | // use SSL
70 | useSSL: true
71 | };
72 |
73 | // topic to subscribe to when you connect to the broker:
74 | let topic = 'lights';
75 |
76 | // UI elements:
77 | // a pushbutton to send messages:
78 | let sendButton;
79 | // divs for text from the broker:
80 | let localDiv;
81 | let remoteDiv;
82 |
83 | function setup() {
84 | noLoop();
85 | // createCanvas(windowWidth, windowHeight);
86 | // a div for the Hue hub's responses:
87 | remoteDiv = createDiv('Hub response');
88 | // position it:
89 | remoteDiv.position(20, 130);
90 | // a slider to dim one light:
91 | dimmer = createSlider(0, 254, 127)
92 | // position it:
93 | dimmer.position(10, 10);
94 | // set a behavior for it:
95 | dimmer.mouseReleased(changeBrightness);
96 |
97 | // Create an MQTT client:
98 | client = new Paho.MQTT.Client(broker, port, clientID);
99 | // set callback handlers for the client:
100 | client.onConnectionLost = onDisconnect;
101 | client.onMessageArrived = onMessage;
102 | // connect to the MQTT broker:
103 | client.connect(options);
104 |
105 | // create the send button:
106 | sendButton = createButton('send a message');
107 | sendButton.position(20, 40);
108 | sendButton.mousePressed(sendMqttMessage);
109 | // create a div for local messages:
110 | localDiv = createDiv('local messages will go here');
111 | localDiv.position(20, 70);
112 | // create a div for the response:
113 | remoteDiv = createDiv('waiting for messages');
114 | remoteDiv.position(20, 100);
115 | connect();
116 | }
117 |
118 | /*
119 | this function makes the HTTP GET call to get the light data:
120 | HTTP GET http://your.hue.hub.address/api/username/lights/
121 | */
122 | function connect() {
123 | url = "http://" + url + '/api/' + username + '/lights/';
124 | httpDo(url, 'GET', getLights);
125 | }
126 |
127 | /*
128 | this function uses the response from the hub
129 | to create a new div for the UI elements
130 | */
131 | function getLights(result) {
132 | remoteDiv.html(result);
133 | }
134 |
135 | function changeBrightness() {
136 | lightState.bri = dimmer.value();
137 | if (lightState.bri > 0) {
138 | lightState.on = true;
139 | } else {
140 | lightState.on = false;
141 | }
142 | // make the HTTP call with the JSON object:
143 | setLight(lightNumber, lightState);
144 | }
145 |
146 | /*
147 | this function makes an HTTP PUT call to change the properties of the lights:
148 | HTTP PUT http://your.hue.hub.address/api/username/lights/lightNumber/state/
149 | and the body has the light state:
150 | {
151 | on: true/false,
152 | bri: brightness
153 | }
154 | */
155 | function setLight(whichLight, data) {
156 | var path = url + whichLight + '/state/';
157 |
158 | var content = JSON.stringify(data); // convert JSON obj to string
159 | httpDo(path, 'PUT', content, 'text', getLights); //HTTP PUT the change
160 | }
161 |
162 | // called when the client connects
163 | function onConnect() {
164 | localDiv.html('client is connected');
165 | client.subscribe(topic);
166 | }
167 |
168 | // called when the client loses its connection
169 | function onDisconnect(response) {
170 | if (response.errorCode !== 0) {
171 | localDiv.html('onDisconnect:' + response.errorMessage);
172 | }
173 | }
174 |
175 | // called when a message arrives
176 | function onMessage(message) {
177 | remoteDiv.html('I got a message:' + message.payloadString);
178 | let incomingNumber = parseInt(message.payloadString);
179 | // use it to set the light:
180 | lightState.bri = incomingNumber;
181 | if (lightState.bri > 0) {
182 | lightState.on = true;
183 | } else {
184 | lightState.on = false;
185 | }
186 | // make the HTTP call with the JSON object:
187 | setLight(lightNumber, lightState);
188 | }
189 |
190 | // called when you want to send a message:
191 | function sendMqttMessage() {
192 | // if the client is connected to the MQTT broker:
193 | if (client.isConnected()) {
194 | // make a string with a random number form 0 to 15:
195 | let msg = String(dimmer.value());
196 | // start an MQTT message:
197 | message = new Paho.MQTT.Message(msg);
198 | // choose the destination topic:
199 | message.destinationName = topic;
200 | // send it:
201 | client.send(message);
202 | // print what you sent:
203 | localDiv.html('I sent: ' + message.payloadString);
204 | }
205 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoP5Client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoP5Client/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | p5.js MQTT Client example
3 | This example uses p5.js: https://p5js.org/
4 | and the Eclipse Paho MQTT client library: https://www.eclipse.org/paho/clients/js/
5 | to create an MQTT client that sends and receives MQTT messages.
6 | The client is set up for use on the shiftr.io test MQTT broker,
7 | but other options listed will work.
8 |
9 | created 12 June 2020
10 | modified 31 Dec 2022
11 | by Tom Igoe
12 | */
13 |
14 | // All these brokers work with this code.
15 | // Uncomment the one you want to use.
16 |
17 | ////// emqx. Works in both basic WS and SSL WS:
18 | // const broker = 'broker.emqx.io'
19 | // const port = 8083; // no SSL
20 | // const broker = 'broker.emqx.io'
21 | // const port = 8084; // SSL
22 |
23 | //////// shiftr.io desktop client.
24 | // Fill in your desktop URL for localhost:
25 | // const broker = 'localhost';
26 | // const port = 1884; // no SSL
27 |
28 | //////// shiftr.io, requires username and password
29 | // (see options variable below):
30 | const broker = 'public.cloud.shiftr.io';
31 | const port = 443;
32 |
33 | //////// test.mosquitto.org, uses no username and password:
34 | // const broker = 'test.mosquitto.org';
35 | // const port = 8081;
36 |
37 | // MQTT client:
38 | let client;
39 | // client credentials:
40 | let clientID = 'EclipsePahoClient';
41 |
42 | let options = {
43 | // Clean session
44 | cleanSession: true,
45 | // connect timeout in seconds:
46 | timeout: 10,
47 | // callback function for when you connect:
48 | onSuccess: onConnect,
49 | // username & password:
50 | userName: 'public',
51 | password: 'public',
52 | // use SSL
53 | useSSL: true
54 | };
55 |
56 | // topic to subscribe to when you connect:
57 | let topic = 'notes';
58 | // divs to show messages:
59 | let localDiv, remoteDiv;
60 | // whether the client should be publishing or not:
61 | let publishing = true;
62 | let connected = false;
63 |
64 | // a pushbutton to send messages
65 | let sendButton;
66 | // intensity of the circle in the middle
67 | let intensity = 255;
68 |
69 | function setup() {
70 | createCanvas(400, 400);
71 | // Create an MQTT client:
72 | client = new Paho.MQTT.Client(broker, port, clientID);
73 | // set callback handlers for the client:
74 | client.onConnectionLost = onDisconnect;
75 | client.onMessageArrived = onMessage;
76 | // connect to the MQTT broker:
77 | client.connect(options);
78 | // create the send button:
79 | sendButton = createButton('send a message');
80 | sendButton.position(20, 20);
81 | sendButton.mousePressed(sendMqttMessage);
82 | // create a div for local messages:
83 | localDiv = createDiv('local messages will go here');
84 | localDiv.position(20, 50);
85 | localDiv.style('color', '#fff');
86 | // create a div for the response:
87 | remoteDiv = createDiv('waiting for messages');
88 | remoteDiv.position(20, 80);
89 | remoteDiv.style('color', '#fff');
90 | }
91 |
92 | function draw() {
93 | background(50);
94 | // draw a circle whose brightness changes when a message is received:
95 | fill(intensity);
96 | circle(width/2, height/2, width/2);
97 | // subtract one from the brightness of the circle:
98 | if (intensity > 0) {
99 | intensity--;
100 | }
101 | }
102 |
103 | // called when the client connects
104 | function onConnect() {
105 | localDiv.html('client is connected');
106 | client.subscribe(topic, {onSuccess: onSubscribe});
107 | }
108 |
109 | function onSubscribe(response) {
110 | // update localDiv text:
111 | localDiv.innerHTML = JSON.stringify(response)
112 | +' Subscribed to ' + topic;
113 | }
114 |
115 | // called when the client loses its connection
116 | function onDisconnect(response) {
117 | if (response.errorCode !== 0) {
118 | localDiv.html('disconnect:' + response.errorMessage);
119 | }
120 | }
121 |
122 | // called when a message arrives
123 | function onMessage(message) {
124 | remoteDiv.html('I got a message:' + message.payloadString);
125 | let incomingNumber = parseInt(message.payloadString);
126 | if (incomingNumber > 0) {
127 | intensity = 255;
128 | }
129 | }
130 |
131 | // called when you want to send a message:
132 | function sendMqttMessage() {
133 | // if the client is connected to the MQTT broker:
134 | if (client.isConnected()) {
135 | // make a string with a random number form 0 to 15:
136 | let msg = String(round(random(15)));
137 | // start an MQTT message:
138 | message = new Paho.MQTT.Message(msg);
139 | // choose the destination topic:
140 | message.destinationName = topic;
141 | // send it:
142 | client.send(message);
143 | // print what you sent:
144 | localDiv.html('I sent: ' + message.payloadString);
145 | }
146 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoSensorReceiverJSON/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
MQTT Sensor Reader with JSON
11 | Topic:
12 |
local messages go here
13 |
remote messages go here
14 |
15 |
16 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoSensorReceiverJSON/script.js:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Client example with JSON parsing
3 | This example uses p5.js: https://p5js.org/
4 | and the Eclipse Paho MQTT client library: https://www.eclipse.org/paho/clients/js/
5 | to create an MQTT client that receives MQTT messages.
6 | The client is set up for use on the shiftr.io test MQTT broker,
7 | but other options listed will work.
8 |
9 | There's no loop here: all the functions are event-driven.
10 |
11 | created 12 June 2020
12 | modified 31 Dec 2022
13 | by Tom Igoe
14 | */
15 |
16 | // All these brokers work with this code.
17 | // Uncomment the one you want to use.
18 |
19 | ////// emqx. Works in both basic WS and SSL WS:
20 | // const broker = 'broker.emqx.io'
21 | // const port = 8083; // no SSL
22 | // const broker = 'broker.emqx.io'
23 | // const port = 8084; // SSL
24 |
25 | //////// shiftr.io desktop client.
26 | // Fill in your desktop URL for localhost:
27 | // const broker = 'localhost';
28 | // const port = 1884; // no SSL
29 |
30 | //////// shiftr.io, requires username and password
31 | // (see options variable below):
32 | const broker = 'public.cloud.shiftr.io';
33 | const port = 443;
34 |
35 | //////// test.mosquitto.org, uses no username and password:
36 | // const broker = 'test.mosquitto.org';
37 | // const port = 8081;
38 |
39 | // MQTT client:
40 | let client;
41 | // client credentials:
42 | let clientID = 'EclipsePahoClient';
43 |
44 | let options = {
45 | // Clean session
46 | cleanSession: true,
47 | // connect timeout in seconds:
48 | timeout: 10,
49 | // callback function for when you connect:
50 | onSuccess: onConnect,
51 | // username & password:
52 | userName: 'public',
53 | password: 'public',
54 | // use SSL
55 | useSSL: true
56 | };
57 |
58 | // topic to subscribe to when you connect:
59 | let topic = 'AQISensor';
60 | // divs to show messages:
61 | let localDiv, remoteDiv;
62 |
63 | // incoming data:
64 | let data;
65 |
66 | function setup() {
67 | // put the divs in variables for ease of use:
68 | localDiv = document.getElementById('local');
69 | remoteDiv = document.getElementById('remote');
70 |
71 | // set text of localDiv:
72 | localDiv.innerHTML = 'trying to connect';
73 | // Create an MQTT client:
74 | client = new Paho.MQTT.Client(broker, port, clientID);
75 | // set callback handlers for the client:
76 | client.onConnectionLost = onDisconnect;
77 | client.onMessageArrived = onMessage;
78 | // connect to the MQTT broker:
79 | client.connect(options);
80 | }
81 |
82 | // handler for mqtt connect event:
83 | function onConnect() {
84 | // update localDiv text:
85 | localDiv.innerHTML = 'connected to broker.'
86 | // subscribe to the topic:
87 | client.subscribe(topic, {onSuccess:onSubscribe});
88 | }
89 |
90 | // handler for mqtt disconnect event:
91 | function onDisconnect(response) {
92 | // update localDiv text:
93 | if (response.errorCode !== 0) {
94 | localDiv.innerHTML = 'disconnected from broker: ' + response.errorMessage;
95 | }
96 | }
97 |
98 | // handler for mqtt error event:
99 | function onError(error) {
100 | // update localDiv text:
101 | localDiv.innerHTML = error;
102 | }
103 |
104 | // handler for mqtt subscribe event:
105 | function onSubscribe(response) {
106 | // update localDiv text:
107 | localDiv.innerHTML = JSON.stringify(response)
108 | +' Subscribed to ' + topic;
109 | }
110 |
111 | function subscribeToTopic(target) {
112 | client.unsubscribe(topic);
113 | localDiv.innerHTML = "unsubscribed from " + topic;
114 | topic = target.value;
115 | if (client.isConnected()) {
116 | client.subscribe(topic, {onSuccess:onSubscribe});
117 | }
118 | }
119 |
120 | // handler for mqtt message received event:
121 | function onMessage(message) {
122 | // variable to hold the incoming result:
123 | let result;
124 | // get the JSON string from the incoming message and parse it:
125 | try {
126 | data = JSON.parse(message.payloadString);
127 | } catch (error) {
128 | // if it's not JSON, report that
129 | result = "message is not JSON: " + message.payloadString;
130 | remoteDiv.innerHTML = result;
131 | return;
132 | }
133 | // assuming you got good JSON:
134 | result = "Incoming data: \n
";
135 | // if it's JSON, doesn't matter what the items are,
136 | // you can parse it as needed:
137 | for (item in data) {
138 | result += "
" + item + ":" + data[item] + "
\n";
139 | }
140 | // put it in the HTML:
141 | remoteDiv.innerHTML = result;
142 | }
143 |
144 | // on page load, call the setup function:
145 | document.addEventListener('DOMContentLoaded', setup);
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoWithQRCode/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | public
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoWithQRCode/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | QR Code generator and MQTT sender
3 |
4 | Draws a QR code using a text string. The QR code is the sketch's
5 | URL. Also sends an MQTT message to shiftr.io.
6 |
7 | Uses
8 | https://github.com/kazuhikoarase/qrcode-generator
9 | as the QR Code generator library. It's hosted at this CDN:
10 | https://unpkg.com/qrcode-generator@1.4.4/qrcode.js
11 |
12 | created 22 Aug 2020
13 | modified 23 Nov 2020
14 | by Tom Igoe
15 | */
16 |
17 | // a string to diisplay in the QR code
18 | // (the URL of this sketch):
19 | let urlString = parent.location.href;
20 | // an HTML div to display it in:
21 | let tagDiv;
22 |
23 | // All these brokers work with this code.
24 | // Uncomment the one you want to use.
25 |
26 | ////// emqx. Works in both basic WS and SSL WS:
27 | // const broker = 'broker.emqx.io'
28 | // const port = 8083; // no SSL
29 | // const broker = 'broker.emqx.io'
30 | // const port = 8084; // SSL
31 |
32 | //////// shiftr.io desktop client.
33 | // Fill in your desktop URL for localhost:
34 | // const broker = 'localhost';
35 | // const port = 1884; // no SSL
36 |
37 | //////// shiftr.io, requires username and password
38 | // (see options variable below):
39 | const broker = 'public.cloud.shiftr.io';
40 | const port = 443;
41 |
42 | //////// test.mosquitto.org, uses no username and password:
43 | // const broker = 'test.mosquitto.org';
44 | // const port = 8081;
45 |
46 | // MQTT client:
47 | let client;
48 | // client credentials (add random number for unique ID):
49 | let clientID = 'p5HueClient-' + Math.floor(Math.random()*1000000);
50 |
51 | let options = {
52 | // Clean session
53 | cleanSession: true,
54 | // connect timeout in seconds:
55 | timeout: 10,
56 | // callback function for when you connect:
57 | onSuccess: onConnect,
58 | // username & password:
59 | userName: 'public',
60 | password: 'public',
61 | // use SSL
62 | useSSL: true
63 | };
64 |
65 | // topic to subscribe to when you connect to the broker:
66 | let topic = 'lights';
67 |
68 | // UI elements:
69 | let dimmer;
70 | let brightness = 0;
71 |
72 | // divs for text from the broker:
73 | let localDiv;
74 | let remoteDiv;
75 |
76 | function setup() {
77 | noCanvas();
78 | noLoop();
79 |
80 | // make the HTML tag div:
81 | tagDiv = createDiv();
82 | // make the QR code:
83 | let qr = qrcode(0, 'L');
84 | qr.addData(urlString);
85 | qr.make();
86 | // create an image from it:
87 | let qrImg = qr.createImgTag(2, 8, "qr code");
88 | // put the image and the URL string into the HTML div:
89 | tagDiv.html(qrImg);
90 | // position it:
91 | tagDiv.position(10, 10);
92 | // set a callback function for clicking on the tag:
93 | tagDiv.mousePressed(hideTag);
94 |
95 | // a slider to dim one light:
96 | dimmer = createSlider(0, 254, 127)
97 | // position it:
98 | dimmer.position(10, 160);
99 | // set a behavior for it:
100 | dimmer.mouseReleased(changeBrightness);
101 |
102 | // Create an MQTT client:
103 | client = new Paho.MQTT.Client(broker, port, clientID);
104 | // set callback handlers for the client:
105 | client.onConnectionLost = onDisconnect;
106 | client.onMessageArrived = onMessage;
107 | // connect to the MQTT broker:
108 | client.connect(options);
109 |
110 | // create a div for local messages:
111 | localDiv = createDiv('local messages will go here');
112 | localDiv.position(20, 100);
113 | // create a div for the response:
114 | remoteDiv = createDiv('waiting for messages');
115 | remoteDiv.position(20, 130);
116 | }
117 |
118 | function draw() {
119 |
120 | }
121 |
122 | // This function hides the tag div when you click on it:
123 | function hideTag() {
124 | tagDiv.hide();
125 | }
126 |
127 | function changeBrightness() {
128 | brightness = dimmer.value();
129 | sendMqttMessage(brightness);
130 | }
131 |
132 | // called when the client connects
133 | function onConnect() {
134 | localDiv.html('client is connected');
135 | client.subscribe(topic);
136 | }
137 |
138 | // called when the client loses its connection
139 | function onDisconnect(response) {
140 | if (response.errorCode !== 0) {
141 | localDiv.html('onDisconnect:' + response.errorMessage);
142 | }
143 | }
144 |
145 | // called when a message arrives
146 | function onMessage(message) {
147 | remoteDiv.html('I got a message:' + message.payloadString);
148 | }
149 |
150 | // called when you want to send a message:
151 | function sendMqttMessage() {
152 | // if the client is connected to the MQTT broker:
153 | if (client.isConnected()) {
154 | // make a string with a random number form 0 to 15:
155 | let msg = String(brightness);
156 | // start an MQTT message:
157 | message = new Paho.MQTT.Message(msg);
158 | // choose the destination topic:
159 | message.destinationName = topic;
160 | // send it:
161 | client.send(message);
162 | // print what you sent:
163 | localDiv.html('I sent: ' + message.payloadString);
164 | }
165 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/EclipsePahoWithQRCode/style.css:
--------------------------------------------------------------------------------
1 | /* adapted from https://css-tricks.com/simplified-fluid-typography/ */
2 |
3 | html {
4 | font-size: min(max(1rem, 4vmax), 22px);
5 | }
6 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/mousePressed-client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/mousePressed-client/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | p5.js MQTT Client example
3 | This example uses p5.js: https://p5js.org/
4 | and the Eclipse Paho MQTT client library: https://www.eclipse.org/paho/clients/js/
5 | to create an MQTT client that sends and receives MQTT messages.
6 | The client is set up for use on the shiftr.io test MQTT broker,
7 | but other options listed will work.
8 |
9 | created 12 June 2020
10 | modified 31 Dec 2022
11 | by Tom Igoe
12 | */
13 |
14 | // All these brokers work with this code.
15 | // Uncomment the one you want to use.
16 |
17 | ////// emqx. Works in both basic WS and SSL WS:
18 | // const broker = 'broker.emqx.io'
19 | // const port = 8083; // no SSL
20 | // const broker = 'broker.emqx.io'
21 | // const port = 8084; // SSL
22 |
23 | //////// shiftr.io desktop client.
24 | // Fill in your desktop URL for localhost:
25 | // const broker = 'localhost';
26 | // const port = 1884; // no SSL
27 |
28 | //////// shiftr.io, requires username and password
29 | // (see options variable below):
30 | const broker = 'public.cloud.shiftr.io';
31 | const port = 443;
32 |
33 | //////// test.mosquitto.org, uses no username and password:
34 | // const broker = 'test.mosquitto.org';
35 | // const port = 8081;
36 |
37 | // MQTT client:
38 | let client;
39 | // client credentials (add random number for unique ID):
40 | let clientID = 'EclipsePahoClient-' + Math.floor(Math.random()*1000000);
41 |
42 | let options = {
43 | // Clean session
44 | cleanSession: true,
45 | // connect timeout in seconds:
46 | timeout: 10,
47 | // callback function for when you connect:
48 | onSuccess: onConnect,
49 | // username & password:
50 | userName: 'public',
51 | password: 'public',
52 | // use SSL
53 | useSSL: true
54 | };
55 |
56 | // topic to subscribe to when you connect:
57 | let topic = 'monkey';
58 | // divs to show messages:
59 | let localDiv, remoteDiv;
60 |
61 | // position of the circle
62 | let xPos, yPos;
63 |
64 | function setup() {
65 | createCanvas(400, 400);
66 | // Create an MQTT client:
67 | client = new Paho.MQTT.Client(broker, port, clientID);
68 | // set callback handlers for the client:
69 | client.onConnectionLost = onDisconnect;
70 | client.onMessageArrived = onMessage;
71 | // connect to the MQTT broker:
72 | client.connect(options);
73 | // create a div for local messages:
74 | localDiv = createDiv('local messages will go here');
75 | localDiv.position(20, 50);
76 | // create a div for the response:
77 | remoteDiv = createDiv('waiting for messages');
78 | remoteDiv.position(20, 80);
79 | }
80 |
81 | function draw() {
82 | background(255);
83 | noStroke();
84 | // draw a circle when a message is received:
85 | fill('#2398CE');
86 | // circle moves with the message:
87 | circle(xPos, yPos, 30);
88 | }
89 |
90 | function mousePressed() {
91 | sendMqttMessage(mouseX + ',' + mouseY);
92 | }
93 | // called when the client connects
94 | function onConnect() {
95 | localDiv.html('client is connected');
96 | client.subscribe(topic);
97 | }
98 |
99 | // called when the client loses its connection
100 | function onDisconnect(response) {
101 | if (response.errorCode !== 0) {
102 | localDiv.html('disconnect:' + response.errorMessage);
103 | }
104 | }
105 |
106 | // called when a message arrives
107 | function onMessage(message) {
108 | remoteDiv.html('I got a message:' + message.payloadString);
109 | // assume the message is two numbers, mouseX and mouseY.
110 | // Split it into an array:
111 | let values = split(message.payloadString, ',');
112 | // convert the array values into numbers:
113 | xPos = Number(values[0]);
114 | yPos = Number(values[1]);
115 | }
116 |
117 | // called when you want to send a message:
118 | function sendMqttMessage(msg) {
119 | // if the client is connected to the MQTT broker:
120 | if (client.isConnected()) {
121 | // start an MQTT message:
122 | message = new Paho.MQTT.Message(msg);
123 | // choose the destination topic:
124 | message.destinationName = topic;
125 | // send it:
126 | client.send(message);
127 | // print what you sent:
128 | localDiv.html('I sent: ' + message.payloadString);
129 | }
130 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/mqtt-midi-client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/mqtt-midi-client/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | p5.js MQTT MIDI Client
3 | This example uses p5.js: https://p5js.org/
4 | and the Eclipse Paho MQTT client library: https://www.eclipse.org/paho/clients/js/
5 | and the Web MIDI API (https://www.w3.org/TR/webmidi/)
6 | to create an MQTT client that sends and receives MQTT messages
7 | that are MIDI messages.
8 | The client is set up for use on the shiftr.io test MQTT broker (https://public.cloud.shiftr.io),
9 | but has also been tested on https://test.mosquitto.org
10 |
11 | created 11 Nov 2020
12 | modified 23 Nov 2020
13 | by Tom Igoe
14 | */
15 |
16 | // MQTT client details:
17 | let broker = {
18 | hostname: 'public.cloud.shiftr.io',
19 | port: 443
20 | };
21 | // MQTT client:
22 | let client;
23 | // client credentials:
24 | // For shiftr.io, use try for both username and password
25 | // unless you have an account on the site.
26 | let creds = {
27 | // add random number for unique client ID:
28 | clientID: 'p5MidiClient-' + Math.floor(Math.random()*1000000),
29 | userName: 'public',
30 | password: 'public'
31 | }
32 | // topic to subscribe to when you connect
33 | // For shiftr.io, use whatever word you want for the subtopic
34 | // unless you have an account on the site.
35 | let subTopic = '';
36 | let topic = 'midi';
37 |
38 | // HTML divs for local and remote messages
39 | let localDiv;
40 | let remoteDiv;
41 |
42 | // select menus for MIDI inputs and outputs:
43 | let inputSelect, outputSelect;
44 |
45 | // arrays for the MIDI devices:
46 | let outputDevices = new Array();
47 | let inputDevices = new Array();
48 |
49 | // variables for the currently selected ones:
50 | let currentOutput, currentInput;
51 |
52 | // an HTML div for messages:
53 | let messageDiv;
54 |
55 |
56 | function setup() {
57 | noCanvas();
58 | noLoop();
59 |
60 | // Create an MQTT client:
61 | client = new Paho.MQTT.Client(broker.hostname, broker.port, creds.clientID);
62 | // set callback handlers for the client:
63 | client.onConnectionLost = onConnectionLost;
64 | client.onMessageArrived = onMessageArrived;
65 | // connect to the MQTT broker:
66 | client.connect(
67 | {
68 | onSuccess: onConnect, // callback function for when you connect
69 | userName: creds.userName, // username
70 | password: creds.password, // password
71 | useSSL: true // use SSL
72 | }
73 | );
74 | // create a div for local messages:
75 | localDiv = createDiv('local messages will go here');
76 | localDiv.position(10, 110);
77 |
78 | // create a div for the response:
79 | remoteDiv = createDiv('waiting for messages');
80 | remoteDiv.position(10, 140);
81 |
82 |
83 | // create the select menus and position them:
84 | inputSelect = createSelect();
85 | inputSelect.position(10, 10);
86 | inputSelect.changed(selectInput);
87 | inputSelect.option('--Choose an input:--', 0);
88 |
89 | outputSelect = createSelect();
90 | outputSelect.position(10, 50);
91 | outputSelect.changed(selectOutput);
92 | outputSelect.option('--Choose an output:--', 0);
93 |
94 | // create the message div and position it:
95 | messageDiv = createDiv('messages will go here');
96 | messageDiv.position(10, 80);
97 |
98 | // initialize MIDI and get device lists:
99 | navigator.requestMIDIAccess()
100 | .then(getDevices);
101 | }
102 |
103 | // called when the client connects
104 | function onConnect() {
105 | localDiv.html('client is connected');
106 | client.subscribe(topic);
107 | }
108 |
109 | // called when the client loses its connection
110 | function onConnectionLost(response) {
111 | if (response.errorCode !== 0) {
112 | localDiv.html('onConnectionLost:' + response.errorMessage);
113 | }
114 | }
115 |
116 | // called when an MQTT message arrives
117 | function onMessageArrived(message) {
118 | let payload = message.payloadBytes;
119 | remoteDiv.html('I got a message ' + payload);
120 | // set up an arrayBuffer and a Uint8 array for the incoming:
121 | let incomingBuffer = new ArrayBuffer(payload.length);
122 | let midiCmd = new Uint8Array(incomingBuffer);
123 |
124 | // move the message payload into the UInt8 array:
125 | for (var i = 0; i < payload.length; i++) {
126 | midiCmd[i] = payload[i];
127 | }
128 |
129 | // if the message is intended for the current MIDIoutput,
130 | // send it there:
131 | if (currentOutput != null) {
132 | currentOutput.send(midiCmd);
133 | }
134 | }
135 |
136 | // called when you want to send a message:
137 | function sendMqttMessage(msg) {
138 | // if the client is connected to the MQTT broker:
139 | if (client.isConnected()) {
140 | // start an MQTT message:
141 | message = new Paho.MQTT.Message(msg);
142 | // choose the destination topic:
143 | message.destinationName = topic;
144 | // send it:
145 | client.send(message);
146 | // print what you sent:
147 | localDiv.html('I sent: ' + message.payloadString);
148 | }
149 | }
150 |
151 | // MIDI Functions /////////////////////////////////////////////////////
152 |
153 | // Get lists of available MIDI controllers
154 | function getDevices(midiAccess) {
155 | const inputs = midiAccess.inputs.values();
156 | const outputs = midiAccess.outputs.values();
157 |
158 | // add inputs and outputs to the global arrays and the select menus:
159 | for (let i of inputs) {
160 | addMidiItem(i);
161 | }
162 | for (let o of outputs) {
163 | addMidiItem(o);
164 | }
165 |
166 | // if any of the devices change state, add or delete it:
167 | midiAccess.onstatechange = function (item) {
168 | // if an item changes state, add it or delete it from the select menus:
169 | if (item.port.state == 'connected') {
170 | addMidiItem(item.port);
171 | }
172 | if (item.port.state == 'disconnected') {
173 | removeMidiItem(item.port);
174 | }
175 |
176 | // Print information about the changed MIDI controller:
177 | messageDiv.html(item.port.name + " "
178 | + item.port.state);
179 | };
180 | }
181 |
182 | // add new MIDI devices:
183 | function addMidiItem(midiItem) {
184 | // add to the appropriate select menu,
185 | // but make sure it's not already in the list:
186 | if (midiItem.type == 'input' && inputDevices.indexOf(midiItem) < 0) {
187 | inputSelect.option(midiItem.name);
188 | // add to the devices array too:
189 | inputDevices.push(midiItem);
190 | }
191 | if (midiItem.type == 'output' && outputDevices.indexOf(midiItem) < 0) {
192 | outputSelect.option(midiItem.name);
193 | // add to the devices array too:
194 | outputDevices.push(midiItem);
195 | }
196 |
197 | // add a message listener:
198 | midiItem.onmidimessage = getMIDIMessage;
199 | }
200 |
201 | // remove items when they go away:
202 | function removeMidiItem(midiItem) {
203 | // choose the right select menu:
204 | if (midiItem.type == 'input') {
205 | selectMenu = inputSelect;
206 | inputDevices.splice(inputDevices.indexOf(midiItem), 1);
207 | }
208 | if (midiItem.type == 'output') {
209 | selectMenu = outputSelect;
210 | outputDevices.splice(outputDevices.indexOf(midiItem), 1);
211 | }
212 |
213 | // clear the message listener:
214 | midiItem.onmidimessage = null;
215 |
216 | // delete the item from the menu:
217 | for (let i = 0; i < selectMenu.elt.length; i++) {
218 | if (selectMenu.elt[i].innerHTML === midiItem.name) {
219 | selectMenu.elt[i].remove();
220 | }
221 | }
222 | }
223 |
224 | // select the current input or output from the select menus:
225 | function selectInput() {
226 | for (let i of inputDevices) {
227 | if (i.name === inputSelect.selected()) {
228 | currentInput = i;
229 | }
230 | }
231 | // if they chose the default position, clear the current input:
232 | if (inputSelect.value() == 0) {
233 | currentInput = null;
234 | }
235 | }
236 |
237 | function selectOutput() {
238 | // iterate over the list of devices:
239 | for (let o of outputDevices) {
240 | if (o.name === outputSelect.selected()) {
241 | currentOutput = o;
242 | }
243 | }
244 | // if they chose the default position, clear the current output:
245 | if (outputSelect.value() == 0) {
246 | currentOutput = null;
247 | }
248 | }
249 |
250 | // MIDI message listener function:
251 | function getMIDIMessage(message) {
252 | // if the message came from a device other than the current input, you're done:
253 | if (currentInput !== message.currentTarget) return;
254 |
255 | // print the message (print the MIDI bytes as hexadeciimal values):
256 | messageDiv.html("MIDI message: 0x"
257 | + message.data[0].toString(16)
258 | + ", 0x" + message.data[1].toString(16)
259 | + ", 0x" + message.data[2].toString(16));
260 |
261 | // if the message is intended for the current output, send it there:
262 | if (currentOutput != null) {
263 | currentOutput.send(message.data);
264 | }
265 |
266 | // if connected to MQTT, send message as MQTT message:
267 | if (client.isConnected()) {
268 | sendMqttMessage(message.data.buffer);
269 | }
270 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/mqtt-midi-controller/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
MIDI MQTT Message Sender and Receiver
14 |
This page connects to an MQTT broker, and uses WebMIDI to connect to any MIDI inputs or outputs on your system. It will auto-detect new MIDI devices as they are connected or disconnected from your system.
15 |
When a MIDI message is received, it is converted to an MQTT message on a topic called Midi, and sent out to the MQTT broker. Likewise, when an MQTT message is received, it is converted to a MIDI message and sent to the selected MIDI output device.
16 |
You can also generate MIDI messages (and MQTT messages) by typing the keys below.
17 |
The Local Echo checkbox selects whether the MIDI output takes messages from local sources, or just from MQTT.
18 |
19 |
20 |
21 |
22 |
local messages will go here
23 |
waiting for messages
24 |
messages will go here
25 |
26 |
Keyboard Input:
27 | W E T Y U O
28 | A S D F G H J K L
29 | C3 D3 E3 F3 G3 A4 B4 C4 D4
30 |
31 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/mqtt-midi-controller/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Arial, Helvetica, sans-serif;
3 | }
4 | #black-keys {
5 | font-size: 24px;
6 | letter-spacing: 5px;
7 | }
8 |
9 | #white-keys {
10 | font-size: 24px;
11 | letter-spacing: 5px;
12 | }
13 |
14 | #notes {
15 | font-size: 12px;
16 | word-spacing: 14px;
17 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/p5Serial-client/ArduinoJoystick/ArduinoJoystick.ino:
--------------------------------------------------------------------------------
1 | /*
2 | A Joystick client
3 | Reads a joystick whose two potentiometers are connected
4 | to analog 0 and analog 1.
5 | */
6 |
7 | void setup() {
8 | Serial.begin(9600);
9 | pinMode(2, INPUT_PULLUP);
10 | }
11 |
12 | void loop() {
13 | int buttonState = digitalRead(2);
14 | // read analog 0, convert to a byte:
15 | int x = analogRead(A0) / 4;
16 | // 1ms delay to stabilize ADC:
17 | delay(1);
18 | // read analog 1, convert to a byte:
19 | int y = analogRead(A1) / 4;
20 | // send values out serial port as a JSON string:
21 | String jsonString = "{\"x\":XPOS,\"y\":YPOS,\"button\":BUTTON}";
22 | // replace the placeholders in the String with the actual values:
23 | jsonString.replace("XPOS", String(x));
24 | jsonString.replace("YPOS", String(y));
25 | jsonString.replace("BUTTON", String(buttonState));
26 | // send the string:
27 | Serial.println(jsonString);
28 | }
29 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/p5Serial-client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/p5Serial-client/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | p5.js MQTT Client and p5.WebSerial example
3 | This example uses p5.js: https://p5js.org/
4 | and the Eclipse Paho MQTT client library: https://www.eclipse.org/paho/clients/js/
5 | to create an MQTT client that sends and receives MQTT messages.
6 | It takes input via asynchronous serial from p5.WebSerial,
7 | allowing you to connect microcontroller projects together
8 | using p5.js, p5.WebSerial, and MQTT.
9 | NOTE: WebSerial does not work on all browsers, just Chrome, Edge, and Opera.
10 | See this chart for more:
11 | https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API#browser_compatibility
12 | The MQTT client is set up for use on the shiftr.io test MQTT broker,
13 | but other options listed will work.
14 |
15 | created 12 June 2020
16 | modified 31 Dec 2022
17 | by Tom Igoe
18 | */
19 |
20 | // All these brokers work with this code.
21 | // Uncomment the one you want to use.
22 |
23 | ////// emqx. Works in both basic WS and SSL WS:
24 | // const broker = 'broker.emqx.io'
25 | // const port = 8083; // no SSL
26 | // const broker = 'broker.emqx.io'
27 | // const port = 8084; // SSL
28 |
29 | //////// shiftr.io desktop client.
30 | // Fill in your desktop URL for localhost:
31 | // const broker = 'localhost';
32 | // const port = 1884; // no SSL
33 |
34 | //////// shiftr.io, requires username and password
35 | // (see options variable below):
36 | const broker = 'public.cloud.shiftr.io';
37 | const port = 443;
38 |
39 | //////// test.mosquitto.org, uses no username and password:
40 | // const broker = 'test.mosquitto.org';
41 | // const port = 8081;
42 |
43 | // MQTT client:
44 | let client;
45 | // client credentials (add random number for unique ID):
46 | let clientID = 'EclipsePahoClient-' + Math.floor(Math.random()*1000000);
47 |
48 | let options = {
49 | // Clean session
50 | cleanSession: true,
51 | // connect timeout in seconds:
52 | timeout: 10,
53 | // callback function for when you connect:
54 | onSuccess: onConnect,
55 | // username & password:
56 | userName: 'public',
57 | password: 'public',
58 | // use SSL
59 | useSSL: true
60 | };
61 |
62 | // topic to subscribe to when you connect:
63 | let topic = 'circle';
64 | // divs to show messages:
65 | let localDiv, remoteDiv;
66 |
67 | // position of the circle
68 | let xPos, yPos;
69 | // variable to hold an instance of the p5.webserial library:
70 | const serial = new p5.WebSerial();
71 |
72 | // HTML button object:
73 | let portButton;
74 | // timestamp and interval for serial sending, in ms:
75 | let lastTimeSent = 0;
76 | const sendInterval = 500;
77 |
78 | function setup() {
79 | createCanvas(400, 400);
80 | // Create an MQTT client:
81 | client = new Paho.MQTT.Client(broker, port, clientID);
82 | // set callback handlers for the client:
83 | client.onConnectionLost = onDisconnect;
84 | client.onMessageArrived = onMessage;
85 | // connect to the MQTT broker:
86 | client.connect(options);
87 | // create a div for local messages:
88 | localDiv = createDiv('local messages will go here');
89 | localDiv.position(20, 50);
90 | // create a div for the response:
91 | remoteDiv = createDiv('waiting for messages');
92 | remoteDiv.position(20, 80);
93 |
94 | // Serial initialization:
95 | // check to see if serial is available:
96 | if (!navigator.serial) {
97 | alert("WebSerial is not supported in this browser. Try Chrome or MS Edge.");
98 | }
99 | // if serial is available, add connect/disconnect listeners:
100 | navigator.serial.addEventListener("connect", portConnect);
101 | navigator.serial.addEventListener("disconnect", portDisconnect);
102 | // check for any ports that are available:
103 | serial.getPorts();
104 | // if there's no port chosen, choose one:
105 | serial.on("noport", makePortButton);
106 | // open whatever port is available:
107 | serial.on("portavailable", openPort);
108 | // handle serial errors:
109 | serial.on("requesterror", portError);
110 | // handle any incoming serial data:
111 | serial.on("data", serialEvent);
112 | serial.on("close", makePortButton);
113 | }
114 |
115 | function draw() {
116 | background(255);
117 | noStroke();
118 | // draw a circle when a message is received:
119 | fill('#2398CE');
120 | // circle moves with the message:
121 | circle(xPos, yPos, 30);
122 | }
123 |
124 | // if there's no port selected,
125 | // make a port select button appear:
126 | function makePortButton() {
127 | // create and position a port chooser button:
128 | portButton = createButton('choose port');
129 | portButton.position(10, 10);
130 | // give the port button a mousepressed handler:
131 | portButton.mousePressed(choosePort);
132 | }
133 |
134 | // make the port selector window appear:
135 | function choosePort() {
136 | serial.requestPort();
137 | }
138 |
139 | // open the selected port, and make the port
140 | // button invisible:
141 | function openPort() {
142 | // wait for the serial.open promise to return,
143 | // then call the initiateSerial function
144 | serial.open().then(initiateSerial);
145 |
146 | // once the port opens, let the user know:
147 | function initiateSerial() {
148 | localDiv.html("port open");
149 | }
150 | // hide the port button once a port is chosen:
151 | if (portButton) portButton.hide();
152 | }
153 |
154 | // read any incoming serial data:
155 | function serialEvent() {
156 | // read a line from the serial port:
157 | let inData = serial.readLine();
158 | // send it as an MQTT message to the topic:
159 | if (inData && millis() - lastTimeSent > sendInterval) {
160 | sendMqttMessage(inData);
161 | lastTimeSent = millis();
162 | }
163 | }
164 |
165 | // pop up an alert if there's a port error:
166 | function portError(err) {
167 | alert("Serial port error: " + err);
168 | serial.port.forget();
169 | }
170 |
171 | // try to connect if a new serial port
172 | // gets added (i.e. plugged in via USB):
173 | function portConnect() {
174 | localDiv.html("port connected");
175 | serial.getPorts();
176 | }
177 |
178 | // if a port is disconnected:
179 | function portDisconnect() {
180 | serial.close();
181 | serial.port.forget();
182 | localDiv.html("port disconnected");
183 | }
184 |
185 | // called when the client connects
186 | function onConnect() {
187 | localDiv.html('client is connected');
188 | client.subscribe(topic);
189 | }
190 |
191 | // called when the client loses its connection
192 | function onDisconnect(response) {
193 | if (response.errorCode !== 0) {
194 | console.log(response.errorMessage);
195 | localDiv.html('broker disconnect:' + response.errorMessage);
196 | }
197 | }
198 |
199 | // called when a message arrives
200 | function onMessage(message) {
201 | remoteDiv.html('I got a message:' + message.payloadString);
202 | // assume the message payload is a JSON object
203 | // From the ArduinoJoystick example in this folder:
204 | // {"x":xPos,"y":yPos,"button":buttonState}
205 | // parse it and use the X and Y:
206 | var joyStick = JSON.parse(message.payloadString);
207 | xPos = joyStick.x;
208 | yPos = joyStick.y;
209 | }
210 |
211 | // called when you want to send a message:
212 | function sendMqttMessage(msg) {
213 | // if the client is connected to the MQTT broker:
214 | if (client.isConnected()) {
215 | // start an MQTT message:
216 | message = new Paho.MQTT.Message(msg);
217 | // choose the destination topic:
218 | message.destinationName = topic;
219 | // send it:
220 | client.send(message);
221 | // print what you sent:
222 | localDiv.html('I sent: ' + message.payloadString);
223 | }
224 | }
--------------------------------------------------------------------------------
/browser-clients/eclipse-pahojs/readme.md:
--------------------------------------------------------------------------------
1 | # Eclipse PAHO JavaScript Library
2 |
3 | **There is an MQTT client library from the Eclipse foundation, the [Eclipse PAHO library](https://github.com/eclipse-paho/paho.mqtt.javascript), but it appears to be no longer supported by the foundation.The [mqtt.js library]({{site.baseurl}}/browser-clients/mqttjs) seems more supported at this date (Feb 2025).**
4 |
5 | There are several examples for Eclipse PAHO in [this directory]({{site.codeurl}}/browser-clients/eclipse-pahojs/).
6 |
7 | ## EclipsePahoClientSimple
8 | * [See the example running](EclipsePahoClientSimple)
9 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/EclipsePahoClientSimple)
10 |
11 | This is a bare minimum client example for Eclipse PAHO JS. On document load, the script for this page gets two divs from the HTML document for local and remote messages.Then it attempts to connect to the broker. Once it does, it sends the local time if it's connected every two seconds. The publish button allows you to turn on and off publishing status, in case you're testing with a second client that's sending to the same topic.
12 |
13 | The [ArduinoMqttClient example]({{site.codeurl}}/arduino-clients/ArduinoMqttClient) uses the same topic and sends the same range of numeric values if you want to test against another client. The [MqttJsClientSimple](../mqttjs/MqttJsClientSimple/) does the same.
14 |
15 | ## EclipsePahoP5Client
16 | * [See the example running](EclipsePahoP5Client)
17 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/EclipsePahoP5Client)
18 |
19 | This example combines Eclipse PAHO and [p5.js](https://p5js.org/). It sends a value between 1 and 15 to a topic called "notes". The MQTT functionality is similar to the example above.
20 |
21 | ## mousePressed-client
22 |
23 | * [See the example running](mousePressed-client)
24 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/mousePressed-client)
25 |
26 | A simpler Eclipse PAHO and p5.js client that sends the mouseX and mouseY on a mouse press. The topic for this one is "monkey".
27 |
28 | ## p5-webSerial-client
29 | * [See the example running](p5-webSerial-client)
30 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/p5-webSerial-client)
31 |
32 | This example combines the p5.js MQTT client and the [p5.js webserial library](https://github.com/yoonbuck/p5.WebSerial). It takes any incoming serial messages and sends them out as MQTT messages. An accompanying Arduino sketch, [ArduinoJoystick](p5-webSerial-client/ArduinoJoystick/) sends the values from a Arduino connected via asynchronous serial port. For more on p5.WebSerial, see [these exercises](https://itp.nyu.edu/physcomp/labs/#p5js_webserial_library).
33 |
34 | ## Sensor Reader Client with JSON
35 | * [See the example running](EclipsePahoSensorReceiverJSON)
36 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/EclipsePahoSensorReceiverJSON)
37 |
38 | The example `EclipsePahoSensorReceiverJSON` subscribes to a topic and listens for JSON messages. It then parses them and displays them. It doesn't care what the data is, as long as it's in JSON format. You can change topics just by entering a new topic name in the topic field.
39 |
40 | This [JSON validator](https://jsonlint.com/) may be useful for when you start reformatting strings and make mistakes.
41 |
42 | This example will work any of the [Arduino sensor client examples]({{site.baseurl}}/arduino-clients/#sensor-clients).
43 |
44 | ## Web MIDI Clients
45 |
46 | * [See the example running](mqtt-midi-client)
47 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/mqtt-midi-client)
48 |
49 | The mqtt-midi-client example combines Eclipse PAHO and [p5.js](https://p5js.org) with the [Web MIDI API](https://www.w3.org/TR/webmidi/), sending MIDI messages over an MQTT broker:
50 |
51 | * [See the example running](mqtt-midi-controller)
52 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/mqtt-midi-controller)
53 |
54 | The mqtt-midi-controller example works without p5.js, and with keyboard input so that it can act as a MIDI controller.
55 |
56 | This [Arduino MQTT-to-MIDI Client]({{site.codeurl}}/arduino-clients/MqttClientMIDIPlayer/MqttClientMIDIPlayer.ino) can receive MIDI messages from the same broker and send MIDI to your operating system or MIDI system. This [Arduino MIDI-to-MQTT client]({{site.codeurl}}/arduino-clients/MqttClientMIDIController/MqttClientMIDIController.ino) can send noteon and noteoff messages via MQTT at the push of a button.
57 |
58 | ## Philips Hue Control
59 |
60 | * [See the example running](EclipsePahoHueLightControl)
61 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/EclipsePahoHueLightControl/)
62 |
63 | This example listens for messages on the topic `lights` and uses them to set the brightness of a Philips Hue light on the browser's local network by sending HTTP messages to a local Philips Hue hub to control Hue lights. For more on controlling the Philips Hue, see [this repository](https://tigoe.github.io/hue-control/). It works with the [Arduino MqttClientHueControl example]({{site.codeurl}}/arduino-clients/MqttClientHueControl/MqttClientHueControl.ino) as well.
64 |
65 | ## Hue Control via QRCode Client
66 |
67 | * [See the example running](EclipsePahoWithQRCode)
68 | * [See the source code]({{site.codeurl}}/browser-clients/eclipse-pahojs/EclipsePahoHueLightControl/)
69 |
70 | This example works with the Philips Hue clients as well. It generates its URL in a QR code, to make it easy to pass from one phone to another. It sends a value to the topic `lights`. If either of the Philips Hue clients is connected to the same broker and topic, they will receive the message and control a Philips Hue light on their own network.
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqtt-midi-controller/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
MIDI MQTT Message Sender and Receiver
14 |
This page connects to an MQTT broker, and uses WebMIDI to connect to any MIDI inputs or outputs on your system. It will auto-detect new MIDI devices as they are connected or disconnected from your system.
15 |
When a MIDI message is received, it is converted to an MQTT message on a topic called Midi, and sent out to the MQTT broker. Likewise, when an MQTT message is received, it is converted to a MIDI message and sent to the selected MIDI output device.
16 |
You can also generate MIDI messages (and MQTT messages) by typing the keys below.
17 |
The Local Echo checkbox selects whether the MIDI output takes messages from local sources, or just from MQTT.
18 |
19 |
20 |
21 |
22 |
local messages will go here
23 |
waiting for messages
24 |
messages will go here
25 |
26 |
Keyboard Input:
27 | W E T Y U O
28 | A S D F G H J K L
29 | C3 D3 E3 F3 G3 A4 B4 C4 D4
30 |
31 |
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqtt-midi-controller/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Arial, Helvetica, sans-serif;
3 | }
4 | #black-keys {
5 | font-size: 24px;
6 | letter-spacing: 5px;
7 | }
8 |
9 | #white-keys {
10 | font-size: 24px;
11 | letter-spacing: 5px;
12 | }
13 |
14 | #notes {
15 | font-size: 12px;
16 | word-spacing: 14px;
17 | }
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqttjs-client-simple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | MQTT Client
9 |
10 |
11 |
mqtt.js basic example
12 |
13 | Click here for the source code
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqttjs-client-simple/script.js:
--------------------------------------------------------------------------------
1 | /*
2 | Bare minimum client example for mqtt.js
3 |
4 | On document load, this script gets two divs from the HTML
5 | for local and remote messages. Then it attempts
6 | to connect to the broker. Once every two seconds,
7 | it sends the local time if it's connected.
8 | The publish button allows you to turn on and off publishing status.
9 |
10 | created 29 Dec 2022
11 | modified 5 Feb 2023
12 | by Tom Igoe
13 | */
14 |
15 | // All these brokers work with this code.
16 | // Uncomment the one you want to use.
17 |
18 | ////// emqx. Works in both basic WS and TLS WS:
19 | // const broker = 'wss://broker.emqx.io:8084/mqtt'
20 | // const broker = 'ws://broker.emqx.io:8083/mqtt'
21 |
22 | //////// shiftr.io desktop client.
23 | // Fill in your desktop IP address for localhost:
24 | // const broker = 'ws://localhost:1884';
25 |
26 | //////// shiftr.io, requires username and password
27 | // (see options variable below):
28 | const broker = 'wss://public.cloud.shiftr.io';
29 |
30 | //////// test.mosquitto.org, uses no username and password:
31 | // const broker = 'wss://test.mosquitto.org:8081';
32 |
33 | // MQTT client:
34 | let client;
35 |
36 | // connection options:
37 | let options = {
38 | // Clean session
39 | clean: true,
40 | // connect timeout in ms:
41 | connectTimeout: 10000,
42 | // Authentication
43 | // add a random number for a unique client ID:
44 | clientId: 'mqttJsClient-' + Math.floor(Math.random()*1000000) ,
45 | // add these in for public.cloud.shiftr.io:
46 | username: 'public',
47 | password: 'public'
48 | }
49 | // topic to subscribe to when you connect:
50 | let topic = 'aardvarks';
51 | // divs to show messages:
52 | let localDiv, remoteDiv;
53 | // whether the client should be publishing or not:
54 | let publishing = true;
55 |
56 | function setup() {
57 | // put the divs in variables for ease of use:
58 | localDiv = document.getElementById('local');
59 | remoteDiv = document.getElementById('remote');
60 |
61 | // set text of localDiv:
62 | localDiv.innerHTML = 'trying to connect';
63 | // attempt to connect:
64 | client = mqtt.connect(broker, options);
65 | // set listeners:
66 | client.on('connect', onConnect);
67 | client.on('close', onDisconnect);
68 | client.on('message', onMessage);
69 | client.on('error', onError);
70 | }
71 |
72 | function loop() {
73 | // if the client is connected, publish:
74 | if (client.connected && publishing) {
75 | // make a message with a random number from 0-255
76 | let thisMessage = Math.floor(Math.random() * 255).toString();
77 | // publish to broker:
78 | client.publish(topic, thisMessage);
79 | // update localDiv text:
80 | localDiv.innerHTML = 'published to broker.'
81 | }
82 | }
83 |
84 | // changes the status of the publishing variable
85 | // on a click of the publishStatus button:
86 | function changeSendStatus(target) {
87 | // change the publishing status:
88 | publishing = !publishing;
89 | // set the html of the button accordingly:
90 | if (publishing) {
91 | target.innerHTML = 'stop publishing';
92 | } else {
93 | target.innerHTML = 'start publishing';
94 | }
95 | }
96 |
97 | // handler for mqtt connect event:
98 | function onConnect() {
99 | // update localDiv text:
100 | localDiv.innerHTML = 'connected to broker. Subscribing...'
101 | // subscribe to the topic:
102 | client.subscribe(topic, onSubscribe);
103 | }
104 |
105 | // handler for mqtt disconnect event:
106 | function onDisconnect() {
107 | // update localDiv text:
108 | localDiv.innerHTML = 'disconnected from broker.'
109 | }
110 |
111 | // handler for mqtt error event:
112 | function onError(error) {
113 | // update localDiv text:
114 | localDiv.innerHTML = error;
115 | }
116 |
117 | // handler for mqtt subscribe event:
118 | function onSubscribe(response, error) {
119 | if (!error) {
120 | // update localDiv text:
121 | localDiv.innerHTML = 'Subscribed to broker.';
122 | } else {
123 | // update localDiv text with the error:
124 | localDiv.innerHTML = error;
125 | }
126 | }
127 |
128 | // handler for mqtt message received event:
129 | function onMessage(topic, payload, packet) {
130 | let result = 'received a message on topic: ' + topic;
131 | // message is a Buffer, so convert to a string:
132 | result += ' message payload: ' + payload.toString();
133 | // packet is a JSON object, so list its elements:
134 | result += ' MQTT packet:
';
135 | for (let item in packet) {
136 | result += '
' + item + ': ' + packet[item] + '
';
137 | }
138 | // close the ul tag
139 | result += '
';
140 | // update the remote div text:
141 | remoteDiv.innerHTML = result;
142 | }
143 |
144 | // on page load, call the setup function:
145 | document.addEventListener('DOMContentLoaded', setup);
146 | // run a loop every 2 seconds:
147 | setInterval(loop, 2000);
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqttjs-p5js-mousepressed-client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqttjs-p5js-mousepressed-client/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | p5.js MQTT Client example
3 | This example uses p5.js: https://p5js.org/
4 | and the mqtt.js client library: https://www.npmjs.com/package/mqtt
5 | to create an MQTT client that sends and receives MQTT messages.
6 | The client is set up for use on the shiftr.io test MQTT broker,
7 | but other options listed will work.
8 |
9 | created 12 June 2020
10 | modified 19 Feb 2025
11 | by Tom Igoe
12 | */
13 |
14 | // All these brokers work with this code.
15 | // Uncomment the one you want to use.
16 |
17 | ////// emqx. Works in both basic WS and TLS WS:
18 | // const broker = 'wss://broker.emqx.io:8084/mqtt'
19 | // const broker = 'ws://broker.emqx.io:8083/mqtt'
20 |
21 | //////// shiftr.io desktop client.
22 | // Fill in your desktop IP address for localhost:
23 | // const broker = 'ws://localhost:1884';
24 |
25 | //////// shiftr.io, requires username and password
26 | // (see options variable below):
27 | const broker = 'wss://public.cloud.shiftr.io';
28 |
29 | //////// test.mosquitto.org, uses no username and password:
30 | // const broker = 'wss://test.mosquitto.org:8081';
31 |
32 | // MQTT client:
33 | let client;
34 | // connection options:
35 | let options = {
36 | // Clean session
37 | clean: true,
38 | // connect timeout in ms:
39 | connectTimeout: 10000,
40 | // Authentication
41 | // add a random number for a unique client ID:
42 | clientId: 'mqttJsClient-' + Math.floor(Math.random()*1000000) ,
43 | // add these in for public.cloud.shiftr.io:
44 | username: 'public',
45 | password: 'public'
46 | }
47 |
48 |
49 | // topic to subscribe to when you connect:
50 | let topic = 'monkey';
51 | // divs to show messages:
52 | let localDiv, remoteDiv;
53 |
54 | // position of the circle
55 | let xPos, yPos;
56 |
57 | function setup() {
58 | createCanvas(400, 400);
59 | // Create an MQTT client:
60 | // attempt to connect:
61 | client = mqtt.connect(broker, options);
62 | // set listeners:
63 | client.on('connect', onConnect);
64 | client.on('close', onDisconnect);
65 | client.on('message', onMessage);
66 | client.on('error', onError);
67 |
68 | // create a div for local messages:
69 | localDiv = createDiv('local messages will go here');
70 | localDiv.position(20, 50);
71 | // create a div for the response:
72 | remoteDiv = createDiv('waiting for messages');
73 | remoteDiv.position(20, 80);
74 | }
75 |
76 | function draw() {
77 | background(255);
78 | noStroke();
79 | // draw a circle when a message is received:
80 | fill('#2398CE');
81 | // circle moves with the message:
82 | circle(xPos, yPos, 30);
83 | }
84 |
85 | function mousePressed() {
86 | sendMqttMessage(mouseX + ',' + mouseY);
87 | }
88 |
89 | // called when the client connects
90 | function onConnect() {
91 | localDiv.html('client is connected');
92 | client.subscribe(topic);
93 | }
94 | // handler for mqtt disconnect event:
95 | function onDisconnect() {
96 | // update localDiv text:
97 | localDiv.html('disconnected from broker.');
98 | }
99 |
100 | // handler for mqtt error event:
101 | function onError(error) {
102 | // update localDiv text:
103 | localDiv.html(error);
104 | }
105 |
106 | // handler for mqtt subscribe event:
107 | function onSubscribe(response, error) {
108 | if (!error) {
109 | // update localDiv text:
110 | localDiv.html('Subscribed to broker.');
111 | } else {
112 | // update localDiv text with the error:
113 | localDiv.html(error);
114 | }
115 | }
116 |
117 | // called when a message arrives
118 | function onMessage(topic, payload, packet) {
119 | let message = payload.toString();
120 | remoteDiv.html('I got a message:' + message);
121 | // assume the message is two numbers, mouseX and mouseY.
122 | // Split it into an array:
123 | let values = message.split(',');
124 | // convert the array values into numbers:
125 | xPos = Number(values[0]);
126 | yPos = Number(values[1]);
127 | }
128 |
129 | // called when you want to send a message:
130 | function sendMqttMessage(msg) {
131 | // if the client is connected to the MQTT broker:
132 | if (client.connected) {
133 | client.publish(topic, msg);
134 | // update localDiv text
135 | localDiv.html('I sent: ' + msg);
136 | }
137 | }
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqttjsHueLightControl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | public
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/browser-clients/mqttjs/mqttjsHueLightControl/sketch.js:
--------------------------------------------------------------------------------
1 | /*
2 | Hue Hub light control over MQTT
3 |
4 | This example will change the brightness of a light
5 | on a local hub when you change the slider, and will
6 | send an MQTT message with the value of the slider
7 | when you press the button. If it receives an MQTT message
8 | on the `lights` topic, it uses that value to change the
9 | brightness of the light. So you can use this
10 | to change the brightness of a local hub, or of a
11 | friend's hub on a remote network if you are both connected
12 | to the same broker.
13 |
14 | created 23 July 2020
15 | modified 18 Feb 2025
16 | by Tom Igoe
17 | */
18 | // Fill in your hue hub IP credentials here:
19 | let url = '192.168.0.8';
20 | let username = 'xxxxxxxx-xxxxxxxxx';
21 | // slider for dimming the lights:
22 | let dimmer;
23 | // the number of the light in the hub:
24 | let lightNumber = 3;
25 | // The light state:
26 | let lightState = {
27 | bri: 0,
28 | on: false
29 | }
30 |
31 | // All these brokers work with this code.
32 | // Uncomment the one you want to use.
33 |
34 | ////// emqx. Works in both basic WS and TLS WS:
35 | // const broker = 'wss://broker.emqx.io:8084/mqtt'
36 | // const broker = 'ws://broker.emqx.io:8083/mqtt'
37 |
38 | //////// shiftr.io desktop client.
39 | // Fill in your desktop IP address for localhost:
40 | // const broker = 'ws://localhost:1884';
41 |
42 | //////// shiftr.io, requires username and password
43 | // (see options variable below):
44 | const broker = 'wss://public.cloud.shiftr.io';
45 |
46 | //////// test.mosquitto.org, uses no username and password:
47 | // const broker = 'wss://test.mosquitto.org:8081';
48 |
49 | // MQTT client:
50 | let client;
51 | // client credentials:
52 | let clientID = 'p5HueClient';
53 |
54 | let options = {
55 | // Clean session
56 | clean: true,
57 | // connect timeout in ms:
58 | connectTimeout: 10000,
59 | // Authentication
60 | // add a random number for a unique client ID:
61 | clientId: 'mqttJsClient-' + Math.floor(Math.random()*1000000) ,
62 | // add these in for public.cloud.shiftr.io:
63 | username: 'public',
64 | password: 'public'
65 | }
66 |
67 | // topic to subscribe to when you connect to the broker:
68 | let topic = 'lights';
69 |
70 | // UI elements:
71 | // a pushbutton to send messages:
72 | let sendButton;
73 | // divs for text from the broker:
74 | let localDiv;
75 | let remoteDiv;
76 |
77 | function setup() {
78 | noLoop();
79 | // createCanvas(windowWidth, windowHeight);
80 | // a div for the Hue hub's responses:
81 | remoteDiv = createDiv('Hub response');
82 | // position it:
83 | remoteDiv.position(20, 130);
84 | // a slider to dim one light:
85 | dimmer = createSlider(0, 254, 127)
86 | // position it:
87 | dimmer.position(10, 10);
88 | // set a behavior for it:
89 | dimmer.mouseReleased(changeBrightness);
90 |
91 | // attempt to connect:
92 | client = mqtt.connect(broker, options);
93 | // set listeners:
94 | client.on('connect', onConnect);
95 | client.on('close', onDisconnect);
96 | client.on('message', onMessage);
97 | client.on('error', onError);
98 |
99 | // create the send button:
100 | sendButton = createButton('send a message');
101 | sendButton.position(20, 40);
102 | sendButton.mousePressed(sendMqttMessage);
103 | // create a div for local messages:
104 | localDiv = createDiv('local messages will go here');
105 | localDiv.position(20, 70);
106 | // create a div for the response:
107 | remoteDiv = createDiv('waiting for messages');
108 | remoteDiv.position(20, 100);
109 | hueConnect();
110 | }
111 |
112 | /*
113 | this function makes the HTTP GET call to get the light data:
114 | HTTP GET http://your.hue.hub.address/api/username/lights/
115 | */
116 | function hueConnect() {
117 | url = "http://" + url + '/api/' + username + '/lights/';
118 | httpDo(url, 'GET', getLights);
119 | }
120 |
121 | /*
122 | this function uses the response from the hub
123 | to create a new div for the UI elements
124 | */
125 | function getLights(result) {
126 | remoteDiv.html(result);
127 | }
128 |
129 | function changeBrightness() {
130 | lightState.bri = dimmer.value();
131 | if (lightState.bri > 0) {
132 | lightState.on = true;
133 | } else {
134 | lightState.on = false;
135 | }
136 | // make the HTTP call with the JSON object:
137 | setLight(lightNumber, lightState);
138 | }
139 |
140 | /*
141 | this function makes an HTTP PUT call to change the properties of the lights:
142 | HTTP PUT http://your.hue.hub.address/api/username/lights/lightNumber/state/
143 | and the body has the light state:
144 | {
145 | on: true/false,
146 | bri: brightness
147 | }
148 | */
149 | function setLight(whichLight, data) {
150 | var path = url + whichLight + '/state/';
151 |
152 | var content = JSON.stringify(data); // convert JSON obj to string
153 | httpDo(path, 'PUT', content, 'text', getLights); //HTTP PUT the change
154 | }
155 |
156 | // called when the client connects
157 | function onConnect() {
158 | localDiv.html('client is connected');
159 | client.subscribe(topic);
160 | }
161 |
162 | // called when the client loses its connection
163 | function onDisconnect(response) {
164 | if (response.errorCode !== 0) {
165 | localDiv.html('onDisconnect:' + response.errorMessage);
166 | }
167 | }
168 |
169 | // handler for mqtt error event:
170 | function onError(error) {
171 | // update localDiv text:
172 | localDiv.html("error: " + error);
173 | }
174 |
175 | // called when a message arrives
176 | function onMessage(topic, payload, packet) {
177 | remoteDiv.html('I got a message:' + payload);
178 | let incomingNumber = parseInt(payload);
179 | // use it to set the light:
180 | lightState.bri = incomingNumber;
181 | if (lightState.bri > 0) {
182 | lightState.on = true;
183 | } else {
184 | lightState.on = false;
185 | }
186 | // make the HTTP call with the JSON object:
187 | setLight(lightNumber, lightState);
188 | }
189 |
190 | // called when you want to send a message:
191 | function sendMqttMessage() {
192 | // if the client is connected to the MQTT broker:
193 | if (client.isConnected()) {
194 | // make a string with a random number form 0 to 15:
195 | let msg = String(dimmer.value());
196 | // start an MQTT message:
197 | message = new Paho.MQTT.Message(msg);
198 | // choose the destination topic:
199 | message.destinationName = topic;
200 | // send it:
201 | client.send(message);
202 | // print what you sent:
203 | localDiv.html('I sent: ' + message.payloadString);
204 | }
205 | }
--------------------------------------------------------------------------------
/browser-clients/mqttjs/readme.md:
--------------------------------------------------------------------------------
1 | # mqtt.js Browser Client Examples
2 |
3 | These examples are based on the [mqtt.js](https://github.com/mqttjs/MQTT.js) client library.
4 |
5 | ## mqttjs-client-simple
6 | * [See the example running](mqttjs-client-simple)
7 | * [See the source code]({{site.codeurl}}/browser-clients/mqttjs/mqttjs-client-simple)
8 |
9 | This is a bare minimum client example for mqtt.js. On document load, the script for this page gets two divs from the HTML document for local and remote messages.Then it attempts to connect to the broker. Once it does, it sends the local time if it's connected every two seconds. The publish button allows you to turn on and off publishing status, in case you're testing with a second client that's sending to the same topic.
10 |
11 | The [ArduinoMqttClient example]({{site.codeurl}}/arduino-clients/ArduinoMqttClient) uses the same topic and sends the same range of numeric values if you want to test against another client.
12 |
13 | ## mqttjs-p5js-mousepressed-client
14 | * [See the example running](mqttjs-p5js-mousepressed-client)
15 | * [See the source code]({{site.codeurl}}/browser-clients/mqttjs/mqttjs-p5js-mousepressed-client)
16 |
17 | This example uses [p5.js](https://p5js.org/) and the [mqtt.js client library](https://www.npmjs.com/package/mqtt) to create an MQTT client that sends and receives MQTT messages. The client is set up for use on the [shiftr.io](https://www.shiftr.io/try/) test MQTT broker, but other options listed will work.
18 |
19 | ## mqtt-midi-controller
20 | * [See the example running](mqtt-midi-controller)
21 | * [See the source code]({{site.codeurl}}/browser-clients/mqttjs/mqtt-midi-controller)
22 |
23 | This example uses the [mqtt.js library](https://www.npmjs.com/package/mqtt) and the [Web MIDI API](https://www.w3.org/TR/webmidi/) to create an MQTT client that sends and receives MQTT messages that are MIDI messages. You can use keyboard input as well, as shown in the HTML.
24 | The client is set up for use on the [shiftr.io test MQTT broker](https://www.shiftr.io/try/), but has also been tested on other brokers.
25 |
26 | This [Arduino MQTT-to-MIDI Player Client]({{site.codeurl}}/arduino-clients/MqttClientMIDIPlayer/MqttClientMIDIPlayer.ino) can receive MIDI messages from the same broker and send MIDI to your operating system or MIDI system. This [Arduino MIDI-to-MQTT Controller Client]({{site.codeurl}}/arduino-clients/MqttClientMIDIController/MqttClientMIDIController.ino) can send noteon and noteoff messages via MQTT at the push of a button.
27 |
28 | ## mqttjsHueLightControl
29 | * [See the example running](mqttjsHueLightControl)
30 | * [See the source code]({{site.codeurl}}/browser-clients/mqttjs/mqttjsHueLightControl)
31 |
32 | This example will change the brightness of a light on a local [Philips Hue Hub](https://tigoe.github.io/hue-control/) when you change the slider, and will send an MQTT message with the value of the slider when you press the button. If it receives an MQTT message on the `lights` topic, it uses that value to change the brightness of the light. So you can use this to change the brightness of a local hub, or of a friend's hub on a remote network if you are both connected to the same broker.
--------------------------------------------------------------------------------
/img/NanoLedPushbutton.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigoe/mqtt-examples/67298ab78163ff2168fb6688a99cf08a1c403bf5/img/NanoLedPushbutton.fzz
--------------------------------------------------------------------------------
/img/NanoLedPushbutton_bb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigoe/mqtt-examples/67298ab78163ff2168fb6688a99cf08a1c403bf5/img/NanoLedPushbutton_bb.png
--------------------------------------------------------------------------------
/img/NanoLedPushbutton_schem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigoe/mqtt-examples/67298ab78163ff2168fb6688a99cf08a1c403bf5/img/NanoLedPushbutton_schem.png
--------------------------------------------------------------------------------
/img/light-broker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigoe/mqtt-examples/67298ab78163ff2168fb6688a99cf08a1c403bf5/img/light-broker.png
--------------------------------------------------------------------------------
/img/web-midi-mqtt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
85 |
--------------------------------------------------------------------------------
/mqtt-vs-websockets.md:
--------------------------------------------------------------------------------
1 | # MQTT vs WebSockets
2 |
3 | At first glance, MQTT might look a bit like WebSockets. In both cases, once the connection is established, you can send anything you want between client and server. Traffic is full duplex, meaning that both client and server are listening and speaking at the same time. However, there are some differences. Overall, MQTT is a lighter weight protocol, and is message-based as opposed to session-based.
4 |
5 | ## WebSockets are Session-Based
6 | The connection process between a WebSocket client and server always begins with a HTTP request from the client that looks like this:
7 |
8 | ````
9 | HTTP/1.1
10 | GET /websocket
11 | Host:
12 | Upgrade: websocket
13 | Connection: Upgrade
14 | Sec-WebSocket-Key:
15 | ````
16 |
17 | The server responds like this:
18 |
19 | ````
20 | HTTP/1.1 101 Switching Protocols
21 | Upgrade: websocket
22 | Connection: Upgrade
23 | Sec-WebSocket-Accept:
24 | ````
25 |
26 | Once the initial exchange is done, the client and server establish a socket conection. In OSI terms, this is a [session](https://en.wikipedia.org/wiki/Session_layer), meaning both sides formally opem communications, then maintain information on the state of the connection. The connection is synchronous: once the request is sent, the client has to wait for the server to respond. The server never initiates the connection, it always starts with the client.
27 |
28 | WebSockets were designed as an extension of HTTP, so the session is maintained until one side or the other explicitly closes it. WebSockets work great if you have a client that's native to HTTP (for example, a browser), but if you're making a client on a microcontroller or other memory-limited device, the extra complexity of establishing an HTTP connection to get the WebSocket can be a burden.rm
29 |
30 | ## MQTT is Message-Based
31 |
32 | MQTT, unlike WebSockets, is message- and topic-based. Client and broker don't establish a session. Instead, they continually exchanges messages. The pattern is called **publish and subscribe**. MQTT host programs are called brokers instead of servers, since they broker traffic between clients. It works like this:
33 |
34 | First, the client sends a connection message, and the broker acknowledges it.
35 |
36 | Next, the client either sends a message to a particular topic, or subcribes to a topic. In either case, the broker sends an acknowledgement.
37 |
38 | Messages can be sent at any time. Client or broker do not have to wait for the other besore sending.
39 |
40 | The broker saves the message as the topic's current value, and if other clients subscribe to the same topic, it sends them the value. If another client publishes to the topic, the value is updated, and all clients who've subscribed to the topic are updated with the latest value.
41 |
42 | Client and broker don't maintain a session, they just exchange messages. A broker doesn't save the history of a topic or who sent the latest message, it just maintains the latest message and when it was sent. It's up to the clients to save the history if they need it.
43 |
44 | ## One-to-One vs. Many-to-Many
45 |
46 | The synchronous, one-way nature of WebSockets makes them great for an ongoing one-to-one relationship between client and server, but it's a problem if you want multiple clients all communicating at the same time. Similarly, the fact that every exchange starts with an exchange of complex headers makes HTTP and WebSockets a heavier method of exchange than MQTT. MQTT is really designed for a network of sensors that come online from time to time, send an update, and then go back offline. It makes it easy for sensor devices to be ephemeral. WebSockets aren't designed for this kind of on-and-off pattern. They're great if you have a client that needs a dedicated connection to a server for a set period of time, for example a game controller, but it comes at the expense of a stricter, more formal communications protocol.
47 |
48 | ## Customized Server vs. Generic Broker
49 |
50 | There are generally two approaches to using an HTTP server: either you set it up to server static files, and organize all your files in a directory structure, or you write a dynamic server with custom RESTful API endpoints or routes. Either way, clients access your server using a specific set of routes like so:
51 |
52 | ````
53 | GET /index.html
54 | GET /images/kitty.jpg
55 | POST /sensor/245
56 | POST /motor/1/speed/100
57 | GET /readings/2020/april
58 | ````
59 |
60 | The work of managing the information is handled by the server, and by the programmer who sets up the server. Every application demands a custom data structure, and the routes to access that structure.
61 |
62 | MQTT, on the other hand, puts the work on the client. A broker doesn't limit you a particular data model, and it doesn't save any information. If a client needs a new topic, it just names it and publishes to it. As a result, you seldom need to write a custom MQTT broker program. You can use [any broker](https://tigoe.github.io/mqtt-examples/#mqtt-brokers), and make up all the topics and subtopics you want. Two clients who want to communicate through a broker have to be using the same data model, but the broker doesn't care what it is, it just publishes what you send it.
63 |
64 | For example, let's say you want to control a complex lighting system like the Philips Hue system, and a simple lighting device like an Arduino with an LED attached, both from the same device client through the same broker. The common property that all these clients have is that they want to either receive a light intensity reading, or publish to one. What they do with that reading is up to them. Figure 1 shows what that might look like via MQTT:
65 |
66 | 
67 |
68 | _Figure 1. An MQTT broker managing the conversation between a microcontroller dimmer, a microcontroller lamp, a browser-based light controller, and a Philips Hue hub. The one thing they have in common, the intensity of light, is the published and subscribed topic._
69 |
70 | In this case, as in most MQTT applications, the organizational work is done by the clients, not the broker. The browser-based Hue controller has to translate between MQTT and HTTP, to talk to the Hue hub. The microntroller dimmer has to translate the ADC reading obtained via `analogRead()` into an MQTT publish message. The microcontroller light has to translate the MQTT messages published on the light topic to a PWM signal via `analogWrite()` to control the LED.
71 |
72 | The advantage of this is that [any MQTT broker](https://tigoe.github.io/mqtt-examples/#mqtt-brokers) will do the job, and you probably don't have to write your own. You can use one of many existing brokers. It means you have to come up with your own data model, and write clients that can use it, and this part is similar to an HTTP application. The difference is that anything you'd want a server to save has to be written into a client that will store the data published to your topics.
--------------------------------------------------------------------------------
/node-clients/MqttNodeClient/mqtt-client.js:
--------------------------------------------------------------------------------
1 | /*
2 | Simple MQTT Node.js client.
3 | Connects to shiftr.io's public broker, and sends
4 | a message to a topic called lights every two
5 | seconds.
6 |
7 | created 10 Apr 2021
8 | by Tom Igoe
9 | */
10 |
11 | // include the MQTT library:
12 | const mqtt = require('mqtt');
13 | // the broker you plan to connect to.
14 | // transport options:
15 | // 'mqtt', 'mqtts', 'tcp', 'tls', 'ws', or 'wss':
16 | //const broker = 'mqtt://test.mosquitto.org';
17 | const broker = 'mqtt://public.cloud.shiftr.io';
18 |
19 | // client options:
20 | const options = {
21 | // add a random number for a unique clientId:
22 | clientId: 'nodeClient-' + Math.floor(Math.random()*1000000),
23 | username: 'public',
24 | password: 'public',
25 | clean: true,
26 | connectTimeout: 4000,
27 | reconnectPeriod: 1000
28 | }
29 | // topic and message payload:
30 | let myTopic = 'aardvarks';
31 | let payload;
32 |
33 | // connect handler:
34 | function setupClient() {
35 | console.log('setup');
36 | client.subscribe(myTopic);
37 | client.on('message', readMqttMessage);
38 | }
39 |
40 | // new message handler:
41 | function readMqttMessage(topic, message) {
42 | // message is a Buffer, so convert to a string:
43 | let msgString = message.toString();
44 | console.log(topic);
45 | console.log(msgString);
46 | }
47 |
48 | // message sender:
49 | function sendMqttMessage(topic, msg) {
50 | if (client.connected) {
51 | let msgString = JSON.stringify(msg);
52 | client.publish(topic, msgString);
53 | console.log('update');
54 | }
55 | }
56 |
57 | // setInterval handler:
58 | function update() {
59 | payload = Math.round(Math.random(254) * 254);
60 | sendMqttMessage(myTopic, payload);
61 | }
62 |
63 | // make a client and connect:
64 | let client = mqtt.connect(broker, options);
65 | client.on('connect', setupClient);
66 |
67 | // // send a message every two seconds:
68 | setInterval(update, 100);
--------------------------------------------------------------------------------
/node-clients/MqttNodeClient/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "mqtt": "^1.14.0"
4 | },
5 | "name": "mqtt-node-client",
6 | "version": "0.0.2",
7 | "description": "a simple node mqtt client",
8 | "main": "mqtt-client.js",
9 | "devDependencies": {},
10 | "scripts": {
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/tigoe/mqtt-examples.git"
16 | },
17 | "keywords": [
18 | "mqtt"
19 | ],
20 | "author": "Tom Igoe",
21 | "license": "ISC",
22 | "bugs": {
23 | "url": "https://github.com/tigoe/mqtt-examples/issues"
24 | },
25 | "homepage": "https://github.com/tigoe/mqtt-examples#readme"
26 | }
27 |
--------------------------------------------------------------------------------
/node-clients/MqttNodeClientFileWriter/client.js:
--------------------------------------------------------------------------------
1 | /*
2 | MQTT Node.js client writes to filesystem.
3 | Connects to a broker, subscribes to a broad range of topics,
4 | and writes any messages received to a local file called
5 | data.json
6 |
7 | created 10 Apr 2021
8 | modified 3 Nov 2024
9 | by Tom Igoe
10 | */
11 |
12 | // include the libraries:
13 | const mqtt = require('mqtt');
14 | const fs = require('fs');
15 |
16 | // All these brokers work with this code.
17 | // Uncomment the one you want to use.
18 |
19 | ////// emqx. Works in both basic WS and TLS WS:
20 | // const broker = 'wss://broker.emqx.io:8084/mqtt'
21 | // const broker = 'ws://broker.emqx.io:8083/mqtt'
22 |
23 | //////// shiftr.io desktop client.
24 | // Fill in your desktop IP address for localhost:
25 | // const broker = 'ws://localhost:1884';
26 |
27 | //////// shiftr.io, using username and password
28 | // (see options variable below):
29 | // const broker = 'wss://public.cloud.shiftr.io';
30 |
31 | //////// test.mosquitto.org, uses no username and password:
32 | // const broker = 'wss://test.mosquitto.org:8081';
33 |
34 | // or use your own:
35 | const broker = 'mqtt://mysite.com';
36 |
37 | // the path to the data file:
38 | let filePath = __dirname + '/data.json';
39 |
40 | // client options:
41 | const options = {
42 | // add the current epoch time for a unique clientId:
43 | clientId: 'nodeClient-' + Date.now(),
44 | username: 'user',
45 | password: 'password!',
46 | clean: true,
47 | connectTimeout: 4000,
48 | reconnectPeriod: 1000
49 | }
50 | // topic:
51 | let myTopic = '#';
52 |
53 | // connect handler:
54 | function setupClient() {
55 | console.log('client connected');
56 | client.subscribe(myTopic);
57 | }
58 |
59 | // new message handler:
60 | function readMqttMessage(topic, message, packet) {
61 | // // make a timestamp string:
62 | let now = new Date();
63 | // create a new record from the topic and subtopics:
64 | let record = {};
65 | let subTopics = topic.split('/');
66 | // assume first subTopic is the creator name:
67 | record.creator = subTopics[0];
68 | // if there's a second subTopic, assume that's the data label:
69 | let dataLabel = subTopics[1];
70 | // if it's empty, use the label 'data':
71 | if (!dataLabel) dataLabel = 'data';
72 | // make a timestamp:
73 | record.timeStamp = now.toISOString();
74 |
75 | // see if the message parses as valid JSON:
76 | try {
77 | let data = JSON.parse(message.toString());
78 | // if it parses, it's JSON or a valid number or array.
79 | // if it's not, just put it in the data category as is:
80 | if (typeof data != 'object') {
81 | record[dataLabel] = data;
82 | } else {
83 | // if JSON, Extract the object properties
84 | // and put each in the record as its own property:
85 | for (i in data) {
86 | record[i] = data[i];
87 | }
88 | }
89 | } catch (err) {
90 | // if it fails parsing, just put the string in the dataLabel property:
91 | record[dataLabel] = message.toString();
92 | }
93 | // save to the file:
94 | saveData(record);
95 | }
96 |
97 |
98 | function saveData(data) {
99 | // this function is called by the writeFile and appendFile functions
100 | // below:
101 | function fileWriteResponse() {
102 | console.log("wrote to file at: " + data.timeStamp);
103 | }
104 | /*
105 | write to the file asynchronously. The third parameter of
106 | writeFile is the callback function that's called when
107 | you've had a successful write.
108 | */
109 | fs.exists(filePath, function (exists) {
110 | if (exists) {
111 | fs.appendFile(filePath, JSON.stringify(data) + '\n', fileWriteResponse);
112 | } else {
113 | fs.writeFile(filePath, JSON.stringify(data) + '\n', fileWriteResponse);
114 | }
115 | });
116 | }
117 |
118 | // make a client and connect:
119 | let client = mqtt.connect(broker, options);
120 | client.on('connect', setupClient);
121 | client.on('message', readMqttMessage);
--------------------------------------------------------------------------------
/node-clients/MqttNodeClientFileWriter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mqttnodeclientfilewriter",
3 | "version": "0.0.3",
4 | "description": "A node mqtt client that writes to the filesystem",
5 | "main": "client.js",
6 | "dependencies": {
7 | "mqtt": "^4.3.7"
8 | },
9 | "devDependencies": {},
10 | "scripts": {
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "keywords": [
14 | "mqtt"
15 | ],
16 | "author": "Tom Igoe",
17 | "license": "ISC"
18 | }
19 |
--------------------------------------------------------------------------------
/node-clients/MqttNodeClientSerial/SerialInOut/SerialInOut.ino:
--------------------------------------------------------------------------------
1 | int lastSensorReading = 0;
2 | int threshold = 5;
3 |
4 | void setup() {
5 | // open serial port and set timeout for reading to 10ms:
6 | Serial.begin(9600);
7 | Serial.setTimeout(10);
8 | // init pin 9 as output:
9 | pinMode(9, OUTPUT);
10 | }
11 |
12 | void loop() {
13 | // read a sensor, get a range from 0-255:
14 | int sensor = analogRead(A0) / 4;
15 |
16 | // if it's changed enough, send it:
17 | if (abs(sensor - lastSensorReading) > threshold) {
18 | Serial.println(sensor);
19 | }
20 | // if there's serial to be read, read and parse
21 | // for an integer:
22 | if (Serial.available() > 0) {
23 | int intensity = Serial.parseInt();
24 | // if the result is > 0,
25 | // set the LED on pin 9 with it:
26 | if (intensity > 0) {
27 | analogWrite(9, intensity);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/node-clients/MqttNodeClientSerial/mqtt-client-serial.js:
--------------------------------------------------------------------------------
1 | /*
2 | Simple MQTT Node.js client with serial port.
3 | Connects to shiftr.io's public broker. Reads from serial
4 | port and sends to broker; reads from broker and sends to
5 | serial port.
6 |
7 | To launch this, give the portname like so:
8 | node mqtt-client-seial.js portname
9 |
10 | Arduino sketch SerialInOut.ino works with this script.
11 |
12 | created 10 Apr 2021
13 | modified 21 Jun 2021
14 | by Tom Igoe
15 | */
16 |
17 | // include the MQTT library:
18 | const mqtt = require('mqtt');
19 | // include serialport libraries
20 | const SerialPort = require('serialport'); // include the serialport library
21 | const Readline = require('@serialport/parser-readline');
22 |
23 | // the broker you plan to connect to.
24 | // transport options:
25 | // 'mqtt', 'mqtts', 'tcp', 'tls', 'ws', or 'wss':
26 | const broker = 'mqtt://public.cloud.shiftr.io';
27 |
28 | // client options:
29 | const options = {
30 | // add a random number for a unique client ID:
31 | clientId: 'nodeClient-' + Math.floor(Math.random()*1000000),
32 | username: 'public',
33 | password: 'public',
34 | clean: true,
35 | connectTimeout: 4000,
36 | reconnectPeriod: 1000
37 | }
38 | // topic and message payload:
39 | let myTopic = 'lights';
40 | let payload;
41 |
42 | // connect handler:
43 | function setupClient() {
44 | client.subscribe(myTopic);
45 | client.on('message', readMqttMessage);
46 | }
47 |
48 | // new message handler:
49 | function readMqttMessage(topic, message) {
50 | // message is a Buffer, so convert to a string:
51 | let msgString = message.toString();
52 | console.log(topic + ': ' + msgString);
53 | // send it out the serial port:
54 | myPort.write(msgString);
55 | }
56 |
57 | // message sender:
58 | function sendMqttMessage(topic, msg) {
59 | if (client.connected) {
60 | client.publish(topic, msg);
61 | }
62 | }
63 |
64 | ///////////////////////// Serial functions
65 | // make a readline parser:
66 | const parser = new Readline({ delimiter: '\r\n' });
67 | // get the port name from the command line:
68 | var portName = process.argv[2];
69 | // serial port config:
70 | var portConfig = {
71 | baudRate: 9600,
72 | };
73 |
74 | function openPort() {
75 | console.log('port open');
76 | console.log('baud rate: ' + myPort.baudRate);
77 | }
78 |
79 | function serialEvent(data) {
80 | sendMqttMessage(myTopic, data);
81 | console.log(data);
82 | }
83 |
84 | // open the serial port:
85 | var myPort = new SerialPort(portName, portConfig);
86 | // set up a line reading parser:
87 | myPort.pipe(parser);
88 | // open the port:
89 | myPort.on('open', openPort);
90 | // set up a listener for new lines:
91 | parser.on('data', serialEvent);
92 |
93 | // make a client and connect:
94 | let client = mqtt.connect(broker, options);
95 | client.on('connect', setupClient);
--------------------------------------------------------------------------------
/node-clients/MqttNodeClientSerial/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mqtt-node-client-serial",
3 | "version": "0.0.2",
4 | "description": "An MQTT to Serialport client",
5 | "main": "mqtt-client-serial.js",
6 | "dependencies": {
7 | "mqtt": "^1.14.0",
8 | "serialport": "^9.2.0"
9 | },
10 | "scripts": {
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/tigoe/mqtt-examples.git"
16 | },
17 | "keywords": [
18 | "mqtt",
19 | "serialport"
20 | ],
21 | "author": "Tom Igoe",
22 | "license": "ISC",
23 | "bugs": {
24 | "url": "https://github.com/tigoe/mqtt-examples/issues"
25 | },
26 | "homepage": "https://github.com/tigoe/mqtt-examples#readme"
27 | }
28 |
--------------------------------------------------------------------------------
/node-clients/readme.md:
--------------------------------------------------------------------------------
1 | # Node.js Clients
2 |
3 | There are three clients built in node.js in this repository
4 | * [MqttNodeClient]({{site.codeurl}}/node-clients/MqttNodeClient/) which is a basic example of how to make a client with the [node.js MQTT library](https://www.npmjs.com/package/mqtt). It sends a reading every few seconds, and subscribes to a topic called `lights`. It will work with the light control examples above.
5 | * [MqttNodeClientSerial]({{site.codeurl}}/node-clients/MqttNodeClientSerial/) is similar, but it uses the node serialport library from [serialport.io](https://serialport.io/docs) to connect MQTT to serial in and out.
6 | * [MqttNodeClientFileWriter]({{site.codeurl}}/node-clients/MqttNodeClientFileWriter/) reads messages from a topic and writes them to a text file.
7 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # MQTT Examples
2 |
3 | **Message Queueing Telemetry Transfer**, or **[MQTT](https://mqtt.org/)**, is a lightweight IP-based messaging protocol designed for communication between sensors, controllers, and other devices. It's designed to support equipment that may not always be online, like automated devices built with microcontrollers. MQTT server programs are called **brokers**. A broker keeps track of messages from clients, and allows any client to query the last message sent by another client.
4 |
5 | Messages are organized into **topics**. Typically, a topic represents a device, with each sub-topic representing its characteristics. For example, a weather station might have the main topic "station" with subtopics "temperature", "humidity", "air quality", and so forth. The weather station itself would send messages to each of the subtopics, and a web client might subscribe to those topics to graph them onscreen over time.
6 |
7 | Clients either publish new messages to topics, or subscribe to topics, and the broker notifies them when new messages arrive. For this reason, MQTT is known as a **Publish & Subscribe**, or **PubSub** system.
8 |
9 | What's nice about MQTT, as opposed to HTTP, for example, is that it's a simple protocol, you can send anything you want in a message with whatever formatting you want, and when you subscribe to a topic, you get updates whenever a new message from a remote client arrives. So it's great for situations where two or more devices need to communicate in both directions in near real-time. It offers the convenience of web sockets, but without having to maintain a connection to the server, as all communication is message-based, not session-based.
10 |
11 | Because MQTT doesn't care what you put in each message, you can format your messages to match whatever end use you need. You text-formatted messages like comma-separate values (CSV) or JSON strings inside an MQTT message, for example, or binary messages like MIDI commands or OSC messages. The broker doesn't care what's in the message. This means that your client's job is just to send and receive messages between the broker and your end application, whatever it may be.
12 |
13 | For a more detailed explanation, see [this explanation from IBM](https://developer.ibm.com/articles/iot-mqtt-why-good-for-iot/), who developed the protocol initially.
14 |
15 | Here is a [comparison between WebSockets and MQTT](mqtt-vs-websockets.md).
16 |
17 | ## Arduino Client Libraries
18 |
19 | [ArduinoMqttClient examples in this repository](arduino-clients)
20 |
21 | There are multiple MQTT client libraries for Arduino. The examples here all use the [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient) library. This library works with all the WiFi-enabled Arduino models, and many third-party models as well.
22 |
23 | There are many other Arduino MQTT libraries. Joël Gähwiler's [arduino-mqtt](https://github.com/256dpi/arduino-mqtt) is another good example.
24 |
25 |
26 | ## JavaScript Clients
27 |
28 | For JavaScript clients, the most common library is the [mqtt.js library](https://github.com/mqttjs/MQTT.js#readme), which is written for both browsers and for node.js. There is a second library from the Eclipse foundation, the [Eclipse PAHO library](https://github.com/eclipse-paho/paho.mqtt.javascript), but it appears to be no longer supported by the foundation. They both have similar functionality, but the mqtt.js library has a bit simpler syntax, and it can be used both in the browser and in node.js scripts.
29 |
30 | **NOTE:** Both of these clients use webSockets to connect to an MQTT broker initially, because they come from the browser, and browsers, can't use MQTT as of this writing (Feb. 2025). So if you are using a local broker like mosquitto, make sure it's set up to receive connections via webSockets as well as via MQTT.
31 |
32 | * [Eclipse PAHO browser examples](browser-clients/eclipse-pahojs/)
33 | * [mqtt.js browser examples](browser-clients/mqttjs/)
34 |
35 | ## Node.js Clients
36 |
37 | There are a few clients built in node.js in this repository, using the same mqtt.js library used in some of the browser clients above
38 | * [node.js clients](node-clients)
39 |
40 | ## Processing Library
41 |
42 | There is an MQTT library for [Processing](https://github.com/256dpi/processing-mqtt) (also by Joël Gähwiler).
43 |
44 | ## Desktop and Mobile Client Apps
45 |
46 | [MQTT Explorer](http://mqtt-explorer.com/) is a desktop client that can be useful for diagnosing issues with client-to-broker communication. It's available on all major operating systems.
47 |
48 | [MQTTX](https://mqttx.app/) is a desktop client for Windows, MacOS, Linux, and Ubuntu, from EMQX.
49 |
50 | [MQTTTool](https://apps.apple.com/us/app/mqttool/id1085976398) is a mobile client for iOS.
51 |
52 | [MyMQTT](https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=en_US&gl=US&pli=1) is a good Android MQTT client app.
53 |
54 | There are multiple other desktop and command line client apps.
55 |
56 | ## MQTT Brokers
57 |
58 | There are a number of MQTT brokers you can use. The most popular is [mosquitto](http://mosquitto.org/). You can run mosquitto on your own computer or server, or you can use [test.mosquitto.org](https://test.mosquitto.org/) as a test broker.
59 |
60 | [Shiftr.io](https://shiftr.io/try) is another MQTT test broker, with a graphic interface so you can see a graph of clients and topics. Shiftr.io has a [desktop broker](https://shiftr.io/desktop) that you can download and use for local testing as well. These examples use shiftr.io as their test broker, though they have been tested on mosquitto.org as well. Note that Shiftr.io's examples use a different Arduino client library and a different JavaScript library than this site does. The code here is still compatible with that briker, however.
61 |
62 | ## MQTT, Web Sockets, and Encryption
63 |
64 | You can make an MQTT request directly, or you can do it encrypted. You can also make MQTT requests over websockets. Each transport method is typically done on a different port number.
65 |
66 | ### test.mosquitto.org Ports
67 |
68 | [test.mosquitto.org](https://test.mosquitto.org) lists the following ports:
69 |
70 | * 1883 MQTT, unencrypted, unauthenticated
71 | * 1884 MQTT, unencrypted, authenticated
72 | * 8883 MQTT, encrypted, unauthenticated
73 | * 8884 MQTT, encrypted, client certificate required
74 | * 8885 MQTT, encrypted, authenticated
75 | * 8886 MQTT, encrypted, unauthenticated
76 | * 8887 MQTT, encrypted, server certificate deliberately expired
77 | * 8080 MQTT over WebSockets, unencrypted, unauthenticated
78 | * 8081 MQTT over WebSockets, encrypted, unauthenticated
79 | * 8090 MQTT over WebSockets, unencrypted, authenticated
80 | * 8091 MQTT over WebSockets, encrypted, authenticated
81 |
82 | ### Shiftr.io Cloud Ports
83 |
84 | [Shiftr.io](https://www.shiftr.io/docs/broker/mqtt-interface/) lists the following ports:
85 | * 1883 MQTT, unencrypted port 1883
86 | * 8883: MQTT, encrypted
87 | * 443: secure WebSocket (WSS/HTTPS)
88 |
89 | ### Shiftr.io Desktop Ports
90 |
91 | * 1883 MQTT, unencrypted port 1883
92 | * 1884: WebSocket (WS/HTTP)
93 |
94 | ### EMQX Public Broker Ports
95 |
96 | [EMQX](https://www.emqx.com/en/mqtt/public-mqtt5-broker) lists the following ports:
97 |
98 | * MQTT TCP Port: 1883
99 | * WebSocket Port: 8083
100 | * MQTT SSL/TLS Port: 8883
101 | * WebSocket SSL/TLS Port: 8084
102 |
103 | Different client APIs support different approaches. For example, the ArduinoMqttClient supports both unencrypted and encrypted MQTT or MQTTS connections just by changing the port number and the WiFiClient to a WiFiSSLClient. The browser clients generally send MQTT messages over web sockets, encrypted or unencrypted. Other MQTT client frameworks use one or more of these four methods.
104 |
105 | ## Broker Client Settings
106 |
107 | Table 1 below shows the settings for each of three client tools: the ArduinoMqttClient library: mqtt.js in a browser; and eclipse.paho.js in a browser; and four different brokers: EMQX; shiftr.io cloud; shiftr.io desktop client; and test.mosquitto.org.
108 |
109 | | Broker| | ArduinoMqttClient | mqtt.js | eclipse.paho.js |
110 | | --- |--- | --- | --- | --- |
111 | | [EMQX](https://www.emqx.com/en/mqtt/public-mqtt5-broker) | | | |
112 | | | Initializer: |WiFiSSLClient | wss:// | useSSL: true in client.connect() |
113 | | | Address:| broker.emqx.io | same | same |
114 | | | Port: | 8883 | 8084| 8084|
115 | | | Credentials: | none | none | none |
116 | | [shiftr.io cloud](https://www.shiftr.io/docs/broker) | | | |
117 | | | Initializer: |WiFiSSLClient | wss:// | useSSL: true in client.connect() |
118 | | | Address:| public.cloud.shiftr.io | same | same |
119 | | | Port: | 8883 | not specified| 443|
120 | | | Credentials: | username : public, password: public | same| same|
121 | | [shiftr.io desktop](https://www.shiftr.io/docs/broker) | | | |
122 | | | Initializer: |WiFiClient | ws:// | none |
123 | | | Address:| your computer's IP address | same| same|
124 | | | Port: | 1883 | 1884 | 1884|
125 | | | Credentials: | none | none| none|
126 | | [test.mosquitto.org](https://test.mosquitto.org/) | | | |
127 | | | Initializer: |WiFiSSLClient | wss:// | useSSL: true in client.connect() |
128 | | | Address:| test.mosquitto.org | same | same |
129 | | | Port: | 8886 | 8081| 8081|
130 | | | Credentials: | none | none | none |
--------------------------------------------------------------------------------