Easy CAN Sensor

1. はじめに

本装置はセンサー情報を集めてCANデータにして上位装置に通知するものである。
世の中にはVectorのツールでもよく知られているものだが、Vectorのツールは高額であり、それほど高度なことをしない限り自作ツールでも問題ない。
むしろ今回処理プロセッサにInfineon(旧Cypress)のPSoCを使用することでセンサーの種類や奇特なIFにも柔軟に対応することが可能となる。

2. 装置概要

今回は普通はCANの情報ないセンサー情報を別途取得し、測定したデータをCANプフォーマットに変換を行い、上位システムに通知する装置例を示す。

Figure 2-1 Easy CAN Sensor Monitor全体構成ブロック図

Sensor Pot
これらのケースは3Dプリンタで製作
センサー処理部本体
制御基板は2枚構成となっている
(マイコン基板+IF基板)
ユニットを1chのみ使って構成した場合
項目内容備考
PSoCボード内部諸元 
メインCPU                             CY8C3866AXI-040 (Cypress)8051 100pinQFP ROM/RAM内蔵 メモリ: ROM:64kbyte,RAM:8kbyte 動作クロック:外部30.0MHz/内部60MHz
A/D変換部16ch(マルチプレクス入力) 変換時間:246.6us/channel 16ch H/Wシーケン測定周期: 3.972msec/period 入力:シングルエンド0~2.048V 量子化ビット:ΔΣ12bit 入力インピーダンス:10MΩ以上DMA転送によりCPUの負荷軽減 A/D変換動作は固定周期
変換データは8タップの移動平均処理する。 座席位置、ドア開閉検出で使用
平均化処理移動平均タップ数8AD変換データの移動平均処理
システムタイマー10msec測定タイマーの基準時間として使用
 外部IF部 
UARTTX:1ch 9600bps N81 RX:5ch 9600bps N81距離センサー TW10S-UARTを使用
ADポート16ch1sensor portで3つのADを割り当てる。
USBUSB:CDC 2ch,HID 1chUSB複合デバイス HID:CAN, CDC1:コンソール出力
CAN~1MbpsDefault:500kbps
キャラクタLCDST7032I I2C IFセンサー測定結果・ステータス情報など表示
タクトSW2個1つはセンサー情報の表示切替で使用
ステータスLED2個使い方はT.B.D

3. CANインターフェース仕様

3.1 CANデータの送信周期

データ取得周期と通知周期は以下の表3-1に従う。送信周期が0.7秒というのはレーザー距離計の測定応答時間を考慮した値となっている。レーザー距離計以外は特に大きな制約はない。

送信方式送信周期更新時間データ内容 CAN ID
定周期700ms100msADデータ 16ch700h~703h
定周期700ms700ms距離データ704h~706h
表3-1 送信周期

3.2 PSoC内の送信メールBOXの設定

PSoCのCANペリフェラルは送信メールボックス8個、受信メールボックス16個から構成されている。本装置においては測定したセンサー情報をCANで送信することから8個のメールボックスで以下のような割り当て送出することにした。

symbolMail BOX#CAN IDDLC内容
CH0003AD2700(h)8ch0~ch3のA/Dデータ
CH0407AD3701(h)8ch4~ch7のA/Dデータ
CH0811AD4702(h)8ch8~ch11のA/Dデータ
CH1215AD5703(h)8ch12~ch15のA/Dデータ
LADIS126704(h)8レーザー距離計 port1~port2
LADIS347705(h)8レーザー距離計 port3~port4
LADIS58706(h)3レーザー距離計 port5

4. システムクロック設定

システムクロック設定

5. ADコンバータ

5.1 AD変換のH/Wシーケンス化

使用したPSoCは8051コアの CY8C3866AXI なので、CPUパフォーマンスはそれほど高くない。一方、AD入力は16chかつUART受信割り込みを5ch同時に動作させるため、なるべくCPUを介さずに動作するようにするため、ADコンバータのH/Wシーケンス処理化を検討してみる。

5.2 A/D変換部動作概要

16ch分のA/D変換は全てH/Wシーケンスで行う。
H/WロジックによりA/D入力のマルチプレクスを行い、SOC(start of conversion)トリガにてA/D変換を行い、その終了のEOC(end of conversion)の信号をDMAのトリガとしてメモリに転送される。DMAにて8チャネル分のデータ転送を行った後、割り込み信号によりCPUで各チャネルを移動平均バッファへと転送する。
なお、上記の一連のA/D変換からメモリへのデータ転送はCPUの処理とは非同期で常に行われている。
16channel分のA/D取り込みから各チャネルの移動平均バッファへの転送は2系統のDMAを使用しDouble Buffer経由で移動平均バッファに転送する。1系統約7.944msecでパイプライン処理するため、16chnnel AD処理はその半分の約3.97msecでおこなう。

H/Wシーケンサーを利用したAD変換方式とダブルバッファデータフロー
PSoC上で構成したH/Wシーケンサーを利用したAD変換ブロック図(1/2)
PSoC上で構成したH/Wシーケンサーを利用したAD変換ブロック図(2/2)

5.3 A/D変換モジュール設定内容

変換レート(40960sps)に設定にするとA/D変換のH/Wシーケンサーによる1周期(16ch)の変換時間は内部RAMにDAM転送する時間を含めて約429usecであり、A/D変換16ch分の測定結果を内部メモリから移動平均バッファに転送するのに391usec要する。
つまり、他の処理で使用できるCPU処理リソースは429-391≒38usecしかない。
PSoC3はCPUが8051@60MHzでありこの時点でCPU動作率が91%となっているのでやりすぎ!
従って、この変換レートを40960sps⇒4096spsに変更する

A/D変換ブロックの設定

5.4 動作タイミグの確認(実測)

A/Dサンプルを40960spsにした場合の動作タイミグ
A/Dサンプルを4096spsにした場合の動作タイミグ

上記にタイミグからわかるようにサンプリングを4096spsにした方がCPUの処理時間をマージンを見て確保することができる。

5.5 移動平均バッファの動作概念

H/Wシーケンスで取得したチャネルごとのADデータはDMA割り込み時にローカルの移動平均バッファへ転送する。また、移動平均ライブラリは2,4,8,16,32タップのいづれかの数で平均処理できるようになっている。ADデータの取り出しは入力とは非同期に行われ、必要な時に直近過去の設定したタップ数の移動平均値を取得する。
A/Dの内部サンプル周期は16channelあたり3.97msecは変わらない。
移動平均したデータを設定された外部転送周期で転送を行う。
PSoC3の評価ボード上で実測したところ16channel,32byteのデータを移動平均処理するのに385usec要しているので約83kbyte/secくらいの処理となる。

測定周期とデータ転送周期概念図

<<Buffer AのDMA割込みハンドラの中の処理>>
/************************************************************************
* Function Name:  ADI1_ISR
* finish 16 channel measurement -> Transfer DMA1 end -> Occured isr!  
********************************************************************/
CY_ISR(ADI1_ISR){
	int i;
    DebugOut_Write(1);
    Control_RegDma_Write(0);
	for(i = 0; i < NUMCHAN; i++){
		MovingAverage_input(padavech[i], ADresult1[i]);
	}
    DebugOut_Write(0);
}

Buffer AのDMA割込みハンドラの中の処理
主にAD buffメモリからローカルの移動平均処理バッファにコピーしているだけ。自作したMovingAverage_input()関数が重いのかもしれないが、CPUが8051だと結構処理時間がかかるという感じ。

6. レーザ距離センサー

6.1 UARTブロック

このブロックはレーザー距離センサー(TW10S-UART)用のもので測定値要求コマンドは”UART_1”ブロックがまとめて各距離センサーモジュール向けにブロードキャストを行う。これはUART_2~UART_5のTXブロックを省略することでH/W使用リソースをなるべくコンパクトにするためである。
一方、TXをまとめるのは多少のピンリソースは消費されるが、基板上で一つにまとめるより今後拡張や用途に応じて柔軟に対応できるからです。各センサーの測定結果はそれぞれにUART RXで受け、ブロック毎の受信割込みでデータ受信する。GPIOは各Sensor Portに対する予備的な信号線であり、今回は使用しない。UARTのデータサンプルクロックはボーレートの8倍を入力することにする。今回の距離センサーの通信レートは9600bps(N8)である。

レーザー距離センサー(5個)との通信するためのUARTブロック群

今回使用するレーザー距離計モジュールはUART IFであり、測定開始のコマンドの後、測定したデータが送られてくる。開始コマンドは同じなので5個のUARTブロックの中で一つだけTX部を持つこととし、それを各デバイスにワイヤードでブロードキャストするような感じ。TXを一つだけのブロックにすことでUDB(User Digital Block)の使用するリソースをなるべく節約する目的もある。
受信はそれぞれに「受信割り込みハンドラ」を設け、個別に距離測定管理する。
通常この規模のマイコンで複数(5個)のUARTペリフェラルはなく、PSoCならでは特徴を活かした構成が容易に可能となる。

受信したデータは下記の処理を行い距離に変換する。

6.2 レーザ距離センサー処理

/****************************
 TW10S-UARTの受信データから距離への変換
 ※Ring_buffライブラリを使用
 引数: TRINGBUF *prx 受信リングバッファポインタ
 戻り値:int_16 distance 距離データ (mm)
********************************/
int16 TW10S_distanceCalc(TRINGBUF *prx, uint8 *stat){
    int16 i,dat[4];
    
    while(RingBuf_LeftValue(prx) > 7){
   /* 受信データ数が9byte以上だったら有効データありと判断してworkbuffdrにコピーする*/
        if(RingBuf_WatchBuf(prx, 0) == 0x01 && 
           RingBuf_WatchBuf(prx, 1) == 0x03 &&
           RingBuf_WatchBuf(prx, 2) == 0x04){
           for(i = 0; i < 3; i++) RingBuf_GetBuf(prx); /* 3つリードポインタを進める */
            dat[0] = RingBuf_GetBuf(prx);
            dat[1] = RingBuf_GetBuf(prx);
            dat[2] = RingBuf_GetBuf(prx);
            dat[3] = RingBuf_GetBuf(prx);
            if(dat[0] >= 0xfc) {
                /* 異常データー時はステータスエラーを返す 距離データは0 */
                *stat = dat[0];
                return 0;
            }else{
            /* 正常距離データ */
                *stat = 0;
                return (dat[0] << 24) + (dat[1] << 16) + (dat[2] << 8) +(dat[3]);
            }
        }else {
           RingBuf_GetBuf(prx); /* ヘッダが出てくるまでリードポインタを進める */
        }
    }
    *stat = 0xfb;   /* データが十分ない */
    return 0;
}

6.3 レーザー距離センサーモジュール(TW10S-UART)

6.3.1 概要仕様

インターフェース: 3.3v-5v/ttl232 3線式シリアルインターフェース
(シングルチップuart/usart/sciインターフェース。rs232インターフェースを直接接続しないでください。)
ボーレート 🙁 4800、9600、19200、38400、57600、115200) オプション、デフォルトは9600
電源電圧: 3.3v;
稼働中: <180ma;
測定範囲: 0.04〜40m (モジュールの前面に基づく)
測定速度: 最大5Hz、つまり1秒以内に5つのデータを測定できます。
測定精度: ± 2ミリメートル + 510 (-5) d、dは測定距離; 動作温度: -10 ~ 50 ℃。 保管温度: -30 ~ 70 ℃ 製品サイズ: 6031*14mm (長さ * 幅 * 高さ);

ピンコネクタアサイン

6.3.2 インターフェース仕様

このレーザー距離計をAliexpressで購入したが、インターフェース仕様書は十分ではなく、ネット上で必要な動作が行えればいいのだが、動作モードに3つほどあり、データ更新周期をなるべく短く従ったのだが、最高0.7秒程度だった。ネットの情報から以下のようIF仕様のようだ。

  1. 準備

各レンジングの前に、enピンを高レベル (3.3v〜5v) に設定すると、センサーが起動してハードウェアを初期化します。センサーは引き続き以下を発行します。
01 03 02 00 00 B8 44
測定が完了すると、センサーは低電力モードになります。

  1. 入力レジスタ (関数コード0x03) を読み取ります

(このコマンドを発行する前に、センサーが続行されるのを待ちます)
例:
読む測定距離
説明アドレスコード関数コード開始アドレスレジスタ数crc
送信: 0x01 0x03 0x00 0x0f 0x00 0x02 0xf4 0x08
通常の応答 (測定距離57.505m):
説明[アドレスコード][関数コード][バイト数][レジスタ1値(2byte)][レジスタ2値(2byte)][crc]
通常応答: 0x01 0x03 0x04 0x00 0x00 0xe0 0xa1 0x72 0x4b
注 (この指示の距離は4バイト、0x00 0x00 0xe0 0xa1、距離は0x0000e0a1、10進数で57505mmに変換)

  1. エラーコード(エラーコード:0x83)

開始アドレスが間違っている場合、レスポンスは次のようになります。
説明[アドレスコード][エラーコード][例外コード][crc]
エラーレスポンス: 0x01 0x83 0x02 0xc0 0xf1 (間違った開始アドレス)
エラーが発生した場合、レジスタ1と2がエラーコードを表します。 具体的なタイプは次のとおりです。
0xff000000 計算エラー、再測定
0xfe000000反射光が弱いか、測定時間が長すぎるため、反射面がより簡単に反射される必要があります。
まな板で、白紙、など。
0xfd000000ターゲットが反射しすぎているため、強い光を当てないでください
0xfc000000測定範囲を超えています。機器の範囲内で測定してください
CRCが後尾についているが、生成多項式が詳細不明。とりあえず無視してもいいかと思われる。

OCTET正常間違った開始アドレス計算エラー 再測定反射光が弱いか、測定時間が長すぎるターゲットが反射しすぎている範囲を超えています
1(アドレスコード)0x010x010x010x010x010x01
2(関数コード)0x030x830x030x030x030x03
3(バイト数)0x040x020x040x040x040x04
4(レジスタ1H)測定値(X3)0xc00xff0xfe0xfd0xfc
5(レジスタ1L)測定値(X2)0xf10x000x000x000x00
6(レジスタ2H)測定値(X1)CRC(上位8)?0x000x000x000x00
7(レジスタ2L)測定値(X0)CRC(下位8)?0x000x000x000x00
8CRC(上位8) CRC(上位8)CRC(上位8)CRC(上位8)CRC(上位8)
9CRC(下位8) CRC(下位8)CRC(下位8)CRC(下位8)CRC(下位8)

7. さぁ、動かしてみよう!

装置の動作イメージ
自作のEasy CAN Monitor で出力データ確認
割り当てたCAN IDにAD値や距離情報が入っていることを確認した
USB-CDCで接続したターミナルでモニタしたセンサー情報
センサーが接続されていポート(ここではAS0, AD2,距離1)に測定したデータが表示されていうことがわかる。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です