2025年1月13日月曜日

出入り検知器をPCB化する(その21)・超音波測距2

 年末年始で手を付けていなかった超音波測距だが、ソフトを作って実際に動かしてみた。PICは14ピンのPIC16F18326を使った。


Timer1に入力するクロック(LFINTOSC=31KHz)をプリスケーラで2分周する事で、計測値1カウント当たり1.1cmの測距距離とした。これで1カウント当たりほぼ1cmと考える事ができる。音波の反射や回り込みによる相互干渉を避けるため Right, Front, Left の3つのセンサーを(同時でなく)100ms毎に順番に起動し測距する。これを連続で行うと3回/秒程度の頻度の測定になる。次図で上のトレースは右(R)のセンサーのトリガーであり、100msずつ遅れて起動する他のセンサーのトリガーは見えていない。下のトレースはTimer1のゲート信号で、順に3つのセンサー(R,F,L)のエコーに対応している。
各エコーのパルス幅が測距距離に対応しており、毛布で覆ってエコーが無いと思われる場合は次のような波形になった。

中央の幅広のパルスを生成しているセンサーがUS-015であり、それ以外はHC-SR04である。それぞれUS-015で75ms、HC-SR04で50ms程度あり最大探知距離相当時間の2倍以上は確保されている。

 測定結果はシリアルインターフェイスを通じてホストへ送信する。

測定したデータの処理には次の3つのモードを設けた。

  1. 生データ表示モード
  2. 測定結果表示モード
  3. 最接近表示モード

1.生データ表示モードはデバッグ用で、測定した3方向の生データを16進表示する。

#0049:0021:001e
#0049:0022:001f
#0049:0022:001f
#0049:0021:001e
#004a:0023:001e

2.測定結果表示モードでは測定した3方向のデータを10進表示するが、この時測定したい距離の閾値(最大距離、最小距離)を適用し、その範囲外のデータは0とする。これは近くにある固定された反射物を避けるとともに、とくに最大探知距離より大きな値(無エコー、誤データ)を排除する為である。

> R:144 F:63 L:32
> R:144 F:63 L:31
> R:73 F:33 L:31
> R:73 F:34 L:32
> R:73 F:32 L:31
> R:144 F:64 L:32
> R:144 F:63 L:31

3.最接近表示モードでは、3方向のうち最も距離の近い対象までの向きとデータ(≒距離)を表示する。3方向とも範囲内に対象物が検知されなかった場合は何も表示しない。

=L23
=L30
=F51
=F53
=F48
=F52
=R71
=R71

基板上の3つのLEDは夫々のセンサーが対象範囲(閾値)内にエコーを捉えていると点灯する。 

3つのセンサーのデータをAI(機械学習)で学習すれば前を通る人の動きを認識出来るかも知れないが、今回はそこまでやらない。

このセンサーユニットを、これまで作った回路と組み合わせることで纏まった動作をさせるよう今後インテグレーションしたい。


(続く)

 

 

2024年12月25日水曜日

出入り検知器をPCB化する(その21)・超音波測距1

 出入り検知器は元々20cm離れた2本の赤外線を人が横切る事を検知するよう考えていた。これは狭いゲートを通過する人を検知するような使い方を前提としていた。一方、目前の歩道を通り過ぎるような人の動きを検知して働くような機能の方がより汎用的に使えるだろうと、そのようなセンシングを考える事とした。

このような動きを捉えるには画像認識以外には次のような幾つかの方法が考えられる。それぞれ対象物との絶対的な距離を測れるものと、距離の変化を捉えるものがある。

  1. 焦電センサー
  2. 赤外測距センサー
  3. 超音波測距センサー
  4. ミリ波センサー 

これらのうち秋月で入手が容易な(比較的安価な)センサーについて特性を調べた。1.焦電センサーは人体から放射される赤外線を捉え、その量の変化が閾値を超えた場合に反応するが屋外では太陽光やその反射光、風が吹いても反応する事があり屋外での特に昼間の利用には不向きである。2.は自ら赤外線を発射し、その反射光を受信するまでの時間から対象物迄の距離を測定する。その例として秋月で売っているVL53L0X使用 レーザー測距モジュールを買ってみた。これは Arduino ではライブラリが使えるようだがモジュール自体の仕様は公開されておらずPICからは容易に使えないので今回は扱わない。3.は超音波を使って2と同様な事を行う。4.はミリ波を使って同様な事を行う。最近は車の人感センサーに応用され比較的入手が容易である。ただ電波法で規制されるため認証されたものを使う必要がある。秋月で売っている手頃なものはドップラー効果を応用しているのか人が近づいたり離れたりする動きのみ取り出せるので焦電センサーと変わりない。


取り合えず安価で最も使い易そうな超音波センサーを使ってみる事とした。秋月では手頃な値段のUS-015とHC-SR04という見かけの似た2つの超音波センサーモジュールを販売している。

値段もあまり違わない。インターフェイスも同じGPIOで4ピンの信号割り当ても同じ。但し(マニュアルは中国語で分かり辛いが)HC-SR04はジャンパーを切り替える事でGPIO(PWM)のほかI2CまたはUARTインターフェイスを選ぶ事が出来るようである。汎用性を考え、とりあえずGPIOインターフェイスで使ってみる事にした。次図はGPIOのタイミングチャートである。


GPIOでは Trig端子に10μsのパルスを加えることで測距がスタートする。先ず40KHzの超音波パルスが8回発射され、それが対象物で反射されて帰ってきたエコーを受けてEcho端子に往復時間に対応する時間幅のパルスが出力される。もしエコーが検知されなかった場合は80msのパルスが出力されるとUS-015のマニュアルにあるが、HC-SR04にはそれに相当する記述はない(実際に測定したところでは50ms強であった)。Trig端子に与えるパルスの繰り返し周期は仕様上はUS-015で85ms程度、HC-SR04では200ms以上必要である。

音速を340m/sとし、最大測距距離4mとして試算すると往復時間(Echo端子への出力パルス幅)は23.5msである。厳密には大気中の音速の温度勾配が0.6m/s/T程度あるようであるが、今回の目的には補正は必要ないだろう。もし補正したいならPICに内蔵の温度センサーを使うと簡易な補正はできる。

測定にPIC16F18326を使う場合、カウンタをゲート制御できるTimer1を使うのが適当である。Echo端子の信号をカウンタのゲートに加える。カウンタに加えるクロックにLFINTOSC(31KHz)を使うと距離を(理論的には)約1.1cm単位で測定する事が出来る(往復だと0.55cm)。また無エコー時の80msパルスのカウント値は24,80カウントでありTimer1の16ビットの範囲に収まる。

・・・てな事を考えながら回路を考え基板を発注した(この回路では将来の拡張を考えてPIC16F18346を使っている)。


この基板では3方向の超音波センサーを使う事を想定している。センサーの指向性は±15度なので各センサーは角度の30度離して取り付けるのが良いと思われるが3つ併せても探知範囲は90度しかない。広い範囲を見るためにあと2個追加して探知範囲を150度としたいものである。

(続く)

 

2024年12月21日土曜日

出入り検知器をPCB化する(その20)サーボ・モータを動かす8

 サーボ・コントローラを語るうえで大事な事を忘れていた。

そもそもサーボモータの制御信号(PWM)には統一規格はあるのか、 それはTowerPro社のSG-90と同じで良いのか、或いはどんなものがあるのか、という点である。こういったサーボモータはラジコンで使われているようなので規格は統一されていそうなものである。実際にカタログには制御信号はPWMとだけ書いてある場合も多く、あたかも統一されているようである。そこで秋月で入手できるもの(360度回転の物を除く)を中心に市販品を調べてみた。全てを調べ切った訳ではないが、概要は次の通り。

  1.  TowerPro - このメーカーのサーボモータの制御信号(PWM)のパルス幅は180°回転の場合500μs~2400μsでセンターは1450μsである。
  2.  FEETECH - このメーカーのサーボモータの制御信号は180°回転の場合500μs~2500μsでセンターは1500μsである。回転角が120°の製品もあるがセンターのパルス幅は同じく1500μsである。またシリアルインターフェイス(1Mbps)のものも販売されているようだ。
  3.  GWS - このメーカーのサーボモータの制御信号は180°回転の場合800μs~2200μsでセンターは1500μsであり、120°回転の場合900μs~2100μsでセンターは同じく1500μsである。
  4. SAVOX - 製品の数が少ないが、回転角が164°のものの制御信号は800μs~2200μsでセンターは1500μsである。

 これらの値をもとに回転角1度当たりのパルス幅変化量を計算すると11μs前後の製品が多いが、中には6.7μsの製品もあった。

これらのメーカのパルス周期はいずれも20ms(50Hz)である。一方Amazonで売っている高トルクのサーボでは高パルス周期(50Hz~333Hz~800Hz)のものもあるようだ。ただ800Hzのパルスを出すとすればパルス幅はせいぜい1ms(1000μs)程度なので、これを使うつもりなら仕様を具体的に検討してみる必要がある。

さて、制御信号の時間的な仕様が分かったので今回作ったサーボ・コントローラで実際にこれが動くのか電気的特性を試してみた。テストに使ったのでは TowerPro の MG996Rである。

このサーボを選んだのはトルクが11Kg/cmもあるので(SG-90は1.8Kg/cm)大喰らいであり、その分だけ制御信号にもある程度パワーが必要かもしれないと考えたからである。つまり(データシートに明示されていない)サーボモータの制御信号の入力インピーダンスや閾値がPICで駆動できる範囲にあるかという事である。

結論から言うと問題なく動いた。最初は電源の電流を500mAに制限して動かしてみたらサーボはかすかに唸るが全く動いてくれなかった、そこで制限を1.5Aくらいに上げると普通に動いた。無負荷のSG-90なら100mAでも動くがMG996Rは無負荷でも1Aは必要である。仕様上は無負荷の電流は170mAとなっているが実際には突入電流が大きく最大電流1400mAの電源を用意しておく必要があるのだろう。やはり大喰らいである。

 以上の事から少なくともTowerPro社のサーボはPICで駆動できる事、またサーボ・コントローラで様々なサーボモータに対応させるためには少なくともPWMの細かい設定が必要な事が分かった(TowerPro社以外のサーボについては機会があれば試したい)。サーボモータを使う側から見ると、制御信号の統一規格は無く、使うサーボモータの仕様に合わせて制御信号のパラメータを変える必要があるという事である。

幸いこの程度の事ならプログラムの簡単な変更で済むのでサーボの仕様に合わせてパラメータを切り替えられようにする予定である。

 (続く)


2024年12月2日月曜日

出入り検知器をPCB化する(その19)サーボ・モータを動かす7

 サーボモータに与えている制御信号を測定してみると、周期が1%ほど短い。また一定している筈の制御パルスの幅にも若干の揺らぎが見られる。これらの原因を考えると、周期の元となっているLFINTOSCの周波数が若干ずれている事と、LFINTOSCとパルス幅を決める元となっているFosc/4(=HFINTOSC/8)の周波数の間に一種の唸り(エイリアシング)が発生して揺らぎが発生しているようだ。

このPICではLFINTOSCの周波数は固定で補正できないが、HFINTOSCのそれは±1%以上補正できるので LFINTOSCの使用を止め、ソースをHFINTOSCに一本化する事で唸りを防ぐ事とした。幸いFosc/4の2MHzから100Hzを取り出す事はこれまで通りTMR0で分周する事で可能だ。結局、次の回路に落ち着いた。また周波数の補正パラメータの値(OSCTUNE)はPIC内部のEEPROMに書き込み保存されるようにした。


これで、この回路を1つの周波数源で駆動する事となり、動作が安定するだろう。また周波数を補正する事でパルス周期をほぼ20msに追い込むことが出来たが発信器には温度特性(次図)もあるのでどこかで妥協が必要である。

電圧依存性は少ないようである。

サーボ・コントローラについては一先ずこれで終わりたい。

(続く)




2024年11月29日金曜日

出入り検知器をPCB化する(その18)サーボ・モータを動かす6

 タイマー0、タイマー1及びCLCを使うことでタイマー2の機能から来る制約から解放されたのでクロック(HFINTOSC)の周波数を4倍の16MHzに上げFoscを8MHz、Fosc/4を2MHzとした。これで処理に余裕も生まれる。

前回の回路を実装してみたが上手く動かない。問題点は2つあった。1つ目はデータシートの回路図上のT1GSPMの表記(1/0)が逆になっていて(本文は正しかった)、ゲートによってカウンタが制御できなかった。このバグを潰すのに数日を要した。もう1点はタイマー1のゲートが閉じているとカウンター1のオーバフローが1になったままリセットできない点であり、そのため2回目以降のタイマー割込みを発生できないうえにD-FFがリセットされたままなのでタイマーのゲートが開けない、いわゆるデッドロックの状態になっている事である。設定を色々試したがどうしてもタイマー1はリセットできなかった(強制的にゲートを開けて数クロック入れてやればリセットされるが美しくない)。この件をネットで検索すると「CCPと組み合わせて使え」とのアドバイスが見付かった。どうやらCCPからタイマーをリセットできるようである。

そこで次図のようにタイマー1をCCPと組み合わせて使うよう変更した。CCPはコンペア+パルス出力+タイマーリセットモードに設定し、タイマー1のオーバーフローではなくタイマー1のカウント値がCCPRの値とマッチするタイミングでパルスを出力するようにし、そのパルスでCLCのD-FFをリセットするとともに割り込みをかけるようにした。同じタイミングでタイマー1はリセットされるようである。

これで上手く行った。これでパルス幅をデッドバンド幅の1μs単位で設定できるので低速の動きもスムーズになった。

このサーボコントローラはシリアルインターフェイス経由で次のようなオンライン・コマンドを受け付ける。


  (続く)

 

2024年11月24日日曜日

出入り検知器をPCB化する(その17)サーボ・モータを動かす5

 これまで使ったTMR2+PWM5,6では大き目のデューティ比のパルスを細かくコントロールする事は苦手である。そこで改めてサーボモータを細かくコントロールする事を考える。サーボモータのデッドバンド幅が1μsだとするとパルス幅を1μs単位でコントロールしたい。1μsを最小単位とし、サーボモータに与える最大パルス幅を2.5msとすると2500倍であり、これを制御するには12ビット以上のカウンタが必要である。これに該当するのは16ビットカウンタを持つタイマー1である(タイマー1は次の回路構成)。またこれに与えるクロックは1MHz以上とする必要がある。

今回の目的にタイマー1を使うときの問題点は、タイマー1はワンショットで、タイマー2の様なフリーランではない事であり、カウントが終了する度に再度カウンターに初期値を設定する必要がある。幸いその時間的余裕は17.5ms以上あるので割り込み処理で間に合うだろう。またタイマー1自体には任意のパルス幅のパルスを生成する機能は無いため、他の機能(例えばCLC)と組み合わせて使うことになる。このアイデアをPIC16F18346を使って組み立てて次図のように構成した。

この図でTMR0の分周比を620とせず310としたのはCLC1とCLC3のCK端子の論理を逆にし、HとVのサーボに与えるパルスを半周期(10ms)ずらし突入電流を減らす事を狙っている為である。TMR0の出力はデユーティ比が50%ではないためCLC2で2分周し周期20ms、デユーティ比50%の方形波を作る。

この回路の動作は、D-FFのD端子が1になると次のCK端子の変化点でQが1となりパルスがスタートする。それと共にタイマーのゲートGが開きカウントがスタート。カウントが進みカウンタが0xffffから0x0へ変わる時オーバーフローが発生してOVFが1になり、その時点でD-FFがリセットされパルスが終わる。この時割込みを発生させ、ソフトで次のカウンタの初期値を設定する。もしD-FFのD端子が0の場合は次のパルスは発生しない。この方法なら制御の最初や最後で中途半端な幅のパルスを生成することは無い。

タイマー1(TMR1,TMR3)のクロック入力には2MHzを使いプリスケーラで2分周して1MHzのクロックとしてカウントする。SG90の性能は0.12sec/60度であるからパルス間隔20msでは10度回転し、これに相当するパルス幅の変化量は概ね110μsであるから、これ(110)が20ms毎のタイマーのカウント値の最大変化量とする。即ちこれ以上カウント値の変化量を大きくしてもサーボモータが追従できない。この値を基準に制御プログラムを作成する。

〔参考〕ここでPICのタイマーの表記が紛らわしいので改めて説明する。PICには3種類のタイマーがあり、それぞれタイマー0、タイマー1、タイマー2と呼ぶ。PICの種類毎にそれぞれのタイマーが何個ずつ実装されているかが異なり、PIC16F183x6ではタイマー0はTMR0、タイマー1はTMR1、TMR3、TMR5、タイマー2はTMR2、TMR4、TMR6が実装されている。

 (続く)



2024年11月22日金曜日

出入り検知器をPCB化する(その16)サーボ・モータを動かす4

 この回路は手動制御とリモート制御の両方を実現しており、双方で制御の仕方が違う。リモート制御では角度を±90度、回転速度は19段階で指示できるが、手動制御ではレバースイッチは回転方向を、回転速度はロータリーコードスイッチで10段階に指示する。この折り合いをどうするかが1つの課題であるが、全て後優先とした。つまり新しい指示が入ると、それに対応した実行中の動作をキャンセルし指示に従う。回転速度の違いはマッピングで吸収した。
 
 基板を発注した。 大きさは 57.2 mm×40.6 mm と試作基板より一回り小さくマッチ箱サイズにできた。そして1週間で納品され、組み立てた。

そして設計通り動いた。

しかし低速での動きがぎこちないのが気に入らない。このままでは3度単位でしか制御できないので仕方ない事であるが、出来ればもっと滑らかな動きにならないか。サーボのデッドバンド幅が1μsなので上手くやれば(機械的なガタが無ければ)0.1度(=180度/2000μs/1μs)単位まで追い込めるはずである。

(続く)