皆さんこんにちは。yossyです。
ラズピコを使った工作をしていると、「ファイルにセンサーのデータを保存したい!」「外部のファイルをラズピコで読み込みたい!」のように思うことがありますよね。データの保存や読み込みができれば、保存したデータを分析したり、読み込んだデータからラズピコの動作を制御したりできます。
そこで、この記事では
- SDカードを使うための準備
- MicroPythonを使ったファイルの読み書き
- CSVファイルを使う方法
を解説します。
この記事を読めば、Raspberry Pi PicoでSDカードを使って、便利にファイルを扱えるようになります!
SDカードをRaspberry Pi Picoで使う方法:基本編
それでは早速、Raspberry Pi PicoでSDカードを使う方法を解説します。
必要なもの
Raspberry Pi PicoでSDカードを使うためには、SDカードモジュールを使います。
SDカードモジュールはSPIという通信方式でラズピコと通信します。SPIは4本の通信線を使います。
SDカード本体についてですが、Raspberry Pi Picoで使うSDカードは32GBまでしか対応していません。これはSDカードのフォーマットに関係していて、SDカードをFAT32でフォーマットする必要があるためです。
・SDカードモジュール
・MicroSDカードモジュール

・MicroSDカード(32GB・アダプター付き)

配線
SDカードモジュールとRaspberry Pi Picoを配線します。
SDカードモジュールによって一部の表記が異なるので、いくつかの形式を表にしています。
詳しくは各モジュールの説明書やデータシートを確認してください。(これだけ書いても他の表記があるかもしれないです。)
SPI表記(別名含む) | SDカード表記 | Raspberry Pi Picoのピン | 説明 |
---|---|---|---|
MOSI / DI / SDI / CMD / DATA-IN | CMD | GPIO3 | Pico → SDカードへのデータ出力 |
MISO / DO / / SDO / DAT0 / DATA-OUT | DAT0 | GPIO4 | SDカード → Picoへのデータ入力 |
SCK / SCLK / CLK / CLOCK | CLK | GPIO2 | クロック信号 |
CS / SS / SDCS / Chip Select | CD*/DAT3 | GPIO5 | チップセレクト |
VCC / 3.3V / 5V | VDD | 3.3Vまたは 5V(VBUS) | 電源プラス |
GND | VSS | GND | 電源マイナス |

SPIの表記は複雑です。しっかり確認して作業しましょう!
ライブラリ(sdcard.py)のインストール
Raspberry Pi PicoでSDカードを使うためのライブラリをインストールします。
sdcard.py(https://github.com/micropython/micropython-lib/blob/master/micropython/drivers/storage/sdcard/sdcard.py)にアクセスして、右上のボタンを押して、ライブラリをコピーしましょう。


コピーしたライブラリのコードを、Thonnyで新しいファイルを作成して貼り付け。sdcard.py
という名前でRaspberry Pi Pico本体に保存します。これでライブラリのインストールは完了です。
プログラム(書き込み・読み込み)
ライブラリがインストールできたので、実際にSDカードを使うためのプログラムを書きます。
from machine import Pin, SPI
import sdcard
import os
#SPIの初期化
spi = SPI(0,
baudrate=1_000_000,
polarity=0,
phase=0,
sck=Pin(2),
mosi=Pin(3),
miso=Pin(4))
cs = Pin(5, Pin.OUT)
sd = sdcard.SDCard(spi, cs) #SDカードのオブジェクトを作成
os.mount(sd, "/sd") #SDカードをマウント
#SDカードに書き込み
with open("/sd/test.txt", "w") as f:
f.write("Hello, SDCard!")
#SDカードから読み込み
with open("/sd/test.txt", "r") as f:
print(f.read())
このプログラムを実行すると、SDカード内にtest.txt
が作成されて、シェルに中身が表示されます。PCでSDカードを読み込んでみると、test.txt
が作成されているのが確認できます。
プログラムの解説
ここからは、プログラムの解説です。
前半
from machine import Pin, SPI
import sdcard
import os
#SPIの初期化
spi = SPI(0,
baudrate=1_000_000,
polarity=0,
phase=0,
sck=Pin(2),
mosi=Pin(3),
miso=Pin(4))
cs = Pin(5, Pin.OUT)
sd = sdcard.SDCard(spi, cs) #SDカードのオブジェクトを作成
os.mount(sd, "/sd") #SDカードをマウント
前半部分を解説します。
まずは、SDカードを使うために必要なモジュール・ライブラリをインポートします。
次に、SPIの初期化を行います。今回はSPI0を使用します。baudrate
,polarity
,phase
は設定しなくても動作します。デフォルト値が同じ値になっているからですが、書いておくとデバッグするときにわかりやすいかもしれません。cs
はチップセレクトといい、SPI通信をするために必要なピンの一つです。
sdという名前でSDカードのオブジェクトを作成します。
os.mount(sd, "/sd")
は、SDカードを/sd
というフォルダにマウント(接続)。これでSDカードを使う準備ができました。
後半
#SDカードに書き込み
with open("/sd/test.txt", "w") as f:
f.write("Hello, SDCard!")
#SDカードから読み込み
with open("/sd/test.txt", "r") as f:
print(f.read())
後半の部分を解説します。
まずは書き込み。with open("/sd/test.txt", "w") as f:
は、"/sd/test.txt"
というファイルをf
として"w"(書き込みモード)
で開くという意味です。書き込みモードを指定すると、ファイルが存在しない場合は作成され、存在する場合は上書きされます。
f.write()
でf
に対して書き込みを行います。
読み込みの場合は"r"
を指定します。この場合、ファイルが存在すれば開くことができます。ただし、存在しない場合はエラーになるので、try/exceptでエラー処理するか、先にファイルが存在するかを確認してから開くようにしましょう。
読み込みでファイルを開いたら、f.read()
とするとファイルの中身を扱うことができます。
withについて
追加で、withについて説明します。
Pythonでのwith open() as f:
は、ファイル操作を安全・シンプルに行うための文法です。
基本的な書き方は次の通り。
with open("ファイル名", "モード") as f:
# ファイルを使った処理
f.write("こんにちは!")
なぜこれを使うかですが、open()
を単体で使うときのコードを見るとわかります。
f = open("test.txt", "w")
f.write("こんにちは")
f.close() # ← 忘れるとやばい
Pythonではopen()
を使ってファイルを開いたあとは、必ずclose()
してファイルを閉じる必要があります。もしclose()
し忘れると、ファイルが壊れたりするなどのトラブルに繋がります。
ここでwithを使ってファイル操作をすると、内部で
f = open("test.txt", "w")
try:
# ここに処理を書く
f.write("こんにちは")
finally:
f.close() # ← 失敗してもちゃんと閉じる!
という処理がされ、ファイル操作の成功・失敗に関わらずにclose()
してくれるのです。



とっても便利な文法ですね!
他のファイル・フォルダ操作
その他、よく使われるファイルやフォルダの操作は次の通りです。
操作 | コマンド例 |
---|---|
一覧表示 | os.listdir("/sd") |
ファイル削除 | os.remove("/sd/abc.txt") |
名前変更 | os.rename("/sd/a.txt", "/sd/b.txt") |
フォルダ作成 | os.mkdir("/sd/folder") |
フォルダ削除 | os.rmdir("/sd/folder") |
ファイル追記 | open(..., "a") |
基本的にはPythonの操作と同じですが、一部対応していないものがあるので気をつけましょう。
内部ストレージを使う
SDカードではなく、内部ストレージを使う場合はパスを"/"
にします。
SPIの設定やSDカードのライブラリをインストールする必要がないので、シンプルなファイルを扱うときは内部ストレージがおすすめです。ただし、容量が小さいので気をつけましょう。
エラーが出るときは
エラーが出る場合は、以下の点を確認してみてください。
- SDカードモジュールとラズピコの配線
- SDカードがFAT32でフォーマットされているか
- SDカードが壊れていないか
- ファイルを読み込むときに、ファイルが存在しているか
- フォルダを消すときに中身が入っていないか



一部相性問題があるSDカードもあったりします。
応用編:Raspberry Pi PicoでCSVファイルを使う
応用編として、Raspberry Pi PicoでCSVファイルを使う方法を紹介します。CSVファイルを使えばデータの処理がとても行いやすくなります。
CSVファイルとは?
CSVファイルは、カンマで区切られたテキストファイルで、表形式のデータを保存するのに使われます。例えば、次のようなデータがあるとします。
名前,年齢,職業
山田太郎,20,学生
田中花子,25,会社員
佐藤健,30,医師
エクセルやGoogleスプレッドシートなどの表計算ソフトで開くと、写真のように表示することができます。


CSVファイルを使えば、データを使いやすい形式で扱うことができます。
CSVファイルを使うためのプログラム
このプログラムでは、ラズピコのADC4に接続された内蔵温度センサーの値を10回計測し、CSV形式で保存します。
from machine import ADC, Pin, SPI
import sdcard
import os
import time
# SPI & SDカードの初期化
spi = SPI(0,
baudrate=1_000_000,
polarity=0,
phase=0,
sck=Pin(2),
mosi=Pin(3),
miso=Pin(4))
cs = Pin(5, Pin.OUT)
sd = sdcard.SDCard(spi, cs)
os.mount(sd, "/sd")
# ファイルパス
file_path = "/sd/data.csv"
# ヘッダーが無ければ追加
if "data.csv" not in os.listdir("/sd"):
with open(file_path, "w") as f:
f.write("count,temperature_C\n")
# 内蔵温度センサー(ADC4)
sensor_temp = ADC(4)
# 計測ループ
for i in range(10): # 10回測定(必要に応じて変更OK)
# センサーから値を取得
reading = sensor_temp.read_u16()
# 温度に変換(公式式)
voltage = reading * 3.3 / 65535
temperature = 27 - (voltage - 0.706) / 0.001721
# ファイルに追記
with open(file_path, "a") as f:
f.write(f"{i+1},{temperature:.2f}\n")
print(f"{i+1}回目: {temperature:.2f}℃")
time.sleep(1) # 1秒ごとに記録
これを実行すると、SDカードにdata.csv
が作成されて計測回数と内部温度センサーの値が保存されます。
もしこれをPCで開く際、Excelを使用すると文字化けする場合があるので気をつけてください。治す方法はありますが、Googleスプレッドシートで開くと正しく表示されるのでそちらをおすすめします。
プログラムの解説
前半はほとんど変わらないので説明は省きます。
# ファイルパス
file_path = "/sd/data.csv"
# ヘッダーが無ければ追加
if "data.csv" not in os.listdir("/sd"):
with open(file_path, "w") as f:
f.write("count,temperature_C\n")
この部分はdata.csv
が/sd
内になければ、新しくファイルを作成して、ヘッダーを追加します。
if文の条件式にあるin
は、リストや文字列の中に要素があるかをチェックします。今回はnot in
なので、要素がなければ中の処理が実行されます。
ここからメインのプログラムです。
# 内蔵温度センサー(ADC4)
sensor_temp = ADC(4)
# 計測ループ
for i in range(10): # 10回測定(必要に応じて変更OK)
# センサーから値を取得
reading = sensor_temp.read_u16()
# 温度に変換(公式式)
voltage = reading * 3.3 / 65535
temperature = 27 - (voltage - 0.706) / 0.001721
# ファイルに追記
with open(file_path, "a") as f:
f.write(f"{i+1},{temperature:.2f}\n")
print(f"{i+1}回目: {temperature:.2f}℃")
time.sleep(1) # 1秒ごとに記録
温度センサーのオブジェクトを作成してセンサーから値を読み取り、生の値→電圧→温度と変換します。
計算した温度をファイルに追記します。追記モードでファイルを開くには"a"
を指定します。
データを書き込むときに、f.write(f"{i+1},{temperature:.2f}\n"
)と難しそうな書き方をしていますが、やってることがわかれば簡単です。
まずf"{変数・式}"
の部分は、{}の中に書いてある変数や式を文字列に埋め込む事ができます。また、後ろに:.2fとすると、小数第2位までにする事ができます。今回それぞれの{}の中身は、
i+1
→計測回数temperature:.2f
→温度の小数第2位まで
となっています。
次に、\n
ですが、これは改行を表します。CSVは行ごとに改行されるので、行の最後に\n
を追加しています。
おまけ:CSVをラズピコで読み取る
先ほどのコードで作成したCSVを、1行ずつ読み取るコードです。
file_path = "/sd/data.csv"
with open(file_path, "r") as f:
# 最初の1行(ヘッダー)を読み飛ばす
header = f.readline()
# 残りの行を1つずつ読み込む
for line in f:
line = line.strip() # 改行を取り除く
values = line.split(",") # カンマで区切る
count = int(values[0]) # 回数(int型に変換)
temp = float(values[1]) # 温度(float型に変換)
print(f"{count}回目の温度: {temp}℃")
読み込みでファイルを開いた後、f.readline()
をして1行目を読み飛ばす処理をします。これはPythonのファイルオブジェクトが読み取り位置を覚えているので、次の処理でデータがある2行目にアクセスできるようにするためです。
そうしたら、for文で2行目から1行ずつ読み込みます。.strip()
で改行を取り除き、.split(",")
を使ってカンマで区切ります。



stripとsplit、若干名前がややこしいですね
あとはintやfloatなどに加工して、使うことができます。読み取ったデータを2次元配列にすると便利そうです。
まとめ
今回はRaspberry Pi PicoでSDカードを使う方法を紹介しました。
SPIやファイルの操作など、難しい話が多かったかもしれません。できるだけわかりやすく説明することを心がけました。
SDカードはCSVを使ってログを保存したり、外部のデータを使ったりするのにピッタリなのでぜひ活用したいですね。