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 で 上記のサンプルデータが地図上にプロットされていることを確認せよ.