【ESP32 开发】ArduinoJson联合PSRAM解决 ESP32内存过小 无限重启的问题
一、前言
最近使用ESP32 WROOM开发语音识别项目时,需要使用阵列麦克风采集信号,并进行切片取出含有语音部分的片段,进而使用base64编码将语音上传到后端服务器进行识别。
在项目开发时,发现虽然ESP32 WROOM有520KB的SRAM,但是还是无法满足语音识别的需求。
查找资料后,发现ESP32-S3N16R8带有8MB的PSRAM,ESP32-S3 PSRAM的配置与测试方法见之前的一篇笔记。
本篇文章首先介绍Arduino环境中常用的Json库ArduinoJson
的普通用法,然后介绍联合PSRAM使用的方法。
二、ArduinoJson普通用法
ArduinoJson的安装方法可以看之前的一篇笔记。在库管理器
中搜索ArduinoJson
并下载即可。
ArduinoJson官方库地址为:https://github.com/bblanchon/ArduinoJson
快速上手:ArduinoJson官方贴心地提供了Json助手
,可以根据Json格式自动生成代码:https://arduinojson.org/v6/assistant/#/step1
1. ArduinoJson V6版本库函数
库函数整理引自:finedayforu
2. 核心类JsonDocument(内存管理)
JsonDocument作为整个V6版本ArduinoJson库的内存入口,负责处理整个json数据的内存管理,分为两个实现类:
- (1)DynamicJsonDocument
内存分配在heap区,无固定大小,可以自动增长所需空间,方法调用完自动回收,建议内存大小大于1KB使用;DynamicJsonDocument doc(2048); //创建一个DynamicJsonDocument类型的doc对象,大小2048byte
- (2)StaticJsonDocument
StaticJsonDocument,内存分配在stack区,有固定大小,大小值由开发者定义,方法调用完自动回收,建议内存大小小于1KB使用;StaticJsonDocument<256> doc;
3. 具体使用案例
转自:Naisu Xu
(1)反序列化
- 引用ArduinoJson库;
- 声明JsonDocument对象;
- 尝试反序列化json字符串到JsonDocument对象;
- 根据需求取用数据;
#include <ArduinoJson.h>//声明一个json数据
char myJson[] = "{\"myChar\":\"hello\",\"myArray\":[13,14],\"myObject\":{\"myFloat\":3.1415926}}";void setup()
{Serial.begin(115200);Serial.println();//StaticJsonDocument<200> doc; //声明一个JsonDocument对象DynamicJsonDocument doc(200); //声明一个JsonDocument对象DeserializationError error = deserializeJson(doc, myJson); //反序列化JSON数据// if (error.c_str() == "OK") //检查反序列化是否成功if (!error) //检查反序列化是否成功{//读取json节点const char *myC = doc["myChar"]; //等同于const char *myC = doc["myChar"].as<char*>();int myN0 = doc["myArray"][0]; //等同于int myN0 = doc["myArray"][0].as<int>();int myN1 = doc["myArray"][1]; //等同于int myN1 = doc["myArray"][1].as<int>();float myF = doc["myObject"]["myFloat"]; //等同于float myF = doc["myObject"]["myFloat"].as<float>();Serial.println(myC);Serial.println(myN0);Serial.println(myN1);Serial.println(myF);// Serial.println(myF, n); //n指定输出小数位数}
}void loop()
{}
(2)序列化
- 引用ArduinoJson库;
- 声明JsonDocument对象;
- 向JsonDocument对象中添加数据;
- 序列化处理JsonDocument对象使成为json字符串;
#include <ArduinoJson.h>void setup()
{Serial.begin(115200);Serial.println();//StaticJsonDocument<200> doc; //声明一个JsonDocument对象DynamicJsonDocument doc(200); //声明一个JsonDocument对象doc["myChar"] = "hello"; //添加一个字符串对象节点JsonArray myA = doc.createNestedArray("myArray"); //添加一个数组节点myA.add(true); //使用add方式添加数据到JsonArraymyA.add(false);JsonObject myO = doc.createNestedObject("myObject"); //添加一个对象节点myO["myNumber"] = 1234567890; //使用[]添加数据到JsonObjectserializeJson(doc, Serial); //序列化JSON数据(压缩形式),并从Serial输出// 以下三行输出结果同上面一行// char myDoc[measureJson(doc) + 1];// serializeJson(doc, myDoc, measureJson(doc) + 1);// Serial.println(myDoc);Serial.println();Serial.println();serializeJsonPretty(doc, Serial); //序列化JSON数据(展开形式),并从Serial输出// 以下三行输出结果同上面一行// char myDocP[measureJsonPretty(doc) + 1];// serializeJsonPretty(doc, myDocP, measureJsonPretty(doc) + 1);// Serial.println(myDocP);
}void loop()
{}
三、ArduinoJson联合PSRAM用法
ArduinoJson官方对PSRAM的介绍见:https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/
ArduinoJson中默认使用malloc()
函数分配SRAM空间;而使用PSRAM需要使用heap_caps_malloc(MALLOC_CAP_SPIRAM)
函数分配空间。因此,要联合PSRAM使用,就不能像上面一样直接调用DynamicJsonDocument
下面是具体实现案例:
struct SpiRamAllocator {void* allocate(size_t size) {return heap_caps_malloc(size, MALLOC_CAP_SPIRAM);}void deallocate(void* pointer) {heap_caps_free(pointer);}void* reallocate(void* ptr, size_t new_size) {return heap_caps_realloc(ptr, new_size, MALLOC_CAP_SPIRAM);}
};using SpiRamJsonDocument = BasicJsonDocument<SpiRamAllocator>;
这个片段定义的SpiRamJsonDocument
类的使用方法与JsonDocument
一致:
SpiRamJsonDocument doc(1048576);
deserializeJson(doc, input);
注意事项:
- 不能声明一个全局变量SpiRamJsonDocument,因为它会heap_caps_malloc()在 PSRAM 准备好使用之前调用。
- 需要开启PSRAM,否则ESP32-S3会无限重启。开启方法见之前的一篇笔记。
- ArduinoJson V5和V5并不兼容,注意检查版本为V6。
完整demo如下:
【ESP32 开发】ArduinoJson联合PSRAM解决 ESP32内存过小 无限重启的问题相关推荐
- ESP32 开发之旅② Arduino For ESP32说明
从这一篇开始,博主将会带领各位读者进入ESP32开发的征程.在此,博主认为各位读者已经具备以下前提: 读者具有C语言以及Arduino的开发知识: 读者了解过博主的ESP8266开发系列: 读 ...
- ESP32 开发笔记(八)ESP32 MP3 播放器
ESP32 MP3 播放器 ESP32 MP3 播放器 开发环境 环境搭建 编译运行 运行结果 ESP32 MP3 播放器 源码地址:GitHub 开发环境 开发框架:ESP-IDF.ESP-ADF ...
- ESP32 入门笔记07: ESP-NOW (ESP32 for Arduino)
[B站乐鑫] ESP-NOW 无线通信方案 简介 ESP-NOW 是一种快速.无连接的通信技术,具有短数据包传输的特点. ESP-NOW 是乐鑫开发的一种"协议",它使多个设备无需 ...
- 解决Arduino环境下ESP8266模块无限重启崩溃问题
问题背景: 最近使用ESP8266模块(NodeMCU)在Arduino环境下进行开发调试时遇到了一个ESP8266模块无限重启崩溃的问题.这个问题不是第一次发生了,很久之前遇到了后面也不知道怎么解决 ...
- dell计算机一直重启,戴尔笔记本无限重启具体解决办法
戴尔笔记本无限重启怎么办?戴尔笔记本虽然性能良好,但若使用时间长了也难免会出现问题,若是戴尔笔记本无限重启该如何解决呢?今天小编要给大家讲解的便是戴尔笔记本无限重启的解决方法,一起来看看吧. 戴尔笔记 ...
- 超便利!教你用ESP32开发板DIY掌上网页服务器!
本文作者:默.默是铁熊的创客好友,经常与铁熊分享创意项目. 前段时间有个老师对我说:每到开学季,学校就要印刷学生的录取名单并进行张贴,为此学校每年都要耗费大量的人力物力.学校里面教学活动很多,传统的通 ...
- 物联网开发笔记(27)- 使用Micropython开发ESP32开发板之控制240x240的oled屏幕(ST7789芯片)
这一节我们讲解了如何控制240x240的oled屏幕,该oled屏幕驱动芯片是ST7789,我们控制屏幕显示两行字. 一.目的 使用MicroPython开发ESP32开发板控制240x240的ole ...
- esp32摄像显示时间_TinyPICO-比拇指还小的ESP32开发板- 国外创客众筹发现第二期
国外创客开发板创新日新月异 我们想尝鲜体验却十分苦难 一片板卡从海外跋山涉水到我们手中 遇到各种各样的问题 海外组团开始啦!~ 本次我们从国外开发板众筹网站crowdsupply 挑选一款体积较小/功 ...
- ubuntu vscode 配置字体_第五章 Ubuntu搭建ESP32开发环境(vscode)
Vscode安装 ubuntu软件中自带vscode的安装包,一键完成,不废话,没有的想办法解决. 编译链操作 下载 官方最新地址 有系统区别,下载对应的压缩到到电脑 · for 64-bit Lin ...
最新文章
- 【预告】腾讯移动分析 MTA 即刻登陆 2017 GMTC 全球移动技术大会
- 【alibaba-cloud】nacos安装
- system health_可重复使用的MicroProfile Health探针
- Java千百问_06数据结构(014)_java数组如何存储在内存中
- 《SQL Server企业级平台管理实践》读书笔记——SQL Server如何设置自动增长和自动收缩项...
- 路由器上的usb接口有什么用_路由器上面的USB接口有什么用途,你都知道吗?
- 如何直观的长时间统计Android应用的动态内存消耗
- 2019年系统分析师和系统架构师考试经验
- 如何把图片整合到war3的mpq文件中作为登录背景界面
- microhard PICO900(P900)电台配置
- 路由器配置双宽带,并相互备份使用
- 浅析DNS劫持和HTTP劫持
- 格兰杰检验的基本步骤_如何用格兰杰检验、协整对数据进行分析_格兰杰因果检验...
- python编程爱心编码_用python画爱心及代码演示
- epic games 无法 下载 unreal engine5
- Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.7.0:repackage (repackage)
- Matlab数学建模(八):评价型模型
- 对redis的keys方法替换
- 宋晓丽20190905-1 每周例行报告
- setup facatory9.0打包详细教程(含静默安装和卸载)