hi all,
For a week I have been stuck inside a rabbit hole for a project of mine. Where would like to wirelessly send an int array with the size of 7 slots between two esp32.
There are many ways, to do this, this is what I have used:
I have used espNOW it was reliably but the code big and not really what I wanted.
Then i stumbled across Web sockets. Here is where I thought the rabbit hole would end...
Web sockets for how I used it really reliable and almost real-time for most of the time.
I'm totally new to this and not really knowing what I'm doing a little help is appreciated.
senders code:
#include <WiFi.h>
#include <WebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoJson.h>
#include <Ticker.h>
//audio stuff. now filled with random values
int FreqVal[7];
int spectrumValue[7];
double mult = 1.00;
// Initialize network parameters
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// Instantiate server objects
WebServer server;
WebSocketsServer webSocket = WebSocketsServer(81);
// Declare/initialize timer variables
Ticker timer;
bool read_data = false;
// Raw string literal for containing the page to be sent to clients
char webpage[] PROGMEM = R"=====(
<html>
<head>
<script>
var Socket;
function init() {
Socket = new WebSocket('ws://' + window.location.hostname + ':81/');
Socket.onmessage = function(event){
// receive the color data from the server
var data = JSON.parse(event.data);
console.log(data);
}
}
</script>
</head>
<body onload="javascript:init()">
<h4>Websocket client served from the Sensor Board!</h4>
</body>
</html>
)=====";
void setup() {
// Connect to WiFi
Serial.begin(115200);
// Setting the ESP as an access point
Serial.print("Setting AP (Access Point)…");
// Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
// define the routes in which the server is accessible
server.on("/",[](){
server.send_P(200, "text/html", webpage);
});
// initialize server and websockets
server.begin();
webSocket.begin();
// initialize timer function
timer.attach(/*rate in secs*/ 0.1, /*callback*/ readData);
// handling incoming messages on the websocket
webSocket.onEvent(webSocketEvent);
}
void readData() {
// should only be used to set/unset flags
read_data = true;
}
void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
{
if(type == WStype_TEXT)
{
// processs any returned data
Serial.printf("payload [%u]: %s\n", num, payload);
}
}
int audioVal(int i){spectrumValue[i] = mult * random(0,4096); return (spectrumValue[i]);}
void loop() {
webSocket.loop();
server.handleClient();
if(read_data){
//sendTest1(payload);//works but there's a bottle neck on the receiver or senders end.
sendTest3(payload); //this sends the data as fast the esp23 could send and receive it and almost perfect real time.
}
}
void sendTest1(uint8_t* payload){
//this kinda works but very slow and only the last json += "value" string is filled. remove 'json += moveValue(6);' and 'json += moveValue(5);' is filled nothing else is being filled.
//after a while the buffer is filled and this grinds the esp32 to a halt and only sending a message every 4 seconds.
String json = "{\"Freq0\":";
json += moveValue(0);
json = "{\"Freq1\":";
json += moveValue(1);
json = "{\"Freq2\":";
json += moveValue(2);
json = "{\"Freq3\":";
json += moveValue(3);
json = "{\"Freq4\":";
json += moveValue(4);
json = "{\"Freq5\":";
json += moveValue(5);
json = "{\"Freq6\":";
json += moveValue(6);
json += "}";
Serial.println(json); // DEBUGGING
webSocket.broadcastTXT(json.c_str(), json.length());
}
/*
void sendTest2(uint8_t* payload){
//i couldn't get this to work ('File' not declared in this scope). my tought was this would fill all doc values. and might be faster...
File file = SD.open(fileName, FILE_WRITE);
StaticJsonDocument<4096> doc;
doc["Freq0"] = audioVal(0);
doc["Freq1"] = audioVal(1);
doc["Freq2"] = audioVal(2);
doc["Freq3"] = audioVal(3);
doc["Freq4"] = audioVal(4);
doc["Freq5"] = audioVal(5);
doc["Freq6"] = audioVal(6);
serializeJson(doc, file);
file.close();
Serial.println(file);
webSocket.broadcastTXT(file.c_str(), file.length());
}
*/
void sendTest3(uint8_t* payload){
//this works perfect the speed is there but i have no idea how to remove the dots or points on the receiver end, it receives fftData string as a uin8_t
//I need to send the audio data as fast as possible, this function does the job perfect without any delay
String fftData = ".";
for (int i = 0; i < 7; i++) {
fftData += moveValue(i);
fftData += ".";
}
Serial.println(fftData); // DEBUGGING
webSocket.broadcastTXT(fftData.c_str(), fftData.length());
}
receiver:
#include <WiFi.h>
#include <WebServer.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
//#include <StreamUtils.h>
// Initialize sensor parameters
int spectrumValue[7];
void printSpectrum() {
for (int i = 0; i < 7; i++) {
Serial.print(spectrumValue[i]);
Serial.print("\t");
}
Serial.println();
}
// Initialize network parameters
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// Declare websocket client class variable
WebSocketsClient webSocket;
// Allocate the JSON document
StaticJsonDocument<200> doc;
void setup() {
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.begin(115200);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("IP Address: "); Serial.println(WiFi.localIP());
// server address, port, and URL path
webSocket.begin("192.168.4.1", 81, "/");
// event handler
webSocket.onEvent(webSocketEvent);
// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
}
void webSocketEvent(WStype_t type, uint8_t* payload, size_t length) {
// Make sure the screen is clear
if (type == WStype_TEXT)
{
translatorTest1(payload);
translatorTest2(payload);
// Serial.printf("payload: %s\n",payload);
}
}
void loop() {
webSocket.loop();
delay(0);
}
void translatorTest1(uint8_t* payload) {
//tried to remove the dots. the dots are removed but spectrumValue isn't filledA
byte index = 0;
String input_cr;
char tempMsg[70];
input_cr = (char*) &payload;
input_cr.toCharArray(tempMsg, 70);
char* spectrumChar = strtok(tempMsg, ".");
while (spectrumChar != NULL) {
spectrumValue[index++] = atoi(spectrumChar);
spectrumChar = strtok(NULL, ".");
}
printSpectrum();
}
void translatorTest2(uint8_t* payload) {
// Deserialize the JSON document
DeserializationError error = deserializeJson(doc, payload);
//ReadBufferingStream bufferedFile(payload, 64); //tried this but no luck compiler error
//DeserializationError error = deserializeJson(doc, bufferedFile);
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
const float Freq0 = doc["Freq0"];
const float Freq1 = doc["Freq1"];
const float Freq2 = doc["Freq2"];
const float Freq3 = doc["Freq3"];
const float Freq4 = doc["Freq4"];
const float Freq5 = doc["Freq5"];
const float Freq6 = doc["Freq6"];
Serial.print("Freq0: "); Serial.print(String(Freq0).c_str());
Serial.print("Freq1: "); Serial.print(String(Freq1).c_str());
Serial.print("Freq2: "); Serial.print(String(Freq2).c_str());
Serial.print("Freq3: "); Serial.print(String(Freq3).c_str());
Serial.print("Freq4: "); Serial.print(String(Freq4).c_str());
Serial.print("Freq5: "); Serial.print(String(Freq5).c_str());
Serial.print("Freq6: "); Serial.println(String(Freq6).c_str());
// Send acknowledgement to the client
// webSocket.sendTXT("{\"status\":\"OK\"}");*/
}