SD カード

SD カードを mruby/c から利用する. SD カードリーダーはシリアル通信の 1 つである SPI でマイコンと通信を行うものであり, ここでは mrubyc for ESP32 ライブラリ に含まれる SDカード 用クラスを利用するものとする.

SPI (Serial Peripheral Interface)

SPI はモトローラ社が提唱した周辺デバイスとのシリアル通信の方式である.

  • I2C と同様に, マスタ側とスレーブ側を分け, マスタ側が全ての制御を行う.
  • 4 本の信号線から構成される. I2C と異なりデータ入力と出力は別の信号線を用いる.
    • SDI (MOSI): シリアルデータ入力
    • SDO (MISO): シリアルデータ出力
    • SCK (SCLK): シリアルクロック信号
    • SS: スレーブセレクト. スレーブが複数存在する場合には, SS1, SS2, SS3,... というように別々の信号線が必要となる.
  • 信号線にはプルアップ抵抗が必要.
    • プルアップ抵抗の説明は例えばここを参照
  • 通信速度は I2C よりも速い (1~2Mbps).
  • 通信速度が必要な SD カードドライブは SPI 接続することが多い.

プロジェクトの準備

$ cd ~/esp

$ git clone https://github.com/gfd-dennou-club/iotex-esp32-mrubyc.git mrubyc-14-sd

$ cd mrubyc-14-sd

なお,make menuconfig で SPI_SD にチェックを入れること

$ make menuconfig 

  [*] USR ESP32 SPI_SD

プログラム例

ここでは,サーバにデータを送るためのコマンドを SD カードへ保管することにする. こうしておくことで,SD カードに書かれたファイルを Linux の bash で実行するだけで データをサーバに送ることができるようになる.

例えば,送信データが以下の場合

  hostname (ホスト名) : sugiyama (各自の固有の名前にすること)
  time (時刻)         : 2021-06-14 21:00:00
  temp (温度)         : 25.0
  humi (湿度)         : 60.0
  lng  (経度)         : 133.026
  lat  (緯度)         : 35.50
  utc  (世界標準時)   : 1 (true)

送信用の URL は以下となる.但し, 日時は UTC になっているものとする.&utc=1 としておくと,サーバ上の PHP スクリプトが UTC から JST (日本標準時) への変換をしてくれる. 

  http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=sugiyama&time=20210614210000&temp=25.0&humi=60.0&lng=133.026&lat=35.50&utc=1

送信用 Linux コマンドは, 上記の URL を curl の引数に与えれば良い.

  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=sugiyama&time=20210614210000&temp=25.0&humi=60.0&lng=133.026&lat=35.50&utc=1"

送信用 Linux コマンドを SD カードに書き込む・SD カードに書かれたデータを読み込むためには, mrblib/loops/master.rb を以下のように作成すれば良い.

1  # coding: utf-8
2 
3  # 初期化
4  SDSPI.spi_bus_initialize(23, 19, 18) # Passing SDI (MOSI), SDO (MISO), SCK (SCLK)
5  SDSPI.esp_vfs_fat_sdspi_mount(2, "/sdcard") # Passing ChipSelect (CS), MountPoint
6 
7  puts "***** Writing ... *****"
8  # write mode
9  fid = ESP32_STDIO.fopen("/sdcard/data.sh", "w")
10 
11 # 書き込みを 10 回行う
12 for i in 0..9  do
13   host  = "user"             #学生番号にすること
14   time0 = "202106231310" + sprintf("%02d", i).to_s   #日時 (UTC)
15   temp  = 20.0 + i           #温度. 確認のために書き込むたびに値を変えておく
16   humi  = 70.0 + i           #湿度
17   lng   = 133.0 + 0.01 * i   #経度
18   lat   = 35.45 + 0.01 * i   #緯度
19   str   = "curl \"http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=#{host}&time=#{time0}&temp=#{temp}&humi=#{humi}&lng=#{lng}&lat=#{lat}&utc=1\"" 
20   puts str
21 
22   # Writing in with fputs.
23   ESP32_STDIO.fputs(fid, str)
24   ESP32_STDIO.fputs(fid, "\n")  #改行
25 end
26 
27 # Closing file
28 ESP32_STDIO.fclose(fid)
29 
30 puts "***** Reading... *****"
31 # Open with fopen. r is read mode, pass file name and mode.
32 fid = ESP32_STDIO.fopen("/sdcard/data.sh", "r")
33 
34 # 10 回読み込んで表示する.
35 10.times do
36   # Reading contents of file with fgets, second argument is maximum length of reading.
37   cont = ESP32_STDIO.fgets(fid, 150)
38   puts cont
39 end
40 
41 # Closing file with fclose.
42 ESP32_STDIO.fclose(fid)
43 
44 # 終了の確認
45 puts "SD card sample finished!!"

プログラムの実行

以下のように実行せよ

$ make 

$ make flash monitor

  ***** Writing ... *****
  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=user&time=20210623131000&temp=20&humi=70&lng=133&lat=35.45&utc=1"
  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=user&time=20210623131001&temp=21&humi=71&lng=133.01&lat=35.46&utc=1"
  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=user&time=20210623131002&temp=22&humi=72&lng=133.02&lat=35.47&utc=1"
  ....(略).....
  ***** Reading... *****
  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=user&time=20210623131000&temp=20&humi=70&lng=133&lat=35.45&utc=1"
  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=user&time=20210623131001&temp=21&humi=71&lng=133.01&lat=35.46&utc=1"
  curl "http://es2021.epi.it.matsue-ct.jp/~sugiyama/php/monitoring.php?hostname=user&time=20210623131002&temp=22&humi=72&lng=133.02&lat=35.47&utc=1"
  ....(略).....
  SD card sample finished!!

データの確認とサーバへの送信

実行が終わったら,実習基板の電源を切り (USB ケーブルを抜き),SD カードを取り出す. SD カードを USB リーダーに入れて,Linux PC に差し込み.ファイル data.sh が存在するか確認をする.

SD カードに含まれるファイル (data.sh) はシェルスクリプトになっているので, そのファイルをそのまま実行すれば,観測データをサーバに送信できるはずである. 但し, 実習で使っている USB Linux については, curl コマンドを先にインストールする必要がある.

$ sudo apt-get update
$ sudo apt-get install curl

$ cd  /media/user/6338-6531   <ファイルのあるディレクトリに移動. 数字は PC によって変わる可能性あり>

$ bash DATA.SH

その後,Leaflet Quick Start Guide で 上記のサンプルデータが地図上にプロットされていることを確認せよ.