アルドウィーノを使った
オープンソース、オープンハードの
ローコストECU
テージのECUが壊れているみたいなので
Speeduinoに装換します。
その14:SMT32_megaCPUボード
SDカードの不具合解析、RTCの不良解析
新作ハーネスでエンジン始動
2024年
8月27日
SDカードの容量を取得するのはCMD9コマンドです。SdFatライブラリ内でCMD9を検索すると、cppには無いですが、ヘッダファイルに見つかりました。
SWD(ST−LINK)のステップ実行を使い、TunerStudioのSDカードのダイアログを開いた時に呼ばれる関数を確認しておきます。下はSdSpiCard.cppのsecterCount関数です。readCSD関数を呼んでいます。
下はSdSpiCard.hのreadCSD関数です。CMD9を引数にreadRegister関数を呼んでいます。
8月28日
TunerStudioのSDカードのダイアログを開いた時に呼ばれる関数が分かったところで、不具合をデバッグします。まず、SpeeduinoとPCアプリとの接続がUSBの場合は直ぐ障害が発生し、デバッグが出来なくなりました。USBは通信が行われていない時にも周期的にフレームが送受信され、接続が保たれていることを確認しています。デバッグのためプロセッサが停止すると、このフレームに対応することが出来なくなり、PCアプリのTunerStudioがオフラインになり、以降操作ができなくなります。PCとの接続をUSBからBTモジュール(UART)に変更して、デバッグが可能になりました。
TunerStudioのSDカードのダイアログを開いた時のSDカードのアクセスをデバッグします。下はSdFatライブラリのCMD9コマンドでカード容量を取得しているreadRegister関数部で、CSR(カード特性データレジスタ)の読み出し時にエラーが発生しています。エラーの種別はSD_CARD_ERROR_READ_REGです。
8月31日
SDカードの容量が不明になる不具合のデバッグ中です。ブレークポイントで止めると、赤枠のCALLSTACKに呼んだ関数一覧が出てきます。ステップインで関数を実行して行くと、呼び出した関数の一覧が増えます。TunerStudioのSDカードダイアログを開くと以下のように動作することが判明しました。
・CMD9コマンドでカードの容量を取得します。
・この時、SdSpiCard.cpp内のcardCommand関数が呼ばれます。
・CMD9コマンド発行前にダミーの1バイトの送受信を行い応答を確認します。
・不具合発生時はこの応答が無く、タイムアウトになります。
このダミー送受信時のSPI信号をロジックアナライザで測定すると、何か分かるかもしれません。
ステップインを進めて、最終的にはSTMが提供したライブラリに行きつきます。CALLSTACKの関数をまとめて、関数一覧を作成しておきました。
9月1日
SDカードスロットから配線を引き出して、アナログディスカバリのロジックアナライザのSPIプロトコルアナライザで波形を測定します。
こちらはダイアログ内でフォーマット後のReset and Waitボタンを押した時のプロトコルアナライザ波形です。FFのダミーの後、CMD9の49が出力されてSDカード側もCSDレジスタと思われる値を出してトランザクションが終了してます。
下はダイアログ内でフォーマットしていない時のReset and Waitボタンを押した時のSPIのプロトコルアナライザの波形です。本来はコントローラがダミーのFFを出力するはずですが、何故か00を出しています。CS、クロックは正常ですが、MOSI、MISOともLOWです。連続でリトライしていますが、タイムアウトで終了します。複雑な不具合では無く、全然動作していないので分かり易いです。どこか単純な間違いと思います。
9月2日
その後、SDカードがアクセスできない原因が判明しました。TunerStudioを起動した時のSDカードの初期化アクセス(CMD0、
CMD8など)は正しく行われます、その後、MOSI、MISOの信号がLOWになり、コマンドの前に出力される1バイトのFFダミーアクセスが正しく送信されず、CMD9コマンド(カード容量取得)がタイムアウトになっていました。一旦は正しくコマンドのやり取りが行われますが、その後、動作しなくなくなることが分かりました。デバッガとプロトコルアナライザで確認したところ、MOSI、MISOの信号がLOWになるのはsetPinMapping関数の引き素が
arduino_MEGAのboardID=3で上書きされるからでした。pazi88さんのBMW PnPのboardIDは31です。SDコ
ンソールでSDカードをフォーマットすると、MOSI、MISOが再設定されるので以降は信号が正しく出力され、再度アクセスできるようになるとい
うことです。ちなみに、下のinit.cppのボードのピンの設定部分で赤枠のように強制的に31を設定すると、動作良好になることも確認しました。
フォーラムで質問したところ、エンジン設定にボード種別の設定があるとの情報がありました。赤枠のようにプルダウンメニューでコントローラボードが選べました(笑)。pazi88さんのYouTubeではこの設定が無く、すっかり忘れていました。この設定すると、speeduino.iniの変更やプログラムの書き換えをしなくても、SDカードが正しく動作するようになりました。ただ、まだ完全ではなく、外部ピンによるログ開始、RTCの時間ずれが大きい、ミニターミナルが応答しないなど、まだ少し問題があります。
9月3日
STM32_megaのRTCの時間ずれを確認中です。赤枠の11:48:56にPCの時間をspeeduino
に設定します。
2時間後に参照すると13:48:56位のはずが、赤枠の13:56:02で、約7分(420秒)と大幅に進んでています。 普通の水晶の精度は20ppm(月差約1分)位ですが、仮に精度が100ppm(1/10000)でも、32768Hzで、ずれは約3.3Hzになり、進む方向で
32771.3Hzです。32768分周すると1.0001秒になり、2時間後に7200.072秒なので約0.72秒進むだけです。負荷容量が合っていないというような問題では無く、安定して発振していないなど、何かおかしいです。他にボードが2枚あるので後で確認します。
9月4日
他の2枚のボードのRTCずれを確認しました。左が設定時、右が1日弱経過語の参照時です。ボード2は正しくRTCがバックアップされて動作しています。
ボード3は大幅に進んでいます。電源断後、電池でバックアップした時の結果なので、通電していても遅れるのかは後で調べてみます。
9月5日
STM32F407xでは無いですが、F103Xのデータシートに負荷容量12.5pFのコンデンサは絶対使うなという文言があります。
ちょっと調べたところ、STMの水晶振動子のデザインガイドがありました。今、実装されているエプソンのFC−135(負荷容量12.5pF)は推奨ではないようです。F4の項目がありません。
デザインガイドにFC−135と同じサイズのF407xに推奨する水晶が複数あります。
これが原因で不具合が起きているのかは不明ですが、RSコンポーネンツに上記の負荷容量6pFの水晶があったので、発注しておきました。PSoC5lpは送料無料の調整用です。
9月9日
STM32_megaではminiターミナルのコマンド応答がarduino_MEGAの時と異なるので調査します。PCとUSB接続するとTunerStudioが切断されてデバッグできないし、BT接続ではTunerStudioにBTポート設定がありません。解決策は本物のシリアルポートを使うと上手く行きそうです。アマゾンでRS−232とTTLレベルを変換するMAX3232ボードが売っています。3枚で700円と安いです。購入したボードが到着しました。
デスクトップPCのシリアルポートを9ピンケーブルで変換ボードと接続しますが、回路図は無いないので、基板を解析して接続しました。例えば、コネクタにTXDと書いてあっても、自分のTXDなのか?相手のTXDに繋がるRXDなのかで、入出力が逆になり、これ永遠の難題です。電源は5Vに接続して、TXとRXをループバックします。回路図が付属していれば悩まなくてもいいんですけど。
シリアルポートはCOM1です。TeraTermでループバックテストして動作良好です。
9月10日
miniターミナルの続きです。BTモジュールの代わりにレベル変換をSpeeduinoのシリアルポートに接続します。Speeduinoに載っているTXの5V−>3V変換アッテネータはそのままでも動きました。TunerStudioのポートをCOM1に設定して、SWDを接続してVSCで制御できることを確認しました。
9月11日
VSCで動作を追ったところ、comms.cppのコマンド分岐部でレガシィフラグを確認しています。これが偽になるので、Fコマンド以外の1字コマンドは実行されません。Fコマンド(プロトコルのバージョン、現在は”
002”)だけがレガシィモードに関係なく動くようになっていました。電源投入時にはinit.cpp内でレガシィフラグがレガシィにセットされます。TunerStudioと接続後に、正しいコマンドが処理されるとレガシィフラグがクリアされ、以降、非レガシィになり、F以外の1文字のコマンドは処理されません。この時の動作フローは2文字目をwhileで待って永久ループとなり、次の受信バイトが入るとルー
プを抜けてタイムアウトのエラー(0x00、0x01、0x80、0x3F、0xBA、0x6C、0xAD)が返ります。永久ループ中は点火、噴射などの処理は停止します。当然、エンジンは止まります。
因みに、強制的にレガシィフラグがクリアされないようにすると、′S′、′Q′や′?′などの1文字コマンドが応答します。という事で、arduino_MEGAと異なる動作は、不具合では無いようです。
9月15日
RSコンポーネンツで購入のSTM32F4xxに推奨の32.768KHzの負荷容量6pF水晶発振子が到着したので、早速、交換しました。両端のコンデンサは20pFから12pFに変更しました。
朝7時半に時間設定して、買い物から帰って、約6時間後に確認して、8分位進んでいるので、水晶が原因ではないようです。原因はデバイスか?プリント基板?でしょうか?
STM32のRTCのリファレンスマニュアルを見ると、RTCクロックを64分周し
た信号をポートPC13に出力することができます。コントロールレジスタの最上位のCOEビットを立てれば良いですが、RTCレジスタは不用意に書
き換えられないように、おまじないが必要です。VSCのペリフェラルレジスタでアクセスしても上手く行かないので、RTC初期化コードにCOEビットを操作を追加します。
VSCで追うと、コントロールレジスタを操作しているHAL_RTCEx_EnableBypassShadow関数が見つかりました。この関数を呼ぶと、シャドウレジスタをバイパスして、カレンダ値をカレンダカウンタから直接読み出すように設定します。
この関数にCOEビットを立てるコード(赤枠)を追加しました。前後にはおまじない(具体的にはRTC_WPRレジスタに0xca、RTC_WPRレジスタに0x53を書き込み)がありあます。PC13はarduinoのD52ピンで未使用です。このピンを周波数カウンタで測定すれば、32768Hzを64分
周した512Hzが観測されるはずです。調子の悪いボードは少し高い周波数が出ているか?または不安定になっているか?確認できそうです。因みに、このポートはコイン電池のVBATで動くので電源を切っても出力されます。
9月16日
初めに上記のRTCのクロック出力のコードが正しく動作しているか確認します。動作良好な2番基板で測定します。電源無しで、D52ピンから引き出してカウンタに接続します。512Hzで正常です。周波数カウンタは古い岩通製のUC−6152です。
不具合のある1番基板はコンデンサを20pFに変更して、周波数は511.9Hz、64倍するとRTCのクロックは32761.6Hzです。周波数が6.4Hz低いです。この時1秒は約1.0002秒になり、2時間で約1.44秒遅れるはずです。この出力波形は連続的で良好なボードと同じ感じです。
2時間後にRTCの時間を確認したところ約3分進んでいます。デバイス不良で
しょうか?
9月17日
RTCの不具合はSTM32を交換してみます。500円クーポンがあったのでマルツ経由のDigiKeyで2個発注しました。
ヤフーオークションで購入のサンハヤトのSMT取外し用の低温ハンダが到着しました。値段はアマゾンでは6000円位ですが、少し安くて送料別で4300円でした。
早速、一つ外してみました。融点が60〜70℃で、半田コテ1本でも簡単に取り外すことができます。
9月19日
新しいSTM32のCPUがトレイに入って到着しました。3番基板のCPUと水晶を交換しました。64分周出力は512Hzですが、偶に511.9Hzになります。両端のコンデンサは12pFですが、本来は6〜7pFが適正と思われます。SpeeduinoでPCの時間と合わせて、約6時間後に約4秒遅れになりました。水晶のみを交換した1番基板は511.9Hzにも関わらず、2時間で3分進むのでやはり、CPUが原因と思われます。この後、6pFのコンデンサを入手して、1番基板のCPUも交換する予定です。
9月22日
1番基板のCPUと水晶、コンデンサを12pFに交換して、3番基板と同一にしました。64分周出力は512Hzでした。ところが、約5時間後に約6分進んでいました。CPUの不具合では無いことになります?不可解です。
STMのフォーラムなどで質問しやすいように、問題を簡単にします。Speeduinoのプログラムを使わないで単純なプログラムでRTCの確認をします。PlatformIOのSTM32duinoRTCライブラリにSimpleRTCというサンプルプログラムがあります。これにreceiveCommand関数を追加して端末からRTCの開始の時分を入力できるようにしました。下はsetup部で、時間が設定されていなければクロックをLSE(外部32.768KHz水晶)に設定し、rtc.setxx関数がRTC_setTime関数を呼んで時分秒を設定します。
loop部では1秒待って、rtc.getxx関数で時間を取得して、シリアルに時分秒を出力します。
PCの時計に合わせて、時分を入力し、一定時間後にPCの時計と比べれば、Speeduinoとは無関係にRTCの動作を評価できます。下は1番基板のSimpleRTCの結果です。5時間で約8分進んで、明らかに異常です。
下は3番基板のSimpleRTCの結果です。6時間で約4秒遅れています。64分周出力が偶に511.9Hzになるので、遅れの方向で誤差が大きいですが、正常と思います。
SpeeduinoのRTCの時間設定と比べてみます。時間が設定されていなければRTC停止、クロックをLSEに設定、RTC開始、rtc.setime関数がRTC_setTime関数を呼んで日時を設定しています。基本的にSimpleRTCと同じです。
時間取得はrtc.getxx関数で、基本的にSimpleRTCと同じです。
9月25日
アナログディスカバリで平均値が出せるので1番基板の64分周出力(RTC_CALIB)の平均周波数を測定します。
立ち上がりでトリガをかけた時は511.94Hzです。
因みに、立ち下がりでトリガをかけた時にはジッタのため、約516Hzです。64倍すると、33024Hz、1秒は0.9922秒になり、5時間で140秒進みます。これが480秒くらいだと、関連がありそうでしたが、無関係と思われます。
リファレンスマニュアルに立ち上がりで測定するように指示があります。
追加で他の基板も測定しておきます。2番基板の平均は512.01Hzです。
1番基板は512.04Hzです。
9月26日
ガレージ内の気温もだいぶ下がってきました。32℃位でしょうか?作業を再開します。
右ハンドルスイッチの汎用スイッチはセカンダリマップの選択、SDカードのログ開始に使います。セカンダリマップは論理の選択ができます。
一方、SDカードのログ開始はHIGHに固定されています。
汎用スイッチがONでログが開始した方がいいので、汎用スイッチの論理を反転させます。初めに配線図を修正しました。
続いて実車です。コネクタからコンタクトを抜いて、配線を入れ替えました。
9月28日
RTCの不具合の続きです。初めから調子の良かった2番基板の水晶をSTMの推奨する負荷容量6pFに交換してみました。両端のコンデンサは12pFです。1時間で約2分進んでいます。ん〜不可解です。
実車の汎用スイッチの論理を入れ替えたので、エンジンエミュレータでSDログの開始/停止を確認をしたのですが、LOWでログが開始します。ダイアログのヘルプにはHIGHで開始、LOWで停止と書いてあります。因みに、ヘルプにはポーリングとトグルの動作モードの記述がありますが、ダイアログに動作モードの選択ボタンはありません。
ソースコードを調べてみます。SD_logger.cppに外部ピンによるログの開始のコードがあり、LOWで開始になっていました。
外部ピンをAuxに指定すると、ゲージに表示ですます。24ピンをAux2に設定してゲージ表示させながら、エンジンエミュレータで24ピンを変化させてSDログの開始/停止の動作を確認しました。LOWで開始で間違いないです。実車の汎用スイッチは前の状態に戻します。
9月30日
RTCの512Hzを測定して気が付いたのですが、アナログディスカバリの周波数偏差の測定値がトリガ位置によって少し変わります。下はトリガ位置がセンタで偏差が大きい時です。最小は507.9Hz、最大は516Hzです。偏差は約8Hzです。
下はトリガ位置を左に移動させた時。最小は511.9Hz、最大は512Hzで、偏差が少ないです。多分こちらが実際の測定値ではないかと思っています。DIGILENTのフォーラムに質問してみました。
今日のガレージ内は28℃位で過ごしやすいです。汎用スイッチの論理を再度反転して、元に戻しました。
6月の中旬にガレージ内が暑くなり、中断していたハーネスの確認作業を再開します。記録ノートと配線図を見
ながら、残っているセンサとECUコネクタ間の確認をします。記録ノートは湿気でカビだらけです。
気温センサに取り付けた、燃調調整ボリュームが反応しないので分解しました。原因は赤枠の半田不良
でした。
基本的なハーネスの確認作業は終了しました。
10月1日
アナログディスカバリの周波数の偏差がトリガ位置によって違う件でDIGILENTのフォーラムから回答がありました。オシロスコープ波形のトリガエッジの指定と周波数測定のエッジは別物でした。ちょっと分かりにくいです。下はスクリーン左端に立ち上がりエッジが出現します。この時、周波数測定は立ち上がりエッジで行われ、偏差は少なくなります。
下はスクリーン左端に立ち下がりエッジが出現します。この時は周波数測定は立ち下がりエッジで行われます。このRTCの512Hzの波形は立下りエッジにはジッタが多いので、偏差が大きくなります。これはアナログディスカバリ/WaveFormsの仕様みたいです。
10月2日
今日は晴れて、ガレージ内は暑いです。
タイヤ径を測ります。約201.5cmでした。
メータユニットにタイヤ径とセンサ点(リアブレーキディスクの固定ボルト数)の4を登録します。後で、1kmを自走し学習が必要です。
オドメータも登録します。22200kmで設定しました。
オドメータ、油温度(30℃)、02センサ値(17.3最薄)、ニュートラルが表示されています。左上のABSワーニングはサイドスタンドが出ている時に表示されます。
Speeduino(arduino−MEGA版)をハーネスコネクタに接続してプラグを抜いてクランキングします。プラグの点火を確認しました。デュアルホイールで問題無く動いているようです。次回はタンクを載せて、ポンプを駆動して始動してみます。
10月3日
Arduino版Speeduinoでエンジン始動しました。新しく作成したハーネスでエンジンがかかることが確認できました。エンジンが暖まっていないので、アイドリングを上げています。クリックすると約5.1Mバイトの動画をダウンロードします。
タンク固定用のグロメットがちぎれてたので、旋盤でウレタンゴムを削って作り直しました。ゴムは柔らかく、切り込んでも寸法が決まらず、難しいです。
タンクを仮止めしたところ、燃料ポンプ/燃料警告センサの配線が長すぎなので、ケーブルを短くして、コンタクトを圧接し直しました。