Flash 如何在ESP32的闪存中存储数据?

Flash 如何在ESP32的闪存中存储数据?,flash,compiler-errors,esp32,Flash,Compiler Errors,Esp32,我正试图用它将数据存储到ESP32闪存中。我特别使用它来写和读浮点值。我刚刚在代码中添加了一个Serial.println(“error”),如下所示- for (uint8_t i = 0; i < arrayLen(floatAddr); i++) { if (flash.writeFloat(0x00, testFloat[i])) { Serial.print(testFloat[i]); Serial.print(" wr

我正试图用它将数据存储到ESP32闪存中。我特别使用它来写和读浮点值。我刚刚在代码中添加了一个Serial.println(“error”),如下所示-

for (uint8_t i = 0; i < arrayLen(floatAddr); i++) 
  {
    if (flash.writeFloat(0x00, testFloat[i])) 
    {
      Serial.print(testFloat[i]);
      Serial.print(" written to 0x");
      Serial.println(floatAddr[i], HEX);
    }
    else
    {
      Serial.println("error");
    }
    
    _float = flash.readFloat(floatAddr[i]);
    Serial.print(_float);
    Serial.print(" read from 0x");
    Serial.println(floatAddr[i], HEX);
  }
#include<SPIMemory.h>

#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
// Required for Serial on Zero based boards
#define Serial SERIAL_PORT_USBVIRTUAL
#endif

#if defined (SIMBLEE)
#define BAUD_RATE 250000
#else
#define BAUD_RATE 115200
#endif

#define arrayLen(x) sizeof(x)/sizeof(x[0])
uint32_t strAddr[3], floatAddr[2], byteAddr[4];
String testStr[] = {
  "Test String 0",
  "Test String 1",
  "Test String 2"
};
float testFloat[] = {
  3.1415, 6.283
};
byte testByte[] = {
  3, 245, 84, 100
};
int8_t SPIPinsArray[] = {18,21,19,5}; //sclk,miso,mosi,ss
//SPIFlash flash(SS1, &SPI1);       //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus
//SPIFlash flash;
SPIFlash flash(int8_t *SPIPinsArray);
void getAddresses();
void writeData();
void setup() {
  Serial.begin(BAUD_RATE);
#if defined (ARDUINO_ARCH_SAMD) || (__AVR_ATmega32U4__) || defined(ARCH_STM32)
  while (!Serial) ; // Wait for Serial monitor to open
#endif
  delay(50); //Time to terminal get connected
  Serial.print(F("Initialising Flash memory"));
  for (int i = 0; i < 10; ++i)
  {
    Serial.print(F("."));
  }
  Serial.println();
  flash.begin();
  
  Serial.println();
  Serial.println();

 // getAddresses();
  dataIO();
  //flash.eraseChip();      // Uncomment this if you would like to erase chip
}

void loop() 
{

}



// Function to write data
void dataIO() 
{
  uint8_t _byte;
  float _float;
  String _string;
 

  for (uint8_t i = 0; i < arrayLen(floatAddr); i++) 
  {
    if (flash.writeFloat(0x00, testFloat[i])) 
    {
      Serial.print(testFloat[i]);
      Serial.print(" written to 0x");
      Serial.println(floatAddr[i], HEX);
    }
    else
    {
      Serial.println("error");
    }
    
    _float = flash.readFloat(floatAddr[i]);
    Serial.print(_float);
    Serial.print(" read from 0x");
    Serial.println(floatAddr[i], HEX);
  }

  
}
for(uint8\u t i=0;i
如果我运行此代码,错误语句将被打印出来,即flash.write不工作。我刚才在页面上看到一些说明,对于ESP32,需要进行一些修改。 *

“的备用版本SPIFlash flash(SPIPinsArray) 构造函数可用于(目前仅适用于ESP32板)启用 自定义SPI引脚的使用。SPIPinsArray必须是4元素数组 包含中的自定义SPI管脚号(作为有符号整数-int8_t) 顺序如下:sck、味噌、mosi、ss。 还要确保在void setup()中包含flash.begin(CHIPSIZE*)。这使库能够检测安装的闪存芯片类型 并加载正确的参数。 *可选“

所以我修改了我的代码如下-

for (uint8_t i = 0; i < arrayLen(floatAddr); i++) 
  {
    if (flash.writeFloat(0x00, testFloat[i])) 
    {
      Serial.print(testFloat[i]);
      Serial.print(" written to 0x");
      Serial.println(floatAddr[i], HEX);
    }
    else
    {
      Serial.println("error");
    }
    
    _float = flash.readFloat(floatAddr[i]);
    Serial.print(_float);
    Serial.print(" read from 0x");
    Serial.println(floatAddr[i], HEX);
  }
#include<SPIMemory.h>

#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
// Required for Serial on Zero based boards
#define Serial SERIAL_PORT_USBVIRTUAL
#endif

#if defined (SIMBLEE)
#define BAUD_RATE 250000
#else
#define BAUD_RATE 115200
#endif

#define arrayLen(x) sizeof(x)/sizeof(x[0])
uint32_t strAddr[3], floatAddr[2], byteAddr[4];
String testStr[] = {
  "Test String 0",
  "Test String 1",
  "Test String 2"
};
float testFloat[] = {
  3.1415, 6.283
};
byte testByte[] = {
  3, 245, 84, 100
};
int8_t SPIPinsArray[] = {18,21,19,5}; //sclk,miso,mosi,ss
//SPIFlash flash(SS1, &SPI1);       //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus
//SPIFlash flash;
SPIFlash flash(int8_t *SPIPinsArray);
void getAddresses();
void writeData();
void setup() {
  Serial.begin(BAUD_RATE);
#if defined (ARDUINO_ARCH_SAMD) || (__AVR_ATmega32U4__) || defined(ARCH_STM32)
  while (!Serial) ; // Wait for Serial monitor to open
#endif
  delay(50); //Time to terminal get connected
  Serial.print(F("Initialising Flash memory"));
  for (int i = 0; i < 10; ++i)
  {
    Serial.print(F("."));
  }
  Serial.println();
  flash.begin();
  
  Serial.println();
  Serial.println();

 // getAddresses();
  dataIO();
  //flash.eraseChip();      // Uncomment this if you would like to erase chip
}

void loop() 
{

}



// Function to write data
void dataIO() 
{
  uint8_t _byte;
  float _float;
  String _string;
 

  for (uint8_t i = 0; i < arrayLen(floatAddr); i++) 
  {
    if (flash.writeFloat(0x00, testFloat[i])) 
    {
      Serial.print(testFloat[i]);
      Serial.print(" written to 0x");
      Serial.println(floatAddr[i], HEX);
    }
    else
    {
      Serial.println("error");
    }
    
    _float = flash.readFloat(floatAddr[i]);
    Serial.print(_float);
    Serial.print(" read from 0x");
    Serial.println(floatAddr[i], HEX);
  }

  
}
#包括
#如果已定义(ARDUINO_SAMD_ZERO)和已定义(SERIAL_PORT_USBVIRTUAL)
//零基板上的串行数据需要
#定义串行_端口_USBVIRTUAL
#恩迪夫
#如果定义(simble)
#定义波特率250000
#否则
#定义波特率115200
#恩迪夫
#定义arrayLen(x)sizeof(x)/sizeof(x[0])
uint32_t strAddr[3],floatAddr[2],byteAddr[4];
字符串testStr[]={
“测试字符串0”,
“测试字符串1”,
“测试字符串2”
};
浮点测试浮点[]={
3.1415, 6.283
};
字节testByte[]={
3, 245, 84, 100
};
int8_t SPIPinsArray[]={18,21,19,5}//sclk、味噌、摩西、ss
//SPIFlash闪存(SS1和SPI1)//如果使用默认SPI以外的SPI总线,请使用此构造函数。仅适用于具有多个硬件SPI总线的芯片
//闪光;
SPIFlash闪光(int8_t*SPIPinsArray);
void getAddresses();
无效写入数据();
无效设置(){
串行开始(波特率);
#如果定义(ARDUINO_ARCH_SAMD)| | | | | | | | | | | | | | | | | | | | |定义(ARCH
while(!Serial);//等待串行监视器打开
#恩迪夫
延迟(50);//连接终端的时间
串行打印(F(“初始化闪存”);
对于(int i=0;i<10;++i)
{
连续打印(F(“.”);
}
Serial.println();
flash.begin();
Serial.println();
Serial.println();
//getAddresses();
dataIO();
//flash.eraseChip();//如果要擦除芯片,请取消对此的注释
}
void循环()
{
}
//用于写入数据的函数
void dataIO()
{
uint8_t_字节;
浮动(u float);;
字符串_字符串;
对于(uint8_t i=0;i
但是当我这样做的时候,我得到了以下错误-

请求“flash”中的成员“begin”,该成员为非类类型 'SPIFlash(int8_t*){aka SPIFlash(signed char*)}'flash.begin


这个错误意味着什么?我无法调试它。有人能帮我解决这个问题吗?

有些ESP32集成了闪存。有些使用外部闪存芯片。该闪存保存应用程序固件,可能有一个文件系统(通常是SPIFFS),也可能有一个键值存储(NVS)。该闪存是ESP32上的主闪存,通常是唯一的闪存

您尝试使用的库无法与我上面描述的主闪存正常工作。您尝试使用的库需要将辅助闪存芯片连接到ESP32。如果它确实使用了主闪存,它将控制它并干扰ESP32运行固件的能力。仅当您将辅助闪存连接到ESP32时才使用此库


要使用ESP32附带的闪存,请将其用于文件系统或将(NVS)用于键值存储。两者都是ESP32的Arduino内核的一部分,易于使用,不需要第二个SPI闪存芯片。

hi@romkey,我的应用程序需要在闪存中每秒存储大约50个浮点值,大约5小时。我考虑过使用spiffs,但它需要对文件进行写入和读取,但并没有提供访问单个字节的自由。我想将数据存储到特定地址,并从这些地址读取数据(应该能够在我的esp32 wroom上读取和写入超过4MB闪存的数据)。我尝试使用eeprom.read和write,但它不允许我的地址超过4kB。我还没有尝试使用首选项,但是如何使用flash来存储如此大量的数据呢?首选项对于大量的数据没有好处。使用SPIFFS写入二进制文件。批量写入,以尽量减少实际写入闪存的次数。然后使用
lseek()
访问特定位置的数据。请注意,大多数ESP32中的闪存只能进行大约100000次写入,因此很容易因为存储内容过于频繁而破坏它。SPIFFS有助于磨损均衡,但尽量减少写入。不管你怎么做,如果没有额外的外部闪存芯片,你引用的库是无用的。还要注意,你的ESP32中的一些4MB已经用于存储你的应用程序固件。你不能全部使用。谢谢你的帮助