bblanchon / ArduinoJson

📟 JSON library for Arduino and embedded C++. Simple and efficient.

Home Page:https://arduinojson.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I'm getting No memory error on deserialization

zekageri opened this issue · comments

I'm using ArduinoJson v7 with ESP32 Wrover-E (8mb external ram)
Here is my log

[HsH_Server] - Error: NoMemory. Size: 117
[HsH_Server] - Raw data: {"path":"/getFresh","method":"GET","query":{},"body":{},"id":"0fhw9bmm0eh6a7yzy4ep36"}
[HsH_Server] - Available heap: 104788 bytes
[HsH_Server] - Available external ram: 4023547 bytes

Here is the function

hshServerClient.onFrame([this](const char* frame, size_t len){
    JsonObject doc;
    DeserializationError err =  deserializeJson(doc,frame);
    if(err){
        Serial.printf("[HsH_Server] - Error: %s. Size: %d\n", err.c_str(), len);
        Serial.printf("[HsH_Server] - Raw data: %s\n", frame);
        Serial.printf("[HsH_Server] - Available heap: %d bytes\n", ESP.getFreeHeap());
        Serial.printf("[HsH_Server] - Available external ram: %d bytes\n", ESP.getFreePsram());
        return;
    }
    handleRequest(doc);
});

The lambda is running in a separate task which has 16 * 1024 stack size and the char* frame is totally complete. Arduinojson refuses to deserialize. Even if i pass in the length.

This produces the same result

hshServerClient.onFrame([this](const char* frame, size_t len){
    JsonObject doc;
    DeserializationError err =  deserializeJson(doc,frame,len); // Passing len
    if(err){
        Serial.printf("[HsH_Server] - Error: %s. Size: %d\n", err.c_str(), len);
        Serial.printf("[HsH_Server] - Raw data: %s\n", frame);
        Serial.printf("[HsH_Server] - Available heap: %d bytes\n", ESP.getFreeHeap());
        Serial.printf("[HsH_Server] - Available external ram: %d bytes\n", ESP.getFreePsram());
        return;
    }
    handleRequest(doc);
});

I also run a memory checker which has detailed info about my ram usage

[SYSTEM] - [HEAP][1]
Free:   112936      
Min:    112936      
Max:    112936      
Contig: 65524       
Diff:   112936      


[SYSTEM] - [EXT][1] 
Free:   4023767     
Min:    4023767
Max:    4023767
Contig: 3932148
Diff:   4023767

The contigous memory in my internal heap is 65524 and 3932148 in the external. There is no way i have no memory.
I also tried to offload the deserialization to other task like this

hshServerClient.onFrame([this](const char* frame, size_t len){
    messageBuffer.push_back(std::string(frame,len));
});

bool HsHServerRouter::handleRequest(){
    if(messageBuffer.empty()){return false;}
    std::string message = messageBuffer.front();
    JsonObject resp,req;
    DeserializationError err =  deserializeJson(req,message);
    if(err){
        Serial.printf("[HsH_Server] - Error: %s. Size: %d\n", err.c_str(), message.length());
        Serial.printf("[HsH_Server] - Raw data: %s\n", message.c_str());
        Serial.printf("[HsH_Server] - Available heap: %d bytes\n", ESP.getFreeHeap());
        Serial.printf("[HsH_Server] - Available external ram: %d bytes\n", ESP.getFreePsram());
        messageBuffer.pop_front();
        return false;
    }
    resp["message"] = "Cya!";
    reply(req,resp);
    messageBuffer.pop_front();
}

void HsHServerRouter::loop(){
    handleRequest();
}

The result is the same. Really interesting. Maybe there are some unique characters in the string which i can't see on the console?

Hi @zekageri,

You passed a null JsonObject to deserializeJson().
You should pass a JsonDocument instead.

- JsonObject doc;
+ JsonDocument doc;
  DeserializationError err =  deserializeJson(doc,frame);

Best regards,
Benoit

Oh god. It was a silly mistake. Thank you very much and sorry for the issue :D