This week I tried to use WiFiNINA to send data from Arduino to server, also used web socket to broadcast the data to every user. Swift

First I tried to get the data I want from Arduino, I got signal strength of connection, and sensor data.

#include <WiFiNINA.h>
#include <ArduinoHttpClient.h>
#include "config.h"

#include <DHT.h>

#define DHTPIN 3          
#define DHTTYPE DHT11   
DHT dht(DHTPIN, DHTTYPE);

WiFiClient wifi;
HttpClient client = HttpClient(wifi, SERVER_ADDRESS, SERVER_PORT);

int wifi_status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  
  while (!Serial);
  dht.begin(); 
  connectWiFi();
}

void loop() {

  // read the sensor values and signalStrength
  float temperature = dht.readTemperature(true);
  float humidity    = dht.readHumidity();
  int signalStrength = WiFi.RSSI();

  // print the values
  Serial.print(temperature);
  Serial.print("°F ");
  Serial.print(humidity);
  Serial.println("% RH");

  Serial.println("Sending data to server via HTTP POST");
  String contentType = "application/x-www-form-urlencoded";
  String postData = "temperature=" + String(temperature);
  postData += "&humidity=" + String(humidity);
  postData += "&device=" + String(DEVICE_ID);
  postData += "&signalStrength=" + String(signalStrength);
  
  client.post("/", contentType, postData);
  Serial.println(postData);

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
  
  printRSSI();

  Serial.println("Waiting for ten seconds\\n");
  delay(10000);
}

void connectWiFi() {

  Serial.print("WiFi firmware version ");
  Serial.println(WiFi.firmwareVersion());
 
  while (wifi_status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(WIFI_SSID);
    wifi_status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    // wait 3 seconds
    delay(3000);
  }
  Serial.println("Connected to WiFi");
  printWiFiStatus();
  printRSSI();
}

void printWiFiStatus() {
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void printRSSI() {
  Serial.print("signal strength (RSSI): ");
  Serial.println( WiFi.RSSI());
}

To get the signal strength, I borrowed the code from WiFi_connection_timeLogger from Tom, since I don't have the SD card, I got those information in serial window.

Then I started server side.

//express and data handler
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
var messages=[];
var dataToSend;
var realTimeData;

app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

const http = require("http").createServer(app);

const port = process.env.PORT || 8080;

//Server
const server = app.listen(port);
console.log("Server is running on <http://localhost>:" + port);

//get route
app.get("/data",function(req,res){
  res.send(realTimeData);
  console.log("res="+realTimeData);
});

//post route
app.post("/",function(req,res){
   let data=req.body;

   let dt = new Date();
   data.timestamp = dt.getTime();

   let remoteAddress = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
   data.remoteAddress = remoteAddress;
   
   messages.push(data);
   realTimeData=data;
   console.log("post="+data.humidity);
   res.send(data);

   io.sockets.emit(
     "change", data
  );
});

/////SOCKET.IO///////
const io = require("socket.io")().listen(server);

For get route, I received the response of the latest data.

For post route, I got the response of data in parsed body of the request. Also, every time the Arduino side sends POST request, the server emits that data to all socket clients.

Then I tried to console log the data sent by web socket. And display them in html div.

socket.on("change",(data)=>{
    console.log(data);
    let humidity = data.humidity;
    let signalStrength = data.signalStrength;
    // glScene.changeSun(data.humidity);
    document.getElementById('device').innerHTML=data.device;
    document.getElementById('data').innerHTML=humidity;
  });

Then I tried to use the data in DOM elements to update the environment in three.js. The connected button can start/stop the synchronization of physical data and virtual environment.