Assistance Parsing and Reading JSON Array Payload Websockets - SOLVED

Hello,

Looking for assistance reading out the Float values of my array that is coming from a webClient.

Desire Outcome in Serial Monitor:

  • If value is "Speed" print (speed float value)
  • If value is "Degree" print (degree float value)

Board:
ESP32 Cam

Example Received Payload:

[0] Connection from 192.168.4.2
[0] Text: {"Speed":0.043380784121874086,"Degree":171.86989764584402}
[0] Text: {"Speed":0.062564656608500427,"Degree":281.30993247402023}
[0] Text: {"Speed":0.12810192035473067,"Degree":286.69924423399362}
[0] Text: {"Speed":0.20058629109535972,"Degree":293.42869280874538}
[0] Text: {"Speed":0.2661473860550167,"Degree":295.97439396243135}
[0] Text: {"Speed":0.30211220250908294,"Degree":299.1676133795778}
[0] Text: {"Speed":0.31354435188173346,"Degree":300.57922687248902}
[0] Text: {"Speed":0.31670943556172532,"Degree":301.53479190518829}
[0] Text: {"Speed":0,"Degree":0}

Arduino Code:

#include "esp_camera.h"
#include <WiFi.h>
#include <WebSocketsServer.h>
#include <ArduinoJson.h>

#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"

//Constants
const char* ssid = "ESP32-TOKEN-THINKER";
const char* password = "password";

//Global
WebSocketsServer webSocket = WebSocketsServer(8888); //port 8888

bool isClientConnected;


/********************************************************************
   Functions
********************************************************************/

//Callback: Receiving any WebSocket message
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

const size_t capacity = JSON_OBJECT_SIZE(2) + 20; //Memory pool
DynamicJsonDocument doc(capacity); 
const char* json = "{\"Speed\":1.000097867,\"Degree\":12.0065454}";

deserializeJson(doc, json);

float Speed = doc["Speed"]; // Get speed value
float Degree = doc["Degree"]; // get degree value
  
  // Figure out the type of WebSocket event
  switch (type) {
    
    //Client Disconnected
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;

    //Client Connected
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connection from ", num);
        Serial.println(ip.toString());
        isClientConnected = true;
      }
      break;
    
    case WStype_TEXT:{
    
    if (strncmp((char *)payload, "degree:", 6) == 0 )
      {
        Serial.print("Degree value: ");
        Serial.println(Degree);     
      }
      else if (strncmp((char *)payload, "ping:", 4) == 0 )
      {
        Serial.print("Speed value: ");
        Serial.println(Speed);    
      }
      else{
        Serial.printf("[%u] Text: %s\n", num, payload);
        }
    

    }
      break;

//-Do Nothing-
    case WStype_BIN:
    case WStype_ERROR:
    case WStype_FRAGMENT_TEXT_START:
    case WStype_FRAGMENT_BIN_START:
    case WStype_FRAGMENT:
    case WStype_FRAGMENT_FIN:
    default:
      break;
  }
}

void setup() {
  //Start Serial port
  Serial.begin(115200);
  Serial.setDebugOutput(true);

  //Connect to Wifi AP
  Serial.println("Connecting...");
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);


//Start WebSocket server and assign callback
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);


}

void loop() {
  webSocket.loop();
}

this 20 is likely too small as you need Additional bytes for input duplication since your have a const char*. (which version of the library? )

const size_t capacity = JSON_OBJECT_SIZE(2) + 20; //Memory pool
DynamicJsonDocument doc(capacity);

otherwise nothing wrong with the extraction - for example this should print on your Serial Monitor (@ 115200 bauds)

[color=purple]
Speed ==> 1.000
Degree ==> 12.007
[/color]
#include <ArduinoJson.h>

void setup()
{
  Serial.begin(115200);
  const char* json = "{\"Speed\":1.000097867,\"Degree\":12.0065454}";
  DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)+50);
  deserializeJson(doc, json);
  float s = doc["Speed"]; // Get speed value
  float d = doc["Degree"]; // get degree value

  Serial.print(F("Speed ==> ")); Serial.println(s, 3);
  Serial.print(F("Degree ==> ")); Serial.println(d, 3);
}

void loop() {}

you can fine tune the 50 by using the ArduinoJson Assistant

Appreciate the fast response, I used the assistance to get that code.

The problem that I’m having is that the converter isn’t updating the new values of the JSON packet.

I need more of a streaming functionality with the identifiers.

Thoughts?

J.N.L I humbly thank you, I was wondering what was going on and it smack me in the face after a few tries and I am ecstatic to say it is working how it should be.

Once I'm done I will have to refactor the code to make it tight nit and easily expandable, but for now I got a W. Wooooohooooooo

otherwise nothing wrong with the extraction

The problem was with what the parser was reading :-[ , because I was so focuses on the code I didn't notice it myself :roll_eyes: :roll_eyes: haha.

Code Before:

 DynamicJsonDocument doc(capacity);
const char* json = "{\"Speed\":1.000097867,\"Degree\":12.0065454}";

deserializeJson(doc, json);

float Speed = doc["Speed"]; // Get speed value
float Degree = doc["Degree"]; // get degree value

Code After - When you see it you will laugh! ;D

DynamicJsonDocument doc(capacity);
//const char* json = "{\"Speed\":1.000097867,\"Degree\":12.0065454}";

deserializeJson(doc, (char *)payload);

float Speed = doc["Speed"]; // Get speed value
float Degree = doc["Degree"]; // get degree value