メモリの話は複雑で、いくつかのサイトを見た上でざっくりとまとめてるため、一部内容が間違ってるかもしれません。
ESP32で使える変数のサイズ
通常のESP32(-wroom)のRAM(変数用のメモリ)は520kBで、さらに変数として使えるのは100kB~200kB(モジュールによって違う?)なので、大きな画像データなどを扱おうとするとメモリが足りないよ、ということになる。
region `dram0_0_seg’ overflowed by 96032 bytes


そのため、ESP32-wroverというモジュールはSPIで通信するRAM(PSRAM)が搭載されており、4MBとか8MBの変数を扱うことができる。(ただしArduino IDEで使えるのは4MBまで)
ESP32-DevKitC-VE ESP32-WROVER-E開発ボード 8MB
https://akizukidenshi.com/catalog/g/g115674/
PSRAM関係の関数
bool psramFound()…PSRAMがあるかの判定
uint32_t ESP.getFreePsram()…フリーなPSRAMのサイズ(Byte)
uint32_t ESP.getPsramSize()…PSRAMのサイズ(Byte)
void* ps_calloc(size_t n, size_t size)…PSRAMの変数の確保。nが配列の数、sizeが配列一つのサイズ
例:char *p = (char*) ps_calloc( n, sizeof(char) );
void free(void* p)…メモリの解放
PSRAMがあるかチェックし、あれば4MBの変数配列を作るスケッチ
書き込み時には設定のPSRAMを”Enabled”にします。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
//char data[200000];//200kB//普通に変数を作るとメモリエラー void setup() { /*//普通に変数を作るとメモリエラー for(uint32_t i=0;i<200000;i++){ data[i] = 0; }*/ Serial.begin(115200); if (psramFound()) { Serial.println("PSRAMが使えます"); Serial.print("PSRAM Free: "); Serial.println(ESP.getFreePsram()); Serial.print("PSRAM All: "); Serial.println(ESP.getPsramSize()); //SPRAM全ての容量を確保 //int memMax = ESP.getFreePsram(); int memMax = 4000000;//4MB char *p = (char*) ps_calloc( memMax, sizeof(char) ); if (p == NULL) { Serial.println("確保できず"); } else{ Serial.println("確保OK"); //1バイト毎に値が書き込めるかチェック int i = 0; while ( i < memMax ) { p[i] = (char)i; //値を書き込む if ( p[i] != (char)i ) //値が合っているかチェック { Serial.printf("write error at %d\n", i); i--; break; } i++; } Serial.printf("%d bytes check Ok\n", i); free(p); //メモリの解放 } } else { Serial.println("PSRAMが使えません"); } } |
実行結果
1 2 3 4 5 |
PSRAMが使えます PSRAM Free: 4192124 PSRAM All: 4194304 確保OK 4000000 bytes check Ok |
PSRAM Freeが4,192,124なので、このサイズまで配列が作れそうなのだが、私の環境ではなぜか4,120,000までしか配列が作れなかった。まあ4MBの配列は作れたのでひとまずOK。
まとめ
・100kB超えの変数を扱うときはPSRAM付きのESP32を使う
・PSRAMが8MBのものでもArduinoでは4MBまで(ESP-IDFでは8MB使えるらしい)
・書き込み設定のPSRAMを”Enabled”にする必要あり
コメント