SSブログ
English Version

CH32V203で遊ぶ(その3)USART割込みでLiDAR接続(その2)高速化 [CH32V]

 前回の記事の末尾に追記したように以前格安で購入した LiDAR は不安定要素が残存するもののセンスしたデータをきれいに描画できるようになりました。
 しかし、秋月電子通商さんで¥120で購入できる CH32C203(clockは144MHz)で処理していて LiDAR からの最大8個の測位データが含まれる通信データの塊(package)を5個中1個の割合でした処理できていませんでした。今回はこの処理を高速化してもっと多くの package を処理できるようにしたいと思います。下の写真は開発環境で CH32V203 を取り付けたブレッドボードにLCD(MSP2807、320 x 240 dot)と LiDAR を接続しています。

開発環境



1.今回の目標
 C言語レベルでの最適化を行い LiDAR から送信されてくる package をなるべく多く処理できるようにします。


2.高速化項目
 具体的な高速化ポイントは下記のとおりです。
  1. 三角関数をテーブルにして、整数演算処理化する
  2. RISC-V は LiDAR からのデータと同様、リトルエンディアンなので LiDAR からの受信データからデータ抽出をせず直接使用する
  3. LiDAR からの package 受信バッファをダブルバッファ化して高速化する


 2-1.三角関数のテーブル化と整数演算処理化
 三角関数テーブルとしてが sin の値を0~90度の区間分持つことにしました。この sin テーブルのデータ形式は LiDAR からのデータ形式及び受信データ表示用のLCDの解像度(320 x 240)を考慮し、下記のようにしました。
  • 角度分解能
     LiDAR からの角度データは dgree の64倍で送られてきます。sin テーブルの角度に関しては dgree の4倍とし、LiDAR のデータ内の角度からの変換はシフト処理のみでできるようにしました。テーブル要素数は 90 x 4 で 360 要素の配列を持つことになります。
  • テーブル要素の値
     メモリを節約し配列要素は1バイトとし、値がゼロの場合は 0x0100 とみなすようにします。配列上は角度0の場合もゼロの値になりますが、角度0の場合は配列を参照せずに結果はゼロと判断するようにしました。

 配列用データの生成は下記の BASIC プロフラムで行いました。
1' create sin table Ver 0.01 2024/07/10 by skyriver 100 DELTA=90*4 110 PRINT "const uint8_t SinTable[] = {"; 120 FOR I=0 to DELTA - 1 130 IF (I MOD 8)=0 THEN PRINT:PRINT CHR$(9); 140 PRINT "0x";RIGHT$( "00" + HEX$(INT(SIN(I/DELTA*3.14159/2)*256+0.5)), 2);","; 150 NEXT 160 PRINT:PRINT "};"

 作成した sin テーブルのソースは下記になります。

sin テーブルのソース
/* * sin table 0-90 degree : 360 values * Ver 0.01 2024/07/20 by skyriver */ #define SINDEGPAR (4) // Angles are digit fixed point degree const uint8_t SinTable[] = { 0x00,0x01,0x02,0x03,0x04,0x06,0x07,0x08 ,0x09,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11 ,0x12,0x13,0x14,0x15,0x16,0x17,0x19,0x1A ,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x23 ,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B ,0x2C,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34 ,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D ,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45 ,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E ,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x57 ,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F ,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 ,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F ,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 ,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F ,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 ,0x88,0x89,0x8A,0x8A,0x8B,0x8C,0x8D,0x8E ,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96 ,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D ,0x9E,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4 ,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAA ,0xAB,0xAC,0xAD,0xAE,0xAF,0xAF,0xB0,0xB1 ,0xB2,0xB3,0xB3,0xB4,0xB5,0xB6,0xB7,0xB7 ,0xB8,0xB9,0xBA,0xBA,0xBB,0xBC,0xBD,0xBD ,0xBE,0xBF,0xC0,0xC0,0xC1,0xC2,0xC3,0xC3 ,0xC4,0xC5,0xC6,0xC6,0xC7,0xC8,0xC8,0xC9 ,0xCA,0xCA,0xCB,0xCC,0xCC,0xCD,0xCE,0xCE ,0xCF,0xD0,0xD0,0xD1,0xD2,0xD2,0xD3,0xD4 ,0xD4,0xD5,0xD5,0xD6,0xD7,0xD7,0xD8,0xD9 ,0xD9,0xDA,0xDA,0xDB,0xDB,0xDC,0xDD,0xDD ,0xDE,0xDE,0xDF,0xDF,0xE0,0xE0,0xE1,0xE2 ,0xE2,0xE3,0xE3,0xE4,0xE4,0xE5,0xE5,0xE6 ,0xE6,0xE7,0xE7,0xE8,0xE8,0xE8,0xE9,0xE9 ,0xEA,0xEA,0xEB,0xEB,0xEC,0xEC,0xED,0xED ,0xED,0xEE,0xEE,0xEF,0xEF,0xEF,0xF0,0xF0 ,0xF1,0xF1,0xF1,0xF2,0xF2,0xF2,0xF3,0xF3 ,0xF3,0xF4,0xF4,0xF4,0xF5,0xF5,0xF5,0xF6 ,0xF6,0xF6,0xF7,0xF7,0xF7,0xF8,0xF8,0xF8 ,0xF8,0xF9,0xF9,0xF9,0xF9,0xFA,0xFA,0xFA ,0xFA,0xFB,0xFB,0xFB,0xFB,0xFC,0xFC,0xFC ,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFD ,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };


 上記の sin テーブルを持つことで LiDAR からのデータ処理を浮動小数点を使わず、全て整数処理で行うことができるようになり、かなり高速化できました。

 下図は従来からの浮動小数点演算処理時のロジアナ波形の再掲ですが、5個の package 中、1個だけ処理ができています。マーカー0がデータ抽出+1ポイント描画の時間でマーカー1が1ポイントの時間なのでデータ抽出には 1ms 程の時間が掛かっていることになります。この package では8個のポイントを描画しています。

浮動小数点演算での処理(従来方式)


 下図は整数演算処理化した改善版のロジアナ波形です。3 package 中1個の package が処理できるようになったので処理率は従来の20%から33%に改善されました。SpiClk が発生している部分がLCD描画している箇所ですが、従来は8回の描画に隙間が見えましたが、高速化したことにより、隙間が見えなくなっています(マーカー1の部分)。マーカー0の部分は LiDAR のデータから必要なデータを抜き取っている部分ですが、800us 程の時間が掛かっていることが判ります。

整数演算で高速化した処理(改善版)



 2-2.データ抽出処理の高速化
 今回使用している CH32V203 は 32 ビット RISC-V をベースに設計されていて、LiDAR からのデータと同様にリトルエンディアンです。従来の処理では LiDAR からのデータの受信バッファからバイト単位でデータを抜き取り、シフト処理でワードデータ等を抽出していました。高速化のために受信バッファ内のポインタをキャストすることでデータ抽出を行わず直接参照するようにしました。

 高速化後のロジアナ波形が下図になります。マーカー0がデータ抽出処理ですが、前述のロジアナ波形では 800us 程度かかっていたデータ抽出処理が 71us 程度に高速化できました。尚、ロジアナ波形の最後に追加した"receiving"はLiDARからのデータを割込み処理で受信中であることを示すディバッグのための信号です。受信データ処理中は LiDAR からのデータを受信できていないことが判ります。

データ抽出部改善後



 2-3.ダブルバッファ化
 LiDAR からのデータを受信するための受信バッファをダブルバッファー化し、処理中でも LiDAR から出力されるデータを受信できるようにすることで受信待ち時間を最小にして高速化しました。
 下図がダブルバッファー化後のロジアナ波形です。処理が追い付かず稀に未処理の package が発生していますが、package の処理率はほぼ100%に改善できました

ダブルバッファー化後



3.まとめ
 最近弄りだした120円の32ビットマイコンの CH32V203 に4年前に購入し、お蔵入りしていた格安の LiDAR を繋いでデータ抽出し、LCD上にリアルタイムで表示できるようになりました。
 CPUパフォーマンスの関係で初めは LiDAR からのデータの20%程度しか表示処理できませんでしたが、今回高速化の改善を行った結果、LiDAR からのデータのほぼ100%を処理し表示できるようになりました。
 ネット上で見かける LiDAR データの表示は M5Stack(32bit 240MHz デュアルコア)等の例が多く、数百円レベルのマイコンでの例は見かけません。
 今回は秋月電子通商さんで120円で購入できるCH32V203(32bit 144MHz)を使って下の写真のように LiDAR からのデータをLCDに表示できるようになりました。
 「非力なマイコンで工夫をしてパフォーマンスを引き出す」というのはマイコン弄りの醍醐味の一つではないでしょうか?

LiDAR データのLCD表示例


★追記 2024/07/21
 X(旧Twitter)に投稿したメッセージに添付した動画を貼っておきます。




★追記 2024/07/24
 X(旧Twitter)で最近話題になっている安価な小型の LiDAR が着荷したので試してみました。「UnknownLiDARMini_M5StackCore2」を参考にさせて頂き、従来のソフトウェアを若干変更することで120円マイコン(CH32V203)で LCD にデータをリアルタイムで表示できました。


新 LiDAR(表面)


新 LiDAR(裏面)


新 LiDAR の試験環境




[TOP] [ 前へ ] 連載記事一覧[ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。