(6) 新しい機能を追加する(SPIFSS)。

前回の”(5)スピーカーに収納する“でラジオに以下の2つの機能を追加したいと思います。追加したい機能はコンパイル無しで

  • WiFiルータのSSIDとPasswordの変更
  • ラジオ局データの変更と追加

を行う機能です。前回までのラジオプログラムとは別にこれらの機能をコーディングし最後にラジオプログラムと合体させる予定です。

データの保存方法

データの保存方法として外部記憶機器(例えばSDカード)を使用する事も考えられますが、

  • 追加のデバイス、配線が必要
  • 保存するデータ量が小さい。

から、今回は自身のFlashを使用する、”SPIFFS” でデータを保存する事にします。

データの編集方法

データの編集方法は、

  • ESP32でHTTPサーバーを立ち上げる。
  • スマホとESP32をAP接続する。
  • サーバーのHPからデータを編集する

事にします。

SPIFFSを実装する

使用したプロジェクトの構成は以下の様になっています。


- spiffs_sample/
      - CMakeLists.txt
      - partitions_example.csv
      - sdkconfig.defaults
      - main/
                   - CMakeLists.txt
                   - main.c
      - components/
                   - spiffs_image/
                              - station.txt

先ずはパティションの設定

SPIFFSを使用するにはESP32のFlashにSPIFFSで使用する領域を設定する必要が有ります。この設定は、ルートディレクトリの下の”partitions_example.csv”で行います。

partitions_example.csv

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 1M,
storage,  data, spiffs,  ,        0xF0000,

ESP32のFlashの容量は4M。デフォルトでのパティションは上記5行目までとなっていて約1M使用しています。そこに今回は6行、”storage, data, spiffs, , 0xF0000,”を追加しSPIFFSで使用する領域の設定を行っています。これで約2MのFlash使用となります。

このファイルを使用してパティションを作成するには、”sdkconfig.defaults”で

sdkconfig.defaults

CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"

と設定する必要が有ります。これでパティションの設定が完了。

実際のプログラム

サンプルプログラムは、”/main/main.c”です。予めESP32に保存されたデータを読み出し画面に表示するプログラムです。

main.c

#include "string.h"
#include <esp_log.h>
#include "nvs_flash.h"
#include "esp_spiffs.h"

static const char *TAG = "example spiffs";

struct st_info_data {         
    char _deco[5];
    char _st_ID[20];
    char _st_URL[200];
};

struct st_info_data info_data[6];

void read_station(void)
{
	char buf[330];
    FILE *fp = NULL;
    int a,b;

	fp = fopen("/spiffs/station.txt", "r");
	for(a = 0; a < 6; a ++)
	{
		fgets(buf, 300, fp);
		buf[strlen(buf) - 1] = 0;

		*(strchr(buf, ',')) = 0;
		strcpy(info_data[a]._deco, buf);
		b = strlen(buf) + 1;

		*(strchr(&buf[b], ',')) = 0;
		strcpy(info_data[a]._st_ID, &buf[b]);
		b += (strlen(&buf[b]) + 1);
		
		strcpy(info_data[a]._st_URL, &buf[b]);
	}	
	fclose(fp);
}

void init_spiffs(void)
{
    esp_vfs_spiffs_conf_t conf = {
      .base_path = "/spiffs",
      .partition_label = NULL,
      .max_files = 5,
      .format_if_mount_failed = false
    };

    esp_vfs_spiffs_register(&conf);
}

void app_main(void)
{
	int a;
    
    ESP_ERROR_CHECK(nvs_flash_init());
    
	init_spiffs();
    read_station();
    
    for(a = 0; a < 6; a ++)
	   	ESP_LOGI(TAG, "No.%d:  _deco: %s  ID: %s URL: %s", a, info_data[a]._deco, info_data[a]._st_ID, info_data[a]._st_URL);
   
}
  • プログラムは53行から始まります。
  • 59行:init_spiffs(); SPIFFSの初期設定。
    • 本体は41行:void init_spiffs(void)  
    • 先ずコンフィグレーションを設定します。パラメータは以下の4つ
      • .base_path:Mount先へのPath。今回は、rootの下に”spiffs”フォルダーと指定
      • .partition_label:パティションの名前の指定。NULLを指定すると、”spiffs”となる様です。
      • .max_files:一度に開けるファイル数
      • .format_if_mount_failed:Mount failした時の処置の指定。trueを指定するとfailした時に フォーマットされます。
    • 50行:esp_vfs_spiffs_register(&conf); この関数でSPIFFS登録とMountを行う。
  • 60行:read_station(); データの読み込み
    • 本体は16行:void read_station(void)
    • fopen() / fclose() / fgets() / fprintf() 等一般的に関数が使用出来ます。
    • ここでは、予め保存していたデータを読み込み構造体の各要素に代入しています。
  • 62行以降: 読み込んだデータの表示

データを予め保存する

データを予め保存するには、先ずmainフォルダーの下の “CMakeLists.txt” で以下の指定を行います。

CMakeLists.txt

idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS ".")
                 
spiffs_create_partition_image(storage ../components/spiffs_image FLASH_IN_PROJECT)

4行目がそれです。ここでは予め保存するファイルの所在を指定している様です。

以下が今回保存したファイルです。”~/esp/spiffs/components/spiffs_image”の下に、”station.txt”で保存しています。

station.txt

1,0,0
1,1,0
1,2,0
2,Classic,http://yp.shoutcast.com/sbin/tunein-station.pls?id=22146
2,JAZZ1,http://yp.shoutcast.com/sbin/tunein-station.pls?id=1528122
2,TOP40,http://yp.shoutcast.com/sbin/tunein-station.pls?id=1914279
  • 構造体の要素(今回は3つ)に合わせてカンマで区切り
  • 構造体6個分のデータを保存しています

これで準備は完了です。次はコンパイルと実行です。プロジェクトをここに保存します。

コンパイルと実行

ESP32を使用することを前提にしています。モニターから、”idf.py -p [usb port] flash monitor” で、プログラムがコンパイル実行され、結果がモニターに表示されます。下記はモニターに表示された結果です。6個の構造体の要素が表示されている事が分かります。

Monitor

I (327) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (651) example spiffs: No.0:  _deco: 1  ID: 0 URL: 0
I (651) example spiffs: No.1:  _deco: 1  ID: 1 URL: 0
I (651) example spiffs: No.2:  _deco: 1  ID: 2 URL: 0
I (651) example spiffs: No.3:  _deco: 2  ID: Classic URL: http://yp.shoutcast.com/sbin/tunein-station.pls?id=22146
I (661) example spiffs: No.4:  _deco: 2  ID: JAZZ1 URL: http://yp.shoutcast.com/sbin/tunein-station.pls?id=1528122
I (671) example spiffs: No.5:  _deco: 2  ID: TOP40 URL: http://yp.shoutcast.com/sbin/tunein-station.pls?id=1914279

次回は

これでデータをESP32のFlashに保存出来る様になりました。次回はHTTPサーバを立ち上げてこのデータをHPを使って編集する事を目指します。