[ESP32] ESP32のPSRAM使い方

こんにちは
今回はESP32のモジュールにあるPSRAMの使い方を書いてみたいと思います。
JSONや大量のデータをWEBやアプリから受信して、使うことがありました。


## 使ったモジュール

PSRAMは
- ESP32-WROVER-B
- ESP32-WROVER-I
しかいないので、確認してみてください。

- https://www.wemos.cc/en/latest/d32/d32_pro.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/b99bee90-1268-12bc-193b-df005ec139ac.png)

## PSRAMの設定

- 簡単です。
- Arduino　IDEでTools > PSRAM > DisableをEnabledに変える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/88ce81e1-098a-c73d-064a-f02bfbbcc194.png)

- ESP32 Wrover Moduleを持って使っている方はComplieのとき、DefaultでPSRAMを使うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/b2a265b3-7ee7-1537-3824-59fe281da717.png)


# 例1

```c:main.ino
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  //PSRAM Initialisation
  if (psramInit()) {
    Serial.println("\nThe PSRAM is correctly initialized");
  } else {
    Serial.println("\nPSRAM does not work");
  }

  log_d("Total heap: %d", ESP.getHeapSize());
  log_d("Free heap: %d", ESP.getFreeHeap());
  log_d("Total PSRAM: %d", ESP.getPsramSize());
  log_d("Free PSRAM: %d", ESP.getFreePsram());
}

void loop() {
  // put your main code here, to run repeatedly:

}
```
## 例1の結果

```terminal
16:17:58.266 -> rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
16:17:58.266 -> configsip: 0, SPIWP:0xee
16:17:58.266 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
16:17:58.266 -> mode:DIO, clock div:1
16:17:58.266 -> load:0x3fff0030,len:1252
16:17:58.266 -> load:0x40078000,len:12716
16:17:58.266 -> load:0x40080400,len:3068
16:17:58.266 -> entry 0x400805e4
16:17:58.403 -> 
16:17:59.264 -> The PSRAM is correctly initialized
16:17:59.264 -> [   881][D][sketch_apr10a.ino:11] setup(): Total heap: 394571
16:17:59.264 -> [   882][D][sketch_apr10a.ino:12] setup(): Free heap: 335479
16:17:59.264 -> [   884][D][sketch_apr10a.ino:13] setup(): Total PSRAM: 4192139
16:17:59.264 -> [   889][D][sketch_apr10a.ino:14] setup(): Free PSRAM: 4192139

```

## getPsramSize()

- https://github.com/espressif/arduino-esp32/blob/371f382db7dd36c470bb2669b222adf0a497600d/cores/esp32/Esp.h#L73

- https://github.com/espressif/arduino-esp32/blob/371f382db7dd36c470bb2669b222adf0a497600d/cores/esp32/Esp.cpp#L134

```
uint32_t EspClass::getPsramSize(void)
{
    multi_heap_info_t info;
    heap_caps_get_info(&info, MALLOC_CAP_SPIRAM);
    return info.total_free_bytes + info.total_allocated_bytes;
}
```

## psramInit()

- https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-psram.c
- https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-psram.h

# 例2

```c
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  //PSRAM Initialisation
  if (psramInit()) {
    Serial.println("\nThe PSRAM is correctly initialized");
  } else {
    Serial.println("\nPSRAM does not work");
  }

  log_d("Total heap: %d", ESP.getHeapSize());
  log_d("Free heap: %d", ESP.getFreeHeap());
  log_d("Total PSRAM: %d", ESP.getPsramSize());
  log_d("Free PSRAM: %d", ESP.getFreePsram());

  //Create an integer
  int *var_int = (int *) ps_malloc(sizeof(int));
  *var_int = 42;
  log_d("var_int PSRAM: %d", ESP.getPsramSize());
  log_d("var_int PSRAM: %d", ESP.getFreePsram());
  
  //Create a float
  float *var_float = (float *) ps_malloc(sizeof(float));
  *var_float = 42.42;

  log_d("var_float PSRAM: %d", ESP.getPsramSize());
  log_d("var_float PSRAM: %d", ESP.getFreePsram());

  Serial.println((String)"var_int = " + *var_int);
  Serial.print("var_float = ");
  Serial.println(*var_float);

}

void loop() {
  // put your main code here, to run repeatedly:

}
```

## 例２の結果

```terminal
16:33:16.824 -> The PSRAM is correctly initialized
16:33:16.824 -> [   881][D][sketch_apr10a.ino:11] setup(): Total heap: 394571
16:33:16.824 -> [   882][D][sketch_apr10a.ino:12] setup(): Free heap: 335479
16:33:16.824 -> [   884][D][sketch_apr10a.ino:13] setup(): Total PSRAM: 4192139
16:33:16.824 -> [   889][D][sketch_apr10a.ino:14] setup(): Free PSRAM: 4192139
16:33:16.824 -> [   895][D][sketch_apr10a.ino:19] setup(): var_int PSRAM: 4192127
16:33:16.824 -> [   901][D][sketch_apr10a.ino:20] setup(): var_int PSRAM: 4192123
16:33:16.869 -> [   907][D][sketch_apr10a.ino:26] setup(): var_float PSRAM: 4192115
16:33:16.869 -> [   913][D][sketch_apr10a.ino:27] setup(): var_float PSRAM: 4192107
16:33:16.869 -> var_int = 42
16:33:16.869 -> var_float = 42.42

```

# 参考
1. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/external-ram.html
2. https://github.com/TridentTD/arduino_esp32_himem

## おわりに
- あと、続きます。