The WebSocket protocol (www.websocket.org) allows a two-way real-time conversation between the web server and client, through a standardized connection to allow both the server and the client to send data at any time. The client sends a request to the server to switch from an HTTP protocol to a WebSocket protocol; and if the server can host the WebSocket protocol, the HTTP connection is replaced with a WebSocket connection, but using the same port as HTTP.
The WebSocketsServer library, listed under WebSockets, by Markus Sattler is available in the Arduino IDE. The WebSocket is connected on port 81, as the default HTTP COM port is 80, and the wsEvent function displays the received message from the client. Listing 9-1 contains the sketch for the transmit and receive text example. The Serial.write() instruction converts ASCII code for an alphanumeric character to display the alphanumeric character, while Serial.print() displays the ASCII (American Standard Code for Information Interchange) code. The loop function in Listing 9-1 still includes the server.handleClient() instruction to manage HTTP requests, but when text is transmitted by the server to the client, the instruction websocket.broadcastTXT(str.c_str(), str.length()) sends the content of the Serial buffer to the client. The text string is converted to a C-style, null-terminated string with the instruction string.c_str(). The base function sends the default web page AJAX code to the client, when the web page is initially loaded.
WebSocket main sketch
Implementation of the WebSocket protocol is contained in the JavaScript section of Listing 9-2, which includes the web page AJAX code. When the web page is loaded, a table with headers is created to display the received and transmitted text, and the init function is called to open the WebSocket connection at ws://web server IP address:81/. When the client transmits a message to the server, the instruction send(document.getElementById('txText').value) in the sendText function sends the content of the variable txText, which is then cleared. When the client receives a message from the server, the message content is stored in the variable rxText, which is displayed on the web page.
WebSocket web page AJAX code
Remote control and WebSocket communication
Height and distance measurement with ESP8266 and ESP32 microcontrollers
Component | Connect to | And to |
---|---|---|
Ultrasonic distance sensor VCC | VCC rail | |
Ultrasonic distance sensor TRIG | ESP8266 D8 or ESP32 GPIO 13 | |
Ultrasonic distance sensor ECHO | ESP8266 D7 or ESP32 GPIO 27 | |
Ultrasonic distance sensor GND | GND rail | |
Laser module S | ESP8266 D6 or ESP32 GPIO 26 | |
Laser module - | GND rail | |
Servo motor signal (orange or white) | ESP8266 D5 or ESP32 GPIO 25 | |
Servo motor (red) | VCC rail | |
Servo motor (brown or black) | GND rail | |
ESP8266 or ESP32 GND | GND rail | |
L4940V5 supply | 9 V battery positive | 100 nF capacitor positive |
L4940V5 GND | GND rail | |
L4940V5 demand | VCC rail | 22 μF capacitor positive |
9 V battery negative | GND rail | |
100 nF capacitor negative | GND rail | |
22 μF capacitor negative | GND rail |
The square wave frequency, F, is included in the instruction servoFB.setPeriodHertz(F), which is generally 50 Hz. In the servoFB.attach(FBpin, min, max) instruction, the min and max parameters refer to the pulse width, in microseconds, of a square wave to move the servo motor to 0° and 180°, respectively. Default values for the min and max parameters are 1000 μs and 2000 μs, with values of 500 μs and 2500 μs for the Tower Pro SG90 servo.
Height and distance measurement
WebSocket and AJAX
which sets autocomplete to on with the slider initial position set at value, as setting autocomplete to off positions the slider in the default middle position. The instruction associates the slider with the sendFB function, which is called when the slider is moved. The third table row displays the calculated height and measured distance.
When the web page is loaded, the init function is called to open the WebSocket connection at ws://web server IP address:81/. When the client receives a message, the message content is stored in the variable rx.data, which is parsed to the variables vertical and horizontal for display on the web page. A message is transmitted by the client with the sendFB function, which combines the angle selected by the slider with the laser state. When the Change laser button is clicked, the changeLaser function is called, which changes the value of the laser state, laserVal, updates the laser state in the web page code, and alternates the bulb image, which is downloaded from the www.w3schools.com website. The location of an image to download from a website is obtained by right-clicking the image and selecting View Image Info or Copy Image Location and including the image location in the AJAX code.
AJAX code for height and distance measurement
Servo motor calibration
Access images, time, and sensor data over the Internet
BMP280 with ESP8266 and ESP32 microcontrollers
Component | ESP8266 Connections | ESP32 Connections |
---|---|---|
BMP280 VCC | 3V3 | 3V3 |
BMP280 GND | GND | GND |
BMP280 SDI | D2 | GPIO 21 |
BMP280 SCK | D1 | GPIO 22 |
BMP280 SD0 | GND | GND |
The first section and the setup function of the sketch in Listing 9-6 are essentially the same as in Listing 9-3. The Adafruit_Sensor library, listed under Adafruit_Unified_Sensor in the Arduino IDE, and the Adafruit_BMP280 library are installed for the BMP280 sensor, which is initialized with its I2C address in the setup function. The tempUrl URL is mapped to the tempFunct function , which is attached to the Ticker library for timing web page updates.
When the server receives, from the client, a message containing the timing interval, the WebSocket wsEvent function is called, which loads the received message for parsing. In Listing 9-6, the message only contains the timing interval variable, interval, and the message string is converted to an integer with the atoi() C++ function. The tempFunct function updates the interval variable, for the Ticker library to control the timing of calls to the tempFunct function, and obtains the temperature reading from the BMP280 sensor. Both the temperature and timing interval are converted to name and value pairs in JSON format, with the JsonConvert function , and transmitted to the client. If several clients are connected to the server and one client changes the timing interval, then the timing interval displayed by each client is also updated. The base and loop functions of Listing 9-6 are identical to those in Listing 9-3. When testing the sketch, the instruction JsonConvert(bmp.readTemperature(), interval) is replaced with JsonConvert(random(20, 50)*1.0, interval) to generate variation between values.
Real-time sensor graphics
AJAX code for the web page is given in Listing 9-7. The content of the web page is formatted as a table with a header row containing the browser current date and time, with two columns consisting of seven rows. The first column, which spans all seven rows, with the instruction <td rowspan="7">, contains the image that is downloaded when the web page is initialized. The first three rows in the second column contain the updated temperature and time interval, both transmitted by the server, and a <canvas> for the graph. The four sliders to control the graph Y-axis maximum and minimum values and the buttons to increase or decrease the time interval call the functions setMaxy, setMiny, sendadd, and sendsub, respectively.
JavaScript array command details are available at www.w3schools.com/jsref/jsref_obj_array.asp.
The graph Y-axis maximum and minimum values are the corresponding slider values, and the functions setMaxy and setMiny convert a slider value to a string for displaying on the web page to the right of the slider. The functions sendadd and sendsub increase and decrease the time interval between updates of the web page by one second, with the updated value sent to the server.
AJAX code for real-time sensor graphics
Summary
Three examples illustrate the advantage of using the WebSocket protocol for a two-way real-time conversation between the client and the web server. In the first example, a web page enabled the client to send text to and receive text from the server in real time. In the second example, the client used a web page slider and button to remotely control the position and state of a laser attached to a servo motor on a tilt bracket. The server responded with the height and distance to an object identified by the laser, with the horizontal distance measured by an ultrasonic sensor. The third example demonstrated the real-time graphic display, on a web page, of temperature sensor data transmitted by the server, with the graph properties and the interval between temperature measurements controlled remotely by the client using a web page slider and buttons.
Components List
ESP8266 microcontroller: LOLIN (WeMos) D1 mini or NodeMCU board
ESP32 microcontroller: DEVKIT DOIT or NodeMCU board
Temperature sensor: BMP280 module
Ultrasonic distance sensor: HC-SR04
Laser module: KY-008
Servo motor: SG90
Servo pan and tilt bracket
Capacitor: 100 nF, 22 μF
Voltage regulator: L4940V5
Battery: 9 V