Yes. 'Serial' is an object whose class inherits from Stream.
As I just started looking into this, I haven't searched the web for tutorials / examples. There was quite a bit of example code posted in your Thread from Last Year.
Using ideas from that thread, I spent an hour putting together a skeletal example (for ESP32) of what I mean. It compiles and shows the techniques I'm talking about but would need to be fleshed out to produce code that does something useful.
The idea (as I said above) is that there are a number of slave nodes that gather sensor data and periodically send it to the master (server) for processing. The Server takes the data from the nodes and processes it somehow.
I didn't include any details about the sensors or how the data is processed since they're not needed to demonstrate the main concept.
In my mind, the advantage of doing it this way is that you don't need to turn numeric sensor data into character strings for transmission just to parse and convert it back to numeric data in the Server. All the data is sent and received in its native binary.
SLAVE NODE:
#include "Arduino.h"
#include <WiFi.h>
#include <AsyncTCP.h>
struct SensorData_t {
uint8_t sensorId;
time_t timeStamp;
float temperature;
float humidity;
float pressure;
};
void connectWiFi();
void handleConnected(void *arg, AsyncClient *client);
void getSensorData(SensorData_t &theData);
IPAddress serverAddress(192, 168, 10, 100);
const uint16_t port = 7050;
bool waitingToConnect = false;
const size_t sensorDataSize = sizeof(SensorData_t);
AsyncClient aClient;
void setup() {
Serial.begin(115200);
connectWiFi();
aClient.onConnect(handleConnected, nullptr);
}
void loop() {
static uint32_t measuremetPeriod = 10000;
static uint32_t prevMillis = millis() - measuremetPeriod;
uint32_t currentMillis = millis();
if (((currentMillis - prevMillis) >= measuremetPeriod) && !waitingToConnect) {
waitingToConnect = true;
prevMillis = currentMillis;
aClient.connect(serverAddress, port);
}
}
void handleConnected(void *arg, AsyncClient *client) {
(void) arg;
(void) client;
SensorData_t newData;
getSensorData(newData);
if (aClient.space() >= sensorDataSize && aClient.canSend()) {
aClient.add(reinterpret_cast<const char *> (&newData), sensorDataSize);
aClient.send();
}
aClient.close();
waitingToConnect = false;
}
void getSensorData(SensorData_t &theData) {
// read the sensors and put the results in theData
}
void connectWiFi() {
// Typical ESP32 WiFi Connection code goes here
}
MASTER SERVER:
#include "Arduino.h"
#include <WiFi.h>
#include <AsyncTCP.h>
struct SensorData_t {
uint8_t sensorId;
time_t timeStamp;
float temperature;
float humidity;
float pressure;
};
void connectWiFi();
void handleNewClient(void *arg, AsyncClient *client);
void handleData(void *arg, AsyncClient *client, void *data, size_t len);
void handleError(void *arg, AsyncClient *client, int8_t error);
void handleDisconnect(void* arg, AsyncClient * client);
static void handleTimeOut(void* arg, AsyncClient * client, uint32_t time);
const size_t sensorDataSize = sizeof(SensorData_t);
const uint16_t port = 7050;
AsyncServer server(port);
void setup() {
Serial.begin(115200);
connectWiFi();
server.onClient(handleNewClient, nullptr);
server.begin();
}
void loop() {
}
void connectWiFi() {
// Typical ESP32 WiFi Connection code goes here
}
void handleNewClient(void *arg, AsyncClient *client) {
(void) arg;
(void) client;
log_i("Client Connected");
client->onData(&handleData, NULL);
client->onError(&handleError, NULL);
client->onDisconnect(&handleDisconnect, NULL);
client->onTimeout(&handleTimeOut, NULL);
// Put any special code that needs to run when client connects here
}
void handleData(void *arg, AsyncClient *client, void *data, size_t len) {
(void) arg;
(void) client;
SensorData_t dataPacket;
if (len == sensorDataSize) {
log_i("Received Data:");
memcpy(&dataPacket, data, len);
// Put code here to process the receieved senosr data
}
}
void handleError(void *arg, AsyncClient *client, int8_t error) {
(void) arg;
(void) client;
log_i("Client Error: %d", error);
// Put any special code to handle client errors here
}
void handleDisconnect(void* arg, AsyncClient * client) {
(void) arg;
(void) client;
log_i("Client Disconnected");
// Put any special code to handle client disconnect here
}
static void handleTimeOut(void* arg, AsyncClient * client, uint32_t time) {
(void) arg;
(void) client;
(void) time;
log_i("Client ACK Timeout");
// Put any special code to handle client timeout here
}