はじめに
倉澤ズズくんです。前回は全日本大会についてお話しました。今回は距離センサです。
マイクロマウスでは走行する際に壁の認識がマストです。壁の有無による迷路のマッピングや壁との機体と距離を利用して走行する位置を制御します。その際に用いるのが距離センサです。
距離センサ
仕組み
距離センサにはLEDとフォトトランジスタを使用します。
LEDを発光させ、壁から反射した光を隣に設置したフォトトランジスタが受光します。フォトトランジスタは受光した光量を電流へと変換し、マイコンのADCに接続して電圧として変換します。
距離に応じて変化するADCの値から壁とセンサがどの程度離れているか評価できます。
この方式はマイクロマウスではオーソドックスなものです。
回路や型番こそ違いますが、Pi:Co Classic3
も同様です。

距離センサ方式の図解
クラシックマウスに搭載する実際の回路は以下の画像の通りです。
ししかわさんの回路を参考にしました。

距離センサ全体の回路
発光
発光側の回路部分を抽出すると画像のようになります。

発光部分の回路図
LEDの発光はNchMOSFETを用いてマイコンからON/OFFを切り替えられるようにします。

NchMOSFET
NchMOSFETは、GATE-SOURCE間に対して電圧を印加することで、DRAIN-SOURCE間に電流が流れる素子です。GATEにマイコンのGPIOピンをつないでHIGHします。これで、LEDを電源から駆動し、高速なON/OFFのスイッチング制御ができるようになります。
スイッチングができれば、距離センサを扱わないときにはLEDを消灯して消費電力を抑えることができます。
加えて、ソフトウェアで環境光のフィルタをかけることもできます。このソフトウェアによるフィルタリングは佐倉さんのブログで解説されています。
受光

受光部分の回路図
受光側の回路部分を抽出すると画像のようになります。
LEDが発光し、壁に反射して返ってきた光量を測る必要があります。
フォトトランジスタの光量を電流に変換する性質を利用し、マイコンのADCで電圧として計測します。
マイコンのADC機能では、ピンに入力されたアナログ値をデジタル値として得られます。STM32F446では、0 ~ 3.3[v]
の範囲の値が12bitの線形な値として変換されます。
マイコンの設定
モータ+エンコーダの時と同じくSTM32CubeMXを使います。
今回必要な機能はGPIOとADCです。

本実験時のSTM32CubeMXのピンアサイン
GPIO(発光側)

GPIOピンの設定
GPIOは単純なデジタル入出力を制御します。
HIGH(STM32f446
では3.3[v])、LOWで(0[v])となります。
言い換えると、「HIGHは出力」「LOWは出力しない」ということです。
今回使用するLED駆動ピンはPC1
です。
第3引数でピンの出力を制御します。
GPIO_PIN_SET
でHIGH(3.3[v]出力)、GPIO_PIN_RESET
でLOW(0[v]出力)です。
ADC(受光側)

ADCピンの設定
各項目の説明は、koraさんのブログが分かりやすいです。
今回設定した距離センサに使用するADCのピンはPC0
(ADC1
のChannel10
)です。
実験
センサの実験を行います。目的はクラシックマウスで使えるかを検証することです。具体的には、走行時に機体がいる現在の区画の前壁・横壁を検知できれば良いので最大でも180[mm]まで計測できれば実用可能と言えます。(クラシックマウスのレギュレーションでは1区画は180[mm])
回路自体はブレッドボードに組んで実験します。
準備
ブレッドボード
画像の通り、ブレッドボード・マイコン上に配線します。

実験の構成(マイコンとブレッドボード)

ブレッドボード上の配線
安定化電源から電源供給を行い、オシロスコープによってLED発光スイッチングのGPIO信号とフォトトランジスタからのADC信号をキャッチします。

LED:SFH4550とフォトトランジスタ`ST-1KL3A`
ブレッドボードの端にはLEDとフォトトランジスタが実装されています。
プログラム
以下のプログラムで動作させます。
#include "stdio.h"
#include "arm_math.h"
#include "adc.h"
void read_dist_sensor()
{
while (1)
{
// LED 点灯
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);
// LEDの発光を待つ
HAL_Delay(1);
// ADCの値を取得
HAL_ADC_Start(&hadc1);
// 1ms以内に値が取得できていなければエラー
if (HAL_ADC_PollForConversion(&hadc1, 1) != HAL_OK) Error_Handler();
// ADCの値をvalueに格納
uint16_t value = HAL_ADC_GetValue(&hadc1);
// LED 消灯
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);
// 画面に出力
printf("sensor value: %5d \r\n", value);
HAL_Delay(100);
}
}
GPIOピンの出力
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
第1引数と第2引数で出力するピンを指定します。
今回のピンはPC1
なので、ポートGPIOC
のピンGPIO_PIN_1
を指定します。
第3引数でピンの出力を制御します。
GPIO_PIN_SET
でHIGH(3.3[v])、GPIO_PIN_RESET
でLOW(0[v])です。
指定時間だけ待機
void HAL_Delay(uint32_t Delay)
引数に入力した時間[ミリ秒]だけ現在の状態で待機します。
ADCによるアナログからデジタルへの変換
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
引数に入力したADCの変換をします。
STM32CubeMXで設定したRank
の順番に変換されます。
一度関数を呼ぶたびにいくつのRank
分のチャネルを変換するかも指定できます。
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
第2引数に入力した時間内に、第1引数に入力したADCが変換完了状態であれば、HAL_OK
を返します。
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
変換したADCの値を返します。任意の変数に代入することでADCの値を利用できます。
方法
ブレッドボード上に構成した距離センサから10[mm]ごとに壁を設置して測定します。
壁を一定距離毎に離してオシロの波形とADCの値を確認します。

壁距離 50[mm]

壁距離 100[mm]

壁距離 150[mm]
結果
オシロスコープ
オシロスコープで読み取れる波形から、LEDの発光側(上段)に同期してフォトトランジスタの受光側(下段)も立ち上がっています。また、電距離に応じてADCの電圧値が変動しています。
50[mm]、100[mm]、150[mm]での距離のオシロスコープの波形の画像を載せておきます。

壁距離50[mm]での波形

壁距離100[mm]での波形

壁距離150[mm]での波形
ADCの値

ADC値と壁距離のプロット
10[mm]おきに計測し、ADCで得られた値をグラフにプロットしました。
距離に応じてADCの値も無事に反映されていることがわかります。
クラシックレギュレーションとして使用可能
計測の結果、グラフでは50-180[mm]間では距離に対するADCの変化量は大きな傾きとなっているため、マイクロマウスに適した特性と言えそうです。
50[mm]以下、200[mm]以上では変化が少ないですが、クラシック競技で走る上では問題ないと考えています。
環境光
距離センサにおける外乱についても触れてみます。クラシックマウスの距離センサとして使用可能という結論を出しましたが、実験環境が変われば蛍光灯や屋外からの光といった外乱が入る可能性がります。
先程の実験環境の壁にライトを照射し、どのような影響を及ぼすかを観測してみました。

ライト点灯なし

ライト点灯あり
オシロスコープの電圧(縦軸)の分解能を2倍にして見てみます。
壁との距離が150mmの状態で計測したところ、ライト点灯時には無点灯時に比べて全体にバイアスがかかった波形を示しました。この場合、LEDがONとOFFの両方の状況での差分を取れば外乱であるライトの影響を取り除いた距離センサの値が得られそうです。

壁距離150[mm]での波形(ライト点灯なし)

壁距離150[mm]での波形(ライト点灯あり)
ですが、環境光は大会会場によっても違い、強力な外乱によりADCの値が飽和してしまう可能性もあります。会場に合わせて抵抗値を変えたり、フィルタ回路を組んで少しでも影響を取り除く対処が必要になるかもしれません。また、様々な施設で外乱について測定しておき、どの程度の影響を及ぼすことが多いかを経験則的に知っておくことは有効だと考えています。大会に足を運んだ際にはマウスの調整のついでに環境光のデータを蓄積してみてください。
まとめ
クラシックマウスで使用する距離センサの検証を行いました。
今回でモータ+エンコーダの足回りと距離センサが揃いました。
これで最低限の走る機能の検証は完了です。ですが、きれいに走行・旋回する上でジャイロセンサも利用したいので、次回はジャイロセンサについて扱います。
当ブログを開始してから2023年度の大会を目処に日数をカウントしていました。
ですが、来年度の大会日程として決定しているのは2024年度の全日本大会のみであり、2年を目処にしたアールティの研修の最終目標の大会ともなるため、2024年度の全国大会2025年2月23日を日数カウントの目標とします。
全日本大会まで、残り341日!