What if we would like to publish data transmitted over RS232 Serial from an embedded Arduino device to a WebSocket browser client?
When prototyping a cable serial connection is very convenient as RF or networking modules may not yet be implemented. How do we get serial data to provision a cloud API service or web browser interface?
We can achieve this easily with Python and PySerial library:
#!/usr/bin/python
import serial
import asyncio
import datetime
import random
import websockets
ser = serial.Serial(
port='/dev/ttyUSB0',\
baudrate=115200,\
parity=serial.PARITY_NONE,\
stopbits=serial.STOPBITS_ONE,\
bytesize=serial.EIGHTBITS,\
timeout=0)
print("connected to: " + ser.portstr)
async def tx(websocket, path):
line = []
while True:
for i in ser.read():
c = chr(i)
line.append(c)
if c == '\n':
print(''.join(line))
await websocket.send(''.join(line))
line = []
break
start_server = websockets.serve(tx, "127.0.0.1", 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
ser.close()
Here is a more detailed example of reading serial port data in C language on Linux Platform –
MQTT is a lightweight messaging protocol suitable for embedded and IOT devices.
Websockets ( RFC6455 – https://tools.ietf.org/html/rfc6455 ) is socket programming for internet, an evolution of browser / web server HTTP enabling real-time bidirectional data exchange and binary messaging.
How do we interface a MQTT enabled IOT sensor device with a web browser interface displaying a real time graph chart?
Introduction to WebSockets – Real Time TCP Sockets for Internet
With modern browser engines and responsive web UI technologies built on HTML5, SVG and JavaScript frameworks, sophisticated visualisation, display and dashboard reporting capabilities have emerged.
Responsive Web UI runs in any browser installed device – laptop, dekstop, tablet or mobile, without need to install additional software or prepare application code for specific device architectures.
HTTP browser clients essentially implement a polling request/response technique for retrieving and updating HTML format webpages.
Due to need to establish a connection for each new request, HTTP is not well suited to real time or high volume messaging, charting or visualisation applications.
Although AJAX (asynchronous JavaScipt XML) and REST, SOAP API programming overcome this to a certain extent these methods are relatively inefficient for some use cases due to protocol overhead.
With Websockets, TCP network socket programming becomes possible in a browser client application.
Clients can establish a network socket connection, this channel remains open and two-way data exchange including binary messaging formats takes place.
Sockets are well established in UNIX and Windows OS client/server programming, but are relatively new to the web.
Arduino ESP32 Barometer Sensor MQTT Device
An environmental sensor based on an Expressif ESP32 micro-controller and BMP280 Bosch sensor reads air pressure, temperature and altitude –
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp;
void setup() {
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
/* Default settings from datasheet. */
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
}
void loop() {
Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure()/100); //displaying the Pressure in hPa, you can change the unit
Serial.println(" hPa");
Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1019.66)); //The "1019.66" is the pressure(hPa) at sea level in day in your region
Serial.println(" m"); //If you don't know it, modify it until you get your current altitude
display.clearDisplay();
float t = bmp.readTemperature(); //Read temperature in C
float p = bmp.readPressure()/100; //Read Pressure in Pa and conversion to hPa
float a = bmp.readAltitude(1019.66); //Calculating the Altitude, the "1019.66" is the pressure in (hPa) at sea level at day in your region
delay(2000);
}
Data is communicated over Wifi to an MQTT messaging server.
On server we require a relay to subscribe for MQTT messages on sensor device channel, establish a WebSocket and write data to connected browser clients.
An implementation in NodeJS requires WS, MQTT and events libraries:
// setup Websocket Server
const WebSocket = require('ws');
var ws_host = "192.168.1.127";
var ws_port = "8080";
const wss = new WebSocket.Server({ host: ws_host, port: ws_port });
var ws = null;
// Setup MQTT Client
// mqtt[s]://[username][:password]@host.domain[:port]
var mqtt = require('mqtt'), url = require('url');
var mqtt_url = url.parse(process.env.MQTT_URL || 'mqtt://192.168.1.127:1883');
var auth = (mqtt_url.auth || ':').split(':');
var url = "mqtt://" + mqtt_url.host;
var mqtt_channel_in = "esp8266.in";
var mqtt_channel_out = "esp8266.out";
var options = {
port: mqtt_url.port,
clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
username: 'mqtt',
password: '__mqtt_password__',
keepalive: 60,
reconnectPeriod: 1000,
protocolId: 'MQIsdp',
protocolVersion: 3,
clean: true,
encoding: 'utf8'
};
NodeJS is event based, when an MQTT message is received it can be forwarded to all connected WebSocket clients:
mqttClient.on('message', function sendMsg(topic, message, packet) {
console.log(topic + ": " + message);
var eventListeners = require('events').EventEmitter.listenerCount(mqttClient,'message');
console.log(eventListeners + " Listner(s) listening to mqttClient message event");
console.log(mqttClient.rawListeners('message'));
wss.clients.forEach(function each(ws) {
if (ws.isAlive === false) return ws.terminate();
console.log(data);
ws.send(data+" ");
});
});
MQTT allows many subscribers to receive topic messages.
Python Eclipse Paho MQTT client with Mongo DB
A client based on Eclipse Paho ( https://www.eclipse.org/paho/ ) developed in Python might add persistence by writing to a Mongo DB datastore:
### Python MQTT client
### Subscribes to an MQTT topic receiving JSON format messages in format:
### [{"ts":1586815920,"temp":22.3,"pressure":102583,"alt":76}]
###
### Writes receieved JSON data to a mongo DB collection
###
import paho.mqtt.client as mqtt
import json
import pymongo
mqtt_server = "192.168.1.127"
mqtt_port = 1883
mqtt_keepalive = 60
mqtt_channel_out = "esp8266.out"
mqtt_channel_in = "esp8266.in"
mongo_server = "mongodb://localhost:27017/"
mongo_db = "weather"
mongo_collection = "sensorData"
def on_connect(client,userdata,flags,rc):
print("Connected with result code:"+str(rc))
print ("MQTT server: "+mqtt_server+", port: "+str(mqtt_port));
print ("MQTT topic: "+mqtt_channel_out);
client.subscribe(mqtt_channel_out)
def on_message(client, userdata, msg):
print(msg.payload)
parsed_json = (json.loads(msg.payload))
res = sensorData.insert_one(parsed_json[0])
mongoClient = pymongo.MongoClient(mongo_server)
mydb = mongoClient[mongo_db]
sensorData = mydb[mongo_collection]
mqttClient = mqtt.Client()
mqttClient.connect(mqtt_server,mqtt_port,mqtt_keepalive);
mqttClient.on_connect = on_connect
mqttClient.on_message = on_message
mqttClient.loop_forever()
Web Browser Client – D3.js WebSocket Real Time Chart
MQTT (Message Queue Telemetry Transport) is a messaging wire communications protocol for machine to machine (M2M) and software component integration.
Use cases:
Sensors / IOT devices
Robotics, Industrial Monitoring & Remote Control
Automation – Smart Home
Mobile, Web Browser UI clients, Cloud Services
Integration – local & long range communication between software & services
In contrast to world wide web, where browsers pull web pages from internet servers (request/response), MQTT implements a Publish / Subscribe (PubSub) and a push messaging model.
Common with HTTP at transport OSI network layer MQTT extends TCP/IP.
MQTT clients connect and transmit to brokers (servers), who register subscribers to named topics (channels).
Message data payload can contain arbitrary binary or UTF-8 Unicode encoded text data (up to 256 MB per message).
Internet of Things (IOT) devices deploy MQTT as a lightweight email (SMTP) like solution for data exchange suitable for integrating software, sensors, devices and cloud services.
An OASIS standard currently at version 5x ( http://mqtt.org/ ) defines capabilities including:
Distributed, bi-directional message flows
Quality of Service (QOS) delivery levels: at least once, only once, guaranteed message order
Browser client integration with WebSockets (RFC 6455)
Lets take a closer look at Mosquitto ( https://mosquitto.org/ ) an open source MQTT broker implementation sponsored by Apache Software Foundation .
Eclipse Mosquitto
Eclipse Mosquitto is an open source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. Mosquitto is lightweight and is suitable for use on all devices
Mosquitto MQTT Setup under Linux Ubuntu
Mosquitto can be installed on Ubuntu with package manager:
sudo /etc/init.d/mosquitto restart
[ ok ] Restarting mosquitto (via systemctl): mosquitto.service.
1594324669: Config loaded from /etc/mosquitto/mosquitto.conf.
1594324669: Opening ipv6 listen socket on port 1883.
1594324669: Opening ipv4 listen socket on port 1883.
1594324669: Opening ipv4 listen socket on port 8883.
1594331039: mosquitto version 1.6.10 starting
Mosquitto Password Authentication
Mosquitto user/password authentication can be required on a per listener basis.
Add broker authentication per listener in default.conf
sudo cat /var/log/mosquitto/mosquitto.lo
1596376328: mosquitto version 1.6.10 starting
1596376328: Config loaded from /etc/mosquitto/mosquitto.conf.
1596376328: Opening ipv6 listen socket on port 1883.
1596376328: Opening ipv4 listen socket on port 1883.
1596376328: Opening ipv4 listen socket on port 8883.
Testing SSL connection with openSSL client
# use openssl client to test connection
sudo openssl s_client -connect mqtt.steveio.com:8883 -CAfile /etc/mosquitto/ca_certificates/ca.crt
A feature within MQTT specification is store / forward, enabling message delivery to offline or clients connecting only on a scheduled basis. Normally, messages are delivered immediately to all topic subscribers. When clients setup a persistent session, messages with QOS level 1 or 2 are queued for delivery in the event they are offline.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
We do not use cookies of this type.
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
We do not use cookies of this type.
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
We do not use cookies of this type.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
We do not use cookies of this type.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
We do not use cookies of this type.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.