ArduinoJson saying deserializeJson() failed: NoMemory when sending Serial json

Hey all I have a sketch that takes up 99% of my storage space since I am using a Arduino Nano.

Although everything in my code fits as-is, there seems to be an issue with me sending a json string over Serial as its coming back saying "deserializeJson() failed: NoMemory". I've also already used the ArduinoJson Assistant.

My json string looks like this:
{"hardd": {"warrDays": "1265","temp": "102","hddST": "18TB","hddSU": "4TB","hddPB": "70","fan": "4200","date": "Fri Mar 11TH 2024","time": "10:45pm"}}

Note that the iconImages.h has just code that has images to byte code like this (there are 12 total of these):

const unsigned char hdd [] PROGMEM = {
	// 'hdd (1), 24x24px
    0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x5f, 0xff, 0xfa, 0x7f, 0xff, 0xfe, 0x7f, 0x00, 0xfe, 0x7e, 
	0x7e, 0x7e, 0x79, 0xcf, 0x9e, 0x7b, 0x0f, 0xde, 0x76, 0x7f, 0xee, 0x64, 0xff, 0xe6, 0x6d, 0xe7, 
	0xf6, 0x69, 0x99, 0xf6, 0x69, 0xbd, 0xf6, 0x6b, 0xbd, 0xf6, 0x6f, 0x99, 0xf6, 0x6f, 0xc3, 0xf6, 
	0x67, 0xff, 0xe6, 0x77, 0xff, 0xee, 0x73, 0xf3, 0xce, 0x79, 0xc7, 0x9e, 0x1c, 0x0e, 0x3e, 0x0f, 
	0x00, 0xfe, 0x66, 0x07, 0xfe, 0x70, 0x3f, 0xfe, 0x72, 0x7f, 0xfe, 0x76, 0x0d, 0x5e, 0x70, 0xed, 
	0x1e, 0x5f, 0xed, 0x5a, 0x3f, 0xef, 0xfc, 0x00, 0x00, 0x00
};

Here is my code - if anyone has any suggestions on how to go about shrinking the amount of storage space/memory so that it wont error out when I send the json string then that would be great!

My code:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_EMC2101.h>
#include <ArduinoJson.h>
#include "iconImages.h"

#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeSerif9pt7b.h>

#define hdd_SCREEN_ADDRESS 0x3C
#define apple_SCREEN_ADDRESS 0x3C
#define dell_SCREEN_ADDRESS 0x3C
#define TCAADDR 0x70

//                           W    H
Adafruit_SSD1306 hdd_display(128, 32, &Wire, -1);
Adafruit_SSD1306 apple_display(128, 32, &Wire, -1);
Adafruit_SSD1306 dell_display(128, 32, &Wire, -1);

Adafruit_EMC2101 emc2101;
char character;

//For timer=========================================
const long Minutes = 1;
const long _Interval = (Minutes * 60 * 1000);
unsigned long previousMillis = 0;
//==================================================

//For HDD Stats=====================================
int i = 0;
const char* hdd_warrDays  = "";
const char* hdd_temp      = "";
const char* hdd_hddST     = "";
const char* hdd_hddSU     = "";
const char* hdd_hddPB     = "";
const char* hdd_fan       = "";
//==================================================

//For Apple Stats===================================
const char* apple_os      = "";
const char* apple_hddST   = "";
const char* apple_hddSU   = "";
const char* apple_hddPB   = "";
const char* apple_ip      = "";
const char* apple_uptime  = "";
//==================================================

//For Dell Stats====================================
const char* dell_os     = "";
const char* dell_hddST  = "";
const char* dell_hddSU  = "";
const char* dell_hddPB  = "";
const char* dell_ip     = "";
const char* dell_uptime = "";
//==================================================

//For Date & Time ==================================
const char* _date = "";
const char* _time = "";
//==================================================

void setup() {
  Serial.begin(9600);

  if (!hdd_display.begin(SSD1306_SWITCHCAPVCC, hdd_SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }

  hdd_display.clearDisplay();
  hdd_display.display();
  hdd_display.setTextColor(WHITE);
  /*
    if(!apple_display.begin(SSD1306_SWITCHCAPVCC, apple_SCREEN_ADDRESS)) {
      Serial.println(F("SSD1306 allocation failed"));
      for(;;);
    }

    apple_display.clearDisplay();
    apple_display.display();
    apple_display.setTextColor(WHITE);

    if(!dell_display.begin(SSD1306_SWITCHCAPVCC, dell_SCREEN_ADDRESS)) {
      Serial.println(F("SSD1306 allocation failed"));
      for(;;);
    }

    dell_display.clearDisplay();
    dell_display.display();
    dell_display.setTextColor(WHITE);
*/
}

void loop() {
  unsigned long currentMillis = millis();

  while (Serial.available()) {
    String input_content = Serial.readString();

    if (input_content.length() > 2) {
      Serial.println(input_content);
      readAndParseJson(input_content);
      input_content = "";
    }
  }

  if (currentMillis - previousMillis >= _Interval) {
    previousMillis = currentMillis;

    Serial.println("previousMillis");

    if (i == 0 || i == 1 || i == 2 || i == 3) {
      i++;
    } else if (i == 4) {
      i = 0;
    }
  }

  doHDD(i);
  //doApple(i);
  //doDell(i);

  delay(100);
}

String getSplitValues(String data, char separator, int index) {
  int found = 0;
  int strIndex[] = { 0, -1 };
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }

  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void scanI2C() {
  for (uint8_t t = 0; t < 8; t++) {
    Wire.beginTransmission(TCAADDR);
    Wire.write(1 << t);
    Wire.endTransmission();
    Serial.print("TCA Port #");
    Serial.println(t);

    for (uint8_t addr = 0; addr <= 127; addr++) {
      if (addr == TCAADDR) continue;

      Wire.beginTransmission(addr);

      if (!Wire.endTransmission()) {
        Serial.print("Found I2C 0x");
        Serial.println(addr, HEX);
      }
    }
  }
}

void readAndParseJson(String json) {
  //https://arduinojson.org/v7/assistant
  StaticJsonDocument<512> doc;
  DeserializationError error = deserializeJson(doc, json);
  json = "";

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());

    return;
  }

  if (doc.containsKey("hardd")) {
    Serial.println("hdd");
    JsonObject hdd = doc[F("hardd")];
    hdd_warrDays = hdd[F("warrDays")];
    hdd_temp = hdd[F("temp")];
    hdd_hddST = hdd[F("hddST")];
    hdd_hddSU = hdd[F("hddSU")];
    hdd_hddPB = hdd[F("hddPB")];
    hdd_fan = hdd[F("fan")];
    _date = hdd[F("date")];
    _time = hdd[F("time")];
  } else if (doc.containsKey("apple")) {
    Serial.println("apple");
    JsonObject apple = doc[F("apple")];
    apple_os = apple[F("OS")];
    apple_hddST = apple[F("hddST")];
    apple_hddSU = apple[F("hddSU")];
    apple_hddPB = apple[F("hddPB")];
    apple_ip = apple[F("ip")];
    apple_uptime = apple[F("uptime")];
  } else if (doc.containsKey("dell")) {
    Serial.println("dell");
    JsonObject dell = doc[F("dell")];
    dell_os = dell[F("OS")];
    dell_hddST = dell[F("hddST")];
    dell_hddSU = dell[F("hddSU")];
    dell_hddPB = dell[F("hddPB")];
    dell_ip = dell[F("ip")];
    dell_uptime = dell[F("uptime")];
  }
}

void doHDD(int num) {
  hdd_display.clearDisplay();
  hdd_display.drawBitmap(0, 0, hdd, 24, 30, WHITE);

  if (num == 0) {
    //Show tempature
    hdd_display.drawBitmap(25, 0, thermometer, 24, 30, WHITE);
    hdd_display.setFont(&FreeSans9pt7b);
    hdd_display.setCursor(45, 15);
    hdd_display.print(hdd_temp);
    //hdd_display.print("100");
    hdd_display.setTextSize(1);
    hdd_display.setCursor(45, 29);
    hdd_display.print("tempature");
    hdd_display.drawBitmap(75, 0, degreesf, 24, 30, WHITE);
  } else if (num == 1) {
    //Show warranty
    hdd_display.setFont();
    hdd_display.drawBitmap(30, 1, warranty, 24, 30, WHITE);
    hdd_display.setTextSize(1);
    hdd_display.setCursor(60, 3);
    //hdd_display.print(341);
    hdd_display.print(hdd_warrDays);
    hdd_display.print(" day's");
    hdd_display.setCursor(60, 13);
    hdd_display.print("left of");
    hdd_display.setCursor(60, 23);
    hdd_display.print("warranty");
  } else if (num == 2) {
    //Show Hdd stats
    hdd_display.setFont();
    hdd_display.drawBitmap(30, 1, hddSpace, 24, 30, WHITE);
    hdd_display.setTextSize(1);
    hdd_display.setCursor(60, 3);
    //hdd_display.print("5.6TB free");
    hdd_display.print(hdd_hddST);
    hdd_display.print(" free");
    hdd_display.setCursor(60, 13);
    //hdd_display.print("of 18TB");
    hdd_display.print("of ");
    hdd_display.print(hdd_hddSU);

    //drawProgressbar(60, 25, 60, 7, atoi(hdd_hddPB));
    int progress = atoi(hdd_hddPB) > 100 ? 100 : atoi(hdd_hddPB);
    progress = progress < 0 ? 0 : progress;
    float bar = ((float)(60 - 1) / 100) * progress;
    hdd_display.drawRect(60, 25, 60, 7, WHITE);
    hdd_display.fillRect(60 + 2, 25 + 2, bar, 7 - 4, WHITE);
  } else if (num == 3) {
    //Show fan rpms
    hdd_display.setFont();
    hdd_display.drawBitmap(30, 1, fanSpeed, 24, 30, WHITE);
    hdd_display.setTextSize(1);
    hdd_display.setCursor(60, 3);
    hdd_display.print("Fan running");
    hdd_display.setCursor(60, 13);
    hdd_display.print("@ ");
    //hdd_display.print("4,102");
    hdd_display.print(hdd_fan);
    hdd_display.print(" rpm");
  } else if (num == 4) {
    //Show date/time
    hdd_display.setFont();
    hdd_display.drawBitmap(30, 1, timeAndDate, 24, 30, WHITE);
    hdd_display.setTextSize(1);
    hdd_display.setCursor(60, 3);
    //hdd_display.print("10:34pm on");
    hdd_display.print(_time);
    hdd_display.print(" on ");
    hdd_display.setCursor(60, 13);
    //hdd_display.print("Fri Sep");
    hdd_display.print(getSplitValues(_date, ' ', 0));
    hdd_display.print(" ");
    hdd_display.print(getSplitValues(_date, ' ', 1));
    hdd_display.setCursor(60, 23);
    //hdd_display.print("22nd 2024");
    hdd_display.print(getSplitValues(_date, ' ', 2));
    hdd_display.print(" ");
    hdd_display.print(getSplitValues(_date, ' ', 3));
  }

  hdd_display.display();
}

void doApple(int num) {
  String _apple_tmp[3];
  apple_display.clearDisplay();
  apple_display.drawBitmap(0, 0, apple, 24, 30, WHITE);

  if (num == 0) {
    //Show OS
    apple_display.setFont();
    apple_display.drawBitmap(30, 1, runningOS, 24, 30, WHITE);
    apple_display.setTextSize(1);
    apple_display.setCursor(60, 3);
    //apple_display.print("macOS 12.9");
    apple_display.print(getSplitValues(apple_os, ' ', 0));
    apple_display.setCursor(60, 13);
    //apple_display.print("Monterey");
    apple_display.print(getSplitValues(apple_os, ' ', 1));
    apple_display.setCursor(60, 23);
    apple_display.print(getSplitValues(apple_os, ' ', 2));
  } else if (num == 1) {
    //Show Hdd stats
    apple_display.setFont();
    apple_display.drawBitmap(30, 1, hddSpace, 24, 30, WHITE);
    apple_display.setTextSize(1);
    apple_display.setCursor(60, 3);
    //apple_display.print("5.6TB free");
    apple_display.print(apple_hddST);
    apple_display.print(" free");
    apple_display.setCursor(60, 13);
    apple_display.print("of ");
    //apple_display.print("of 18TB");
    apple_display.print(apple_hddSU);

    //drawProgressbar(60, 25, 60, 7, atoi(apple_hddPB));
    int progress = atoi(apple_hddPB) > 100 ? 100 : atoi(apple_hddPB);
    progress = progress < 0 ? 0 : progress;
    float bar = ((float)(60 - 1) / 100) * progress;
    apple_display.drawRect(60, 25, 60, 7, WHITE);
    apple_display.fillRect(60 + 2, 25 + 2, bar, 7 - 4, WHITE);
  } else if (num == 2) {
    //Show IP address
    apple_display.setFont();
    apple_display.drawBitmap(30, 1, ethernet, 24, 30, WHITE);
    apple_display.setTextSize(1);
    apple_display.setCursor(60, 3);
    //apple_display.print("192.168.1.123");
    apple_display.print("IP Address");
    apple_display.setCursor(60, 13);
    apple_display.print("...");
    apple_display.print(getSplitValues(apple_ip, '.', 2));
    apple_display.print(".");
    apple_display.print(getSplitValues(apple_ip, '.', 3));
  } else if (num == 3) {
    //Show uptime
    apple_display.setFont();
    apple_display.drawBitmap(30, 1, uptime, 24, 30, WHITE);
    apple_display.setTextSize(1);
    apple_display.setCursor(60, 3);
    //apple_display.print("35 days 17:14");
    apple_display.print("Uptime");
    apple_display.setCursor(60, 13);
    apple_display.print(getSplitValues(apple_uptime, ' ', 0));
    apple_display.print(" ");
    apple_display.print(getSplitValues(apple_uptime, ' ', 1));
    apple_display.setCursor(60, 23);
    apple_display.print(getSplitValues(apple_uptime, ' ', 2));
  } else if (num == 4) {
    //Show date/time
    apple_display.setFont();
    apple_display.drawBitmap(30, 1, timeAndDate, 24, 30, WHITE);
    apple_display.setTextSize(1);
    apple_display.setCursor(60, 3);
    //apple_display.print("10:34pm on");
    apple_display.print(_time);
    apple_display.print(" on ");
    apple_display.setCursor(60, 13);
    //apple_display.print("Fri Sep");
    apple_display.print(getSplitValues(_date, ' ', 0));
    apple_display.print(" ");
    apple_display.print(getSplitValues(_date, ' ', 1));
    apple_display.setCursor(60, 23);
    //apple_display.print("22nd 2024");
    apple_display.print(getSplitValues(_date, ' ', 2));
    apple_display.print(" ");
    apple_display.print(getSplitValues(_date, ' ', 3));
  }

  apple_display.display();
}

void doDell(int num) {
  dell_display.clearDisplay();
  dell_display.drawBitmap(0, 0, dell, 24, 30, WHITE);

  if (num == 0) {
    //Show OS
    dell_display.setFont();
    dell_display.drawBitmap(30, 1, runningOS, 24, 30, WHITE);
    dell_display.setTextSize(1);
    dell_display.setCursor(60, 3);
    //apple_display.print("Windows 11");
    dell_display.print(getSplitValues(dell_os, ' ', 0));
    dell_display.setCursor(60, 13);
    //apple_display.print("Monterey");
    dell_display.print("V. ");
    dell_display.print(getSplitValues(dell_os, ' ', 1));
    dell_display.print(dell_os);
  } else if (num == 1) {
    //Show Hdd stats
    dell_display.setFont();
    dell_display.drawBitmap(30, 1, hddSpace, 24, 30, WHITE);
    dell_display.setTextSize(1);
    dell_display.setCursor(60, 3);
    //dell_display.print("5.6TB free");
    dell_display.print(dell_hddST);
    dell_display.print(" free");
    dell_display.setCursor(60, 13);
    //dell_display.print("of 18TB");
    dell_display.print("of ");
    dell_display.print(dell_hddSU);

    //drawProgressbar(60, 25, 60, 7, atoi(dell_hddPB));
    int progress = atoi(dell_hddPB) > 100 ? 100 : atoi(dell_hddPB);
    progress = progress < 0 ? 0 : progress;
    float bar = ((float)(60 - 1) / 100) * progress;
    dell_display.drawRect(60, 25, 60, 7, WHITE);
    dell_display.fillRect(60 + 2, 25 + 2, bar, 7 - 4, WHITE);
  } else if (num == 2) {
    //Show IP address
    dell_display.setFont();
    dell_display.drawBitmap(30, 1, ethernet, 24, 30, WHITE);
    dell_display.setTextSize(1);
    dell_display.setCursor(60, 3);
    //dell_display.print("192.168.1.123");
    dell_display.print("IP Address");
    dell_display.setCursor(60, 13);
    dell_display.print("...");
    dell_display.print(getSplitValues(apple_ip, '.', 2));
    dell_display.print(".");
    dell_display.print(getSplitValues(apple_ip, '.', 3));
  } else if (num == 3) {
    //Show uptime
    dell_display.setFont();
    dell_display.drawBitmap(30, 1, uptime, 24, 30, WHITE);
    dell_display.setTextSize(1);
    dell_display.setCursor(60, 3);
    //dell_display.print("35 days 17:14");
    dell_display.print("Uptime");
    dell_display.setCursor(60, 13);
    dell_display.print(getSplitValues(apple_uptime, ' ', 0));
    dell_display.print(" ");
    dell_display.print(getSplitValues(apple_uptime, ' ', 1));
    dell_display.setCursor(60, 23);
    dell_display.print(getSplitValues(apple_uptime, ' ', 2));
  } else if (num == 4) {
    //Show date/time
    dell_display.setFont();
    dell_display.drawBitmap(30, 1, timeAndDate, 24, 30, WHITE);
    dell_display.setTextSize(1);
    dell_display.setCursor(60, 3);
    //dell_display.print("10:34pm on");
    dell_display.print(_time);
    dell_display.print(" on ");
    dell_display.setCursor(60, 13);
    //dell_display.print("Fri Sep");
    dell_display.print(getSplitValues(_date, ' ', 0));
    dell_display.print(" ");
    dell_display.print(getSplitValues(_date, ' ', 1));
    dell_display.setCursor(60, 23);
    //dell_display.print("22nd 2024");
    dell_display.print(getSplitValues(_date, ' ', 2));
    dell_display.print(" ");
    dell_display.print(getSplitValues(_date, ' ', 3));
  }

  dell_display.display();
}

Would be great if someone could look over the code and suggest areas where I could save some memory so the json works.

If you have the "classic Nano", the display buffers below already take up 3/4 of the dynamic memory.

Adafruit_SSD1306 hdd_display(128, 32, &Wire, -1);
Adafruit_SSD1306 apple_display(128, 32, &Wire, -1);
Adafruit_SSD1306 dell_display(128, 32, &Wire, -1);

you ask for 512 bytes there (it allocates the memory (a bit more than 512) on the stack at run time)

that's a lot for your small Arduino

I forgot to do v7 so it does not have it defined for it so I edited my code.

Yes, its the classic version.

You need to figure out how 2048 bytes of dynamic memory can be put to best use. 3 display buffers of 512 bytes each is probably not the best choice.

Avoid using String is possibly, that can use an unpredictable amount of ram.

The three displays are your major problem, the U8g2 library with a paged buffer will take less memory, and if you can use an I2C multiplexer or have access to the address lines for the displays its possible to use a single buffer for multiple displays.

What is in the vars.h file? I only get 825 bytes used in the compiler (which does not include the display buffers).

Indeed, that plus the static json of 512 bytes requested on the stack

= 2048 bytes ➜ the entire RAM

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.