假设对象名称匹配 (ArduinoJson),如何将 json 对象的所有成员复制到二维数组

How to copy all members of a json object to a 2d array given that the object name matches (ArduinoJson)

我正在进行一个 Arduino 项目,该项目将为我调配鸡尾酒。我决定将鸡尾酒列表保存在名为 cocktails.json 的 JSON 文件中,该文件保存在 SD 卡上,在选择鸡尾酒时,我希望 Arduino 在 JSON 文件。 JSON 的一小段如下所示:

{
  "Cocktails": {
        "Americano": {
            "campari": 1
            "red vermouth": 2
            "soda": 3
        },
        "Aviation": {
            "gin": 1,
            "cherry liqueur": 2,
            "creme de violette": 3,
            "lemon juice": 4
        },
        "B52 Cocktail": {
            "kahlua": 1,
            "baileys": 2,
            "trand marnier": 3
        }
    }
}

假设我告诉 Arduino 我想要鸡尾酒“Americano”。我希望 Arduino 复制对象“Americano”下的所有数据并将其保存到我在以下结构中创建的二维数组:


struct cocktailData
{
  char name[25];
  char portions[7][1];
} data;

数组初始化为 [7][1],因为最多有 8 种可能的成分,并且它们都与一个数量乘数配对。我不知道如何将整个字符串复制到数组中,以便将食谱保存在内存中。我正在使用 ArduinoJson 库来解析 JSON 文件。 最终目标是数组看起来像这样:


portions[0-7][0]=

"campari", "red vermouth", "soda", (the rest is null)

portions[0-7][1]=
1, 2, 3, (the rest is null)

正如我在评论中提到的,如果您将数据保存在 SD 中(并编写 C++),则无需添加额外的 encoding/decoding 或 JSON 层,您可以读写具有 C++ 结构的数据。

在展示如何将结构 read/write 写入文件之前,你展示的结构不会保存你想要表示的数据,每个鸡尾酒配方都由名称(字符串)和数组组成成分,每个成分由一个字符串和字节组成,代表酒的类型和部分。所以我们正在处理结构中的结构。

typedef struct {
  char liquor[20];
  uint8_t portion;
} Ingridient;

typedef struct {
  char name[20];
  Ingridient ingridients[7];
} Cocktail;

Cocktail cocktails[] = {
    {"Americano", { {"campari", 1}, {"red vermouth", 2}, {"soda", 3} } },
    {"Aviation", { {"gin", 1}, {"cherry liqueur", 2}, {"creme de violette", 3}, {"lemon juice", 4} } },
    {"B52 Cocktail", { {"kahlua", 1}, {"baileys", 2}, {"trand marnier", 3} } }
};

将结构写入文件或从文件中读取结构就像将一系列字节写入文件一样,您需要做的就是告诉您的结构在内存中的位置(即指向结构),结构的大小是多少。

由于我没有带SD卡的Arduino,所以我在ESP32上使用SPIFFS展示它,它应该与SD非常相似,并且您可以将代码转换为使用SD 卡。

这是完整的例子。

#include <SPIFFS.h>

typedef struct {
  char liquor[20];
  uint8_t portion;
} Ingridient;

typedef struct {
  char name[20];
  Ingridient ingridients[7];
} Cocktail;

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

  Cocktail cocktails[] = {
    {"Americano", { {"campari", 1}, {"red vermouth", 2}, {"soda", 3} } },
    {"Aviation", { {"gin", 1}, {"cherry liqueur", 2}, {"creme de violette", 3}, {"lemon juice", 4} } },
    {"B52 Cocktail", { {"kahlua", 1}, {"baileys", 2}, {"trand marnier", 3} } }
  };
 
  if(!SPIFFS.begin()){
      Serial.println("Error while mounting SPIFFS");
      return;
  }
 
  //--------- Write a struct to file
  File fileToWrite = SPIFFS.open("/cocktails.txt", FILE_WRITE);
  
  if(fileToWrite) {
    for (int i=0; i<3; i++) {
      fileToWrite.write( (uint8_t *) &cocktails[i], sizeof(cocktails[i]) );
    }
  }
  
  fileToWrite.close();
  
  
  //---------- Read a struct from file
  Cocktail c[3];  //struct for holding the content from the file
  
  File fileToRead = SPIFFS.open("/cocktails.txt");
  
  if(fileToRead) {
    Serial.println("Data from file...");
    for (int i=0; i<3; i++) {
      fileToRead.read( (byte *) &c[i], sizeof(c[i]) );
      Serial.println(c[i].name);
      int n = 0;
      while (strlen(c[i].ingridients[n].liquor)) {
        Serial.print(c[i].ingridients[n].liquor);
        Serial.print(" - ");
        Serial.print(c[i].ingridients[n].portion);
        n++;
      }
      Serial.println();
    }
  }

  fileToRead.close();
}
 
void loop() {}