LoginSignup
2
1

More than 1 year has passed since last update.

【備忘録】【ESP32】MicroPythonでSDカードにpythonコードを書き込み、SDカード上のpythonコードを実行する

Last updated at Posted at 2022-08-21

0. はじめに

(ラズパイが入手困難なこともあり)今更ながら、最近、ESP32にハマっています。今回は、
MicroPythonでSDカードの読み書きとSDカード上のpythonコードを実行する方法を、備忘録としてまとめておきます。

なお、SDカードのアクセスはSPI接続です。

1. SDカードアダプタ

数年前に製作した、マイクロSDカードのSDカードアダプタに直接ピンヘッダをハンダ付けした物を使用します。3.3VのMCUなら直接接続できます。

2.54mmピッチのピンヘッダがギリフィット。各ピンの意味は下表の通り。
SPIでアクセスする場合は1〜7番ピンのみ接続するため、8・9番ピンのハンダ付けは不要です。

ピン SDモード SPIモード
1 CD / DAT3 CS
2 CMD MOSI
3 VSS1 VSS1
(GND)
4 VDD VDD
5 CLK SCK
6 VSS2 VSS2
(GND)
7 DAT0 MISO
8 DAT1 -
9 DAT2 -

2. ESP32との接続

今回はslot=2を使用し、ESP32の推奨ピンに接続します。

「MISOに指定したピンをプルアップする必要がある」という記事がありますが、無くても問題なく読み書きできます。ただし、これが原因でSDカードやMCUが破損しても責任は持てませんので、自己責任でお願いします。

SDカードアダプタ SPI ESP32
1 CS 5
2 MOSI 23
3 GND GND
4 3v3 3.3V
5 SCK 18
6 GND GND
7 MISO 19

3. SDカードのハンドリング

FAT32でフォーマットしたまっさらなマイクロSDカードを装着しESP32をPCに接続。念のためリセットSWポチ。

ターミナル等からESP32のREPLにアクセス

ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4540
ho 0 tail 12 room 4
load:0x40078000,len:12788
load:0x40080400,len:4176
entry 0x40080680
MicroPython v1.19.1 on 2022-06-18; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>> 

>>> from machine import SDCard
>>> import os
>>> sd = SDCard(slot=2) #slot=2を使用、ESP32の推奨ピンに接続のためパラメタ省略
>>> os.mount(sd, '/sd')
>>> os.mkdir('/sd/lib') #libサブフォルダ作成
>>> os.chdir('/sd/lib')
>>> os.listdir()
[]     #当然ながら空っぽ

#pythonコードを書き込む
>>> f = open('hello.py', 'w')
>>> f.write('print("hello!")')
15
>>> f.close()
>>> 

>>> os.listdir()
['hello.py']     #ファイルが作成された
>>> 

#ファイルを読み出す
>>> f.close()
>>> f = open('hello.py', 'r')
>>> print(f.read())
print("hello!")  #読めました
>>> f.close()

>>> import sys
>>> sys.path
['', '.frozen', '/lib']
>>> sys.path.append('/sd/lib') #pathに追加
>>> sys.path
['', '.frozen', '/lib', '/sd/lib']
>>> 

#SDカード上のhello.pyを実行
>>> import hello
hello!
>>> 

以上のコードで、①SDカードのマウント②テキストファイル書き込み③テキストファイル読み込み④SDカード上のpythonコード実行 ができました。

コード全体
from machine import SDCard
import os
sd = SDCard(slot=2)
os.mount(sd, '/sd')
os.mkdir('/sd/lib')
os.chdir('/sd/lib')
os.listdir()

f = open('hello.py', 'w')
f.write('print("hello!")')
f.close()

os.listdir()

f = open('hello.py', 'r')
print(f.read())
f.close()

import sys
sys.path.append('/sd/lib')
sys.path

import hello

4. SDカードアクセスの性能

以下のコードにて、SDカード上のテキストファイルのアクセス性能を調べてみた。

  • 入力ファイル:1行100文字(UTF-8、改行コード含め101バイト)x 12,800行 = 1,292,800バイト(約1.2MB)/sd/work.txt
  • 入力メソッド:readline()
  • ファイルopen〜closeまでの時間
read_file.py
import utime
start = utime.ticks_us()
f = open('/sd/work.txt', 'r')
cnt = 0
while line := f.readline():
    cnt += 1

f.close()
print('start', start)
print('end', end := utime.ticks_us())
print('duration', end - start)
print('cnt', cnt)

2回測定し、平均で約10.5秒であった。
読み込み性能としては、約120KB/秒。かなり遅い?

結果
# 1回目
start 54995341
end 65450884
duration 10455543
cnt 12800
# 2回目
start 90385829
end 100999955
duration 10614126
cnt 12800

Seeeduino XIAO SAMD21で同じファイルの入力を測定したところ、約20.9秒でした。ESP32の方が2倍速い。

この性能の差は? と考えたとき、両デバイスのCPUクロック数の違いですかね?
Seeeduino XIAOは48MHz、ESP32は160MHz240MHz。ちなみに、上記の性能は160MHzのときで、デフォルトは160MHzのようです。

import machine
machine.freq()
160000000

240MHzに変更して再度測定したところ、秒8.3秒に縮まった。約152KB/秒と160MHz時の約27%アップ。

machine.freq(240000000) # 240MHzに設定

240MHzにすることで消費電力も多くなるでしょうが、プログラムからCPUクロック数を動的に変えられるとは驚きです。

5. おわりに

SDカードのアクセス速度は速くはないが、大量の情報を保持できるというメリットがありますね。ただ、ESP32ならクラウドへ保存する方が一般的なのかも?

SDモード(4ビットバス)接続の場合は、どのくらいアクセスが速くなるのだろうか? 別途、測定してみたいと思います。

以上

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1