I've been looking a while for a library that can connect to a Node.js server using Websockets. The problem is that every library I've tried so far ends up being incompatible with the Rev 2. Is there any library out there that can accomplish this?
You can try the SimpleWebSocket example of this WiFiWebServer Library, then modify it to fit your purpose if it's working.
I actually don't have that UNO WiFi Rev. 2 to make real test, but the example has been compiled OK with UNO WiFi Rev2 and also working OK on many other boads.
In file included from /home/kh/Arduino/abcd-prog_working/WiFiWebServer_GitHub/examples/HTTPClient/SimpleWebSocket/SimpleWebSocket.ino:22:0:
sketch/defines.h:41:4: warning: #warning Using WiFiNINA using WiFiNINA_Generic Library [-Wcpp]
#warning Using WiFiNINA using WiFiNINA_Generic Library
^~~~~~~
In file included from sketch/defines.h:302:0,
from /home/kh/Arduino/abcd-prog_working/WiFiWebServer_GitHub/examples/HTTPClient/SimpleWebSocket/SimpleWebSocket.ino:22:
/home/kh/Arduino/libraries/WiFiWebServer-1.1.1/src/WiFiWebServer.h:90:4: warning: #warning Use WiFiNINA from WiFiWebServer [-Wcpp]
#warning Use WiFiNINA from WiFiWebServer
^~~~~~~
In file included from sketch/defines.h:302:0,
from /home/kh/Arduino/abcd-prog_working/WiFiWebServer_GitHub/examples/HTTPClient/SimpleWebSocket/SimpleWebSocket.ino:22:
/home/kh/Arduino/libraries/WiFiWebServer-1.1.1/src/WiFiWebServer.h:117:4: warning: #warning SENDCONTENT_P_BUFFER_SZ using default 4 Kbytes [-Wcpp]
#warning SENDCONTENT_P_BUFFER_SZ using default 4 Kbytes
^~~~~~~
...
In file included from /home/kh/Arduino/libraries/WiFiNINA_Generic-1.8.0/src/utility/spi_drv.cpp:53:0:
/home/kh/Arduino/libraries/WiFiNINA_Generic-1.8.0/src/WiFiNINA_Pinout_Generic.h:332:4: warning: #warning Use WiFiNINA for UNO WiFi Rev2 [-Wcpp]
#warning Use WiFiNINA for UNO WiFi Rev2
^~~~~~~
Sketch uses 21630 bytes (44%) of program storage space. Maximum is 48640 bytes.
Global variables use 647 bytes (10%) of dynamic memory, leaving 5497 bytes for local variables. Maximum is 6144 bytes.
Good Luck,
Wow, it actually worked! Thank you so much!
That's good news.
If possible, could you please post a simplified version of the working code with Node.js (without any secret) to help other members, just in case
I'd also like to include it into the examples of WiFiWebServer library, certainly with notes of your contribution.
Sure! Right now I just have a simple server that accepts a connection, sends a confirmation message, and listens for messages on the socket.
Here is the Node.js code:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 80 });
wss.on('connection', ws => {
console.log('connection opened');
ws.send('Hello from Node.js server');
ws.on('message', msg => {
console.log('message: ' + msg);
});
ws.on('close', () => {
console.log('connection closed');
});
});
This library is exactly what I've been looking for, but I've been struggling to get this working with the Arduino Uno WiFi Rev 2. I'm getting a rather lengthy series of error outputs in the console (so much so that I can't paste the entire error into this post, so here is a pastebin link with the full output). I'm wondering if I missed a step in configuring something within the defines.h file to make this work with this board.
Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno WiFi Rev2, ATMEGA328"
In file included from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFi_Generic.h:59:0,
from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFiNINA_Generic.h:51,
from D:DocumentsArduinolibrariesWiFiWebServersrc/WiFiWebServer.h:88,
from sketchdefines.h:304,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/utility/wl_definitions.h:87:23: error: redeclaration of 'WL_NO_SHIELD'
WL_NO_SHIELD = 255,
^~~
In file included from D:DocumentsArduinolibrariesWiFiNINAsrc/WiFi.h:29:0,
from D:DocumentsArduinolibrariesWiFiNINAsrc/WiFiNINA.h:23,
from sketchdefines.h:1,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINAsrc/utility/wl_definitions.h:50:2: note: previous declaration 'wl_status_t WL_NO_SHIELD'
WL_NO_SHIELD = 255,
^~~~~~~~~~~~
In file included from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFi_Generic.h:59:0,
from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFiNINA_Generic.h:51,
from D:DocumentsArduinolibrariesWiFiWebServersrc/WiFiWebServer.h:88,
from sketchdefines.h:304,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/utility/wl_definitions.h:88:3: error: redefinition of 'wl_status_t WL_NO_MODULE'
WL_NO_MODULE = WL_NO_SHIELD,
^~~~~~~~~~~~
In file included from D:DocumentsArduinolibrariesWiFiNINAsrc/WiFi.h:29:0,
from D:DocumentsArduinolibrariesWiFiNINAsrc/WiFiNINA.h:23,
from sketchdefines.h:1,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINAsrc/utility/wl_definitions.h:51:9: note: 'wl_status_t WL_NO_MODULE' previously defined here
WL_NO_MODULE = WL_NO_SHIELD,
^~~~~~~~~~~~
In file included from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFi_Generic.h:59:0,
from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFiNINA_Generic.h:51,
from D:DocumentsArduinolibrariesWiFiWebServersrc/WiFiWebServer.h:88,
from sketchdefines.h:304,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/utility/wl_definitions.h:89:23: error: redeclaration of 'WL_IDLE_STATUS'
WL_IDLE_STATUS = 0,
^
In file included from D:DocumentsArduinolibrariesWiFiNINAsrc/WiFi.h:29:0,
from D:DocumentsArduinolibrariesWiFiNINAsrc/WiFiNINA.h:23,
from sketchdefines.h:1,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINAsrc/utility/wl_definitions.h:52:9: note: previous declaration 'wl_status_t WL_IDLE_STATUS'
WL_IDLE_STATUS = 0,
^~~~~~~~~~~~~~
In file included from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFi_Generic.h:59:0,
from D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/WiFiNINA_Generic.h:51,
from D:DocumentsArduinolibrariesWiFiWebServersrc/WiFiWebServer.h:88,
from sketchdefines.h:304,
from D:DocumentsArduinoSimpleWebSocketSimpleWebSocket.ino:22:
D:DocumentsArduinolibrariesWiFiNINA_Genericsrc/utility/wl_definitions.h:90:3: error: redeclaration of 'WL_NO_SSID_AVAIL'
WL_NO_SSID_AVAIL,
^~~~~~~~~~~~~~~~
I installed the WiFiWebServer 1.1.1 library today and allowed it to install all of the libraries it depends on, so everything should be fully up to date. Has anything substantial changed since this thread was opened that might be causing these errors? I've been banging my head against this problem for a few hours now. Any thoughts or insights that either of you could provide would be greatly appreciated.
Without your sketch, it's almost impossible to guess what you're doing wrong, But from the error,
In file included from D:\Documents\Arduino\libraries\WiFiNINA\src/WiFi.h:29:0,
from D:\Documents\Arduino\libraries\WiFiNINA\src/WiFiNINA.h:23,
from sketch\defines.h:1,
from D:\Documents\Arduino\SimpleWebSocket\SimpleWebSocket.ino:22:
I just can guess that you're wrongly including WiFiNINA.h in your defines.h because WiFiNINA_Generic library has been pre-selected to use by WiFiWebServer library
I suggest that you restart by using the intact SimpleWebSocket example.
Compile to verify it's OK. Then modify-verify step-by-step until you get compile error
Just compile and verify and it's still OK for UNO WiFi Rev2
In file included from /home/aaa/Arduino/libraries/WiFiNINA_Generic-1.8.5/src/utility/spi_drv.cpp:55:0:
/home/aaa/Arduino/libraries/WiFiNINA_Generic-1.8.5/src/WiFiNINA_Pinout_Generic.h:334:4: warning: #warning Use WiFiNINA for UNO WiFi Rev2 [-Wcpp]
#warning Use WiFiNINA for UNO WiFi Rev2
^~~~~~~
Sketch uses 22050 bytes (45%) of program storage space. Maximum is 48640 bytes.
Global variables use 650 bytes (10%) of dynamic memory, leaving 5494 bytes for local variables. Maximum is 6144 bytes.
Thank you so much for the quick response. I went back and started with the SimpleWebSocket example and made no modifications and it compiles just fine. I went and added my SSID and pass, and changed the serverAddress and port to a heroku dyno that is just printing out the current time. I am hoping to see the time in my serial monitor output.
It appears to be running fine, but I am not seeing any received messages in my serial monitor.
Starting SimpleWebSocket on AVR Mega with WiFiNINA using WiFiNINA_Generic Library
WiFiWebServer v1.1.1
Please upgrade the firmware
Connecting to SSID: monkeynet
You're connected to the network, IP = 192.168.1.6
SSID: monkeynet, Signal strength (RSSI):-45 dBm
starting WebSocket client
[D:\Documents\Arduino\libraries\WiFiNINA_Generic\src\utility\spi_drv.cpp::348]-I-1,0
disconnected
starting WebSocket client
[D:\Documents\Arduino\libraries\WiFiNINA_Generic\src\utility\spi_drv.cpp::348]-I-1,0
disconnected
starting WebSocket client
[D:\Documents\Arduino\libraries\WiFiNINA_Generic\src\utility\spi_drv.cpp::348]-I-1,0
disconnected
starting WebSocket client
[D:\Documents\Arduino\libraries\WiFiNINA_Generic\src\utility\spi_drv.cpp::348]-I-1,0
disconnected
I am assuming it is getting to wsClient.begin() and then wsClient.connected() never returns true. This is exactly where I have ended up trying to use the ArduinoHttpClient library.
Could the issue be that the firmware needs to be updated for this to work?
That's better, but without your sketch, it's difficult for anybody to imagine what's wrong.
Just a quick question: are you sure you need WebSocket for this because you can just use HTTP(S) to access and get time from HTTP herokuapp.com or HTTPS herokuapp.com ?
As a follow up to that hypothesis, I ran the CheckFirmwareVersion code and I indeed was running 1.0.0. I went through the process of updating the firmware but the most recent version that was available is 1.3.0 and the CheckFirmwareVersion code keeps saying 1.4.3 is the latest version available.
Firmware version installed: 1.3.0
Latest firmware version available : 1.4.3
Check result: NOT PASSED
- The firmware version on the module does not match the
version required by the library, you may experience
issues or failures.
I went and tried the SimpleWebSocket code again and it produces the same output as the previous post.
Here is the entire INO code. The only things I have changed are the server address and port:
/****************************************************************************************************************************
SimpleWebSocket.ino - Simple Arduino web server sample for WiFi shield
For any WiFi shields, such as WiFiNINA W101, W102, W13x, or custom, such as ESP8266/ESP32-AT, Ethernet, etc
WiFiWebServer is a library for the ESP32-based WiFi shields to run WebServer
Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases
Based on and modified from Arduino WiFiNINA library https://www.arduino.cc/en/Reference/WiFiNINA
Built by Khoi Hoang https://github.com/khoih-prog/WiFiWebServer
Licensed under MIT license
Simple WebSocket client for HttpClient
Connects to the WebSocket server, and sends a hello
message every 5 seconds
created 28 Jun 2016
by Sandeep Mistry
modified 22 Jan 2019
by Tom Igoe
*****************************************************************************************************************************/
#include "defines.h"
char serverAddress[] = "damp-beyond-31315.herokuapp.com"; // server address
int port = 3000;
WiFiClient client;
WiFiWebSocketClient wsClient(client, serverAddress, port);
int count = 0;
int status = WL_IDLE_STATUS; // the Wifi radio's status
void printWifiStatus()
{
// print the SSID of the network you're attached to:
// you're connected now, so print out the data
Serial.print(F("You're connected to the network, IP = "));
Serial.println(WiFi.localIP());
Serial.print(F("SSID: "));
Serial.print(WiFi.SSID());
// print the received signal strength:
int32_t rssi = WiFi.RSSI();
Serial.print(F(", Signal strength (RSSI):"));
Serial.print(rssi);
Serial.println(F(" dBm"));
}
void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.print(F("\nStarting SimpleWebSocket on "));
Serial.print(BOARD_NAME);
Serial.print(F(" with "));
Serial.println(SHIELD_TYPE);
Serial.println(WIFI_WEBSERVER_VERSION);
// check for the presence of the shield
#if USE_WIFI_NINA
if (WiFi.status() == WL_NO_MODULE)
#else
if (WiFi.status() == WL_NO_SHIELD)
#endif
{
Serial.println(F("WiFi shield not present"));
// don't continue
while (true);
}
#if USE_WIFI_NINA
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION)
{
Serial.println(F("Please upgrade the firmware"));
}
#endif
// attempt to connect to WiFi network
while ( status != WL_CONNECTED)
{
Serial.print(F("Connecting to SSID: "));
Serial.println(ssid);
// Connect to WPA/WPA2 network
status = WiFi.begin(ssid, pass);
}
// you're connected now, so print out the data
printWifiStatus();
}
void loop()
{
Serial.println("starting WebSocket client");
wsClient.begin();
while (wsClient.connected())
{
Serial.print("Sending Hello ");
Serial.println(count);
// send a hello #
wsClient.beginMessage(TYPE_TEXT);
wsClient.print(count);
String data = " => Hello from SimpleWebSocket on " + String(BOARD_NAME) + ", millis = " + String(millis());
wsClient.print(data);
wsClient.endMessage();
// increment count for next message
count++;
// check if a message is available to be received
int messageSize = wsClient.parseMessage();
if (messageSize > 0)
{
Serial.println("Received a message:");
Serial.println(wsClient.readString());
}
// wait 5 seconds
delay(5000);
}
Serial.println("disconnected");
}
And yes, I would like to use web sockets as eventually I want to create bi-directional messaging between the arduino client and the node.js server, which will then broadcast the messages to other arduino clients.
char serverAddress[] = "damp-beyond-31315.herokuapp.com"; // server address
int port = 3000;
First, are you sure this is the correct WebSockets Server address and port? You have to verify the WS server at address/port working before moving further.
Second, I'm afraid I can't help you any further in dealing with this basic problem.
I really appreciate the help you've provided. I wish I could consider this a basic problem. ![]()
I am running the server side script on port 3000. There are no config vars so it should be using that port number included in the code. It's basically an example for setting up websockets straight from the heroku web site. I'm including the server side Node.js code below for posterity even if you're not able to help me further. Thanks.
'use strict';
const express = require('express');
const socketIO = require('socket.io');
const PORT = process.env.PORT || 3000;
const INDEX = '/index.html';
const server = express()
.use((req, res) => res.sendFile(INDEX, { root: __dirname }))
.listen(PORT, () => console.log(`Listening on ${PORT}`));
const io = socketIO(server);
io.on('connection', (socket) => {
console.log('Client connected');
socket.on('disconnect', () => console.log('Client disconnected'));
});
setInterval(() => io.emit('time', new Date().toTimeString()), 1000);
And here is the index.html that allows the browser to connect and receive the updated time:
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
let socket = io();
let el;
socket.on('time', (timeString) => {
el = document.getElementById('server-time');
el.innerHTML = 'Server time: ' + timeString;
});
</script>
</head>
<body>
<p id="server-time"></p>
</body>
</html>
Just to put a pin in this, I ran stardatara's node.js code locally on a computer on the same LAN as the arduino, and directed the aruino's server address to the computers IP address and it ended up working. I did not expect an incompatibility between socket.io as the server instance and the arduino client libraries. I have both this library's example implementation working as well as the ArduinoHttpClient SimpleWebSocket example. I am still having issues with getting stardatara's example code to execute on the heroku dyno, but that is something else entirely to deal without outside of the scope of this forum. Hope this helps anyone in the future.
Just a note and be careful that SocketIO is different from plain WebSockets.
Check SocketIO Notes
Note: Socket.IO is not a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the ack id when a message acknowledgement is needed. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a WebSocket server (like ws://echo.websocket.org) either. Please see the protocol specification here.
and Arduino Web Socket not connecting
Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds additional metadata to each packet. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a plain WebSocket server either.
I just now managed to get this working. I nixed the socket.io library and switched to a plain websocket implementation using ws running on my heroku dyno. I also needed to switch the port to 80 on my arduino instead of the 3000 that is defined in the node.js script (even though 3000 worked when testing on my LAN).
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.