今までひずみアンプとかSDカード、LCDなどとの接続でSPIは使っていたのですが、
マイコン間の通信で使うのは初めてなので、基礎からじっくりいじることにしました。
※2023年12月31日に4.6Mbpsまでノーエラーで3回ほどやって確認したのですが、2024年1月1日に再度やってみるとこの条件だとエラーが発生しました。100μsec遅延いれてまだ不安定なので、120から150μsecで安定が増してますが、これでいいかどうか未だわかりません。3-4Mbpsはでるということしか未だ言えません。
SPIは、ばらつきがあるので、統計的なエラー測定をしないといけないことが判りましたので、
繰り返し測定してみます。更に、ESP32にUDP機能をいれるので、更に処理時間が遅れて遅くなると思います。Mbpsレベルんの高速転送となるとエラー率が課題となることを新年最初に体験できて良かったです。
●基礎知識の資料
アナログデバイス社の記事が判り易いです。SPIの基本を学ぶ
※SPIの特徴は、2本の上り下りの信号線が同時に双方向通信をする点です。命令1行で送受信してます。
送った信号を戻すには、次のタイミングで返信させれば、送ったデータが大丈夫か確認できます。
●teensy4-ESP32のSPI通信サンプルプログラムを使わせていただいた記事に感謝
QIITAの@Ninagawa123(Izumi Ninagawa)様に感謝
SPI通信 (ESP32スレーブ←→Teensy4.0マスター)
●準備
①SPI配線備忘録
上記参照記事の通りに配線しました。
◆配線で発生したトラブル
接触不良で、クロック波形が鈍ってしまったので、丸ピン接続はやめて、直付けにした。
配線も太いビニールコードにした。太いほど、ノイズに強いはずなので。
配線間も取り合いでならべないで、適当に離れた関係にする
SPIの場合配線でトラブったらオシロでCLKとMOSI,MISOを見る必要があります。4CHオシロが必要です。
◆ESP32モジュールのデバッグ環境用配線
ESP32eモジュールを小型のピッチ変換基板に半田付けして、ピッチ変換基板をCPU基板に
載せた構造にしました。デバッグのときは、ESP32DevkitSと接続してプログラムを書き込むのとUSBシリアルでモニターします。Teensy4.1とは、RX,TXがTeensyのRX2,TX2に接続されてますが、デバッグ時にRX,TXが
モニター側にいくので、TeensyのRX2,TX2とはジャンパピンソケットで切り離しにしました。
ESP32の電源系も完全に切り離せるように、ENのプルアップ抵抗と電源に2か所ジャンパピンをつけておいたのですが、デバッグ時には、ESP32 DEVkitSが自動でENをGNDに落としてくれるので、ジャンパは接続したままで大丈夫でした。
ESp32 devkitSでESP32eを設定する方法の記事
◆Teensy-ESP32モジュールの同時デバッグには、ボタン付きUSBHUBが便利です。
2個のCPUで同時にスタートさせてtertermでログを取る場合、USBHUBの電源ボタン
オンオフすることで、スタートさせる方法が便利です。プログラムでキー入力待ちをしても全データをきちんとログできないので、電源オンオフを同時に行う方法が間違いないです。
1:初期動作
サンプルプログラムをページからそのままコピーしてArduinoIDEの新規スケッチにペーストして
コンパイルすれば、そのまま走ります。ボードはTeensy4.1、EPS32DevModuleを使いました。
◆サンプルプログラムのしてること
TeensyがMASTERとして、CLOCKと初めのデータ送信を行います。
ESP32側は、SPI専用DMAライブラリーを使って、バックグランドで動作してるので、見えません。
Teensyでデータに最終端にチェックサムを載せた20バイトのデータを送信すると
ESP32が受信して、最終端のチェックサム値と受信データを足し算してチャックサムを計算しと
比較して、合っているかをESP32のシリアルに出力します。更に、ESP32が独自にランダムで作成した
20バイトのデータの終端にチェックサムをつけて、Teensyに送信します。Teensyでは、送信された
ランダムのデータの終端のチェックサム値と受信データを計算したチェックサムとの比較してOK、NGを
TeensyのUSBシリアルに出力します。Terterm2個立ち上げて、両方のチェックサムをみながら
SPI通信のデータ落ち信頼性が確認できるようなプログラムになってます。
◆改造したプログラム
Teensy4.1用:https://gist.github.com/dj1711572002/b7281b2cfdaf23dce42741a24b619788
ESP32用:https://gist.github.com/dj1711572002/9b803bdc146596a60a1ad4a219400ab1
改造点0:Teensyから送信したデータをESp32から返送する方法に変更。1回遅れて返送する。
そうすることで、teensyの出力で、送受信のエラー率が判る
改造点1:20バイトでなく512バイトバッファを1万回送信して評価する仕様に変更。
改造点2:大量に転送した場合のチェックサムエラー数と平均スループットを測定する。
改造点3:個々のタイミングでの時間データは、500回に1回プリント出力して1万回で20回だす。
改造点4:1バイト転送毎に50μsec delayしているのをゼロにした。1バイトずつ待っていたらSPIの意味がないほど遅くなる。
評価パラメータは、512バイト送信後のDELAY時間をμsec単位で、ズラシてエラー率をみる。
例としてdelay 50μsecでエラーが大量にでた場合のログの値をみると
TeensyはSPIクロック通りに送信していることが判るが、余裕が50μsecしかない場合は、エラーが多発しているので、delay時間を増やしてエラー数の推移をみてみると
delay 100μsecならエラーが1個(カウント上1個でゼロ個)とエラーが改善されました。
n=,10000,errn=,1,t1=,9352250,t2=,9353039,t2-t1=789,t1-t1_1=,891 MASTER,errn=1, size=512,dly=,100,ts=8912,Speed=640000.0 byte/sec |
結果:SPI周期891μsecで512バイトバッファで 6Mbpsクロックで転送が可能スループットは、
512*10000*8/(8912/1000)=4,596,050 bit/sec=4.6Mbpsの速度がでている。
●以後
UDPを追加して、無線でのスループットがどこまで出せるか実験する 多分相当遅くなるしエラーも増えると
想定されます。httpでの転送も実験する必要があるかもしれません。
エラー率が厳しくなるが、Sdカードに正確なデータが保存されているので、0.3%程度とする
方向で検討したい。