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)単位まで追い込めるはずである。

(続く)


2024年11月21日木曜日

PIC16F18xxxのA5ポートが使えなかった件に関する情報

 PIC16F18313、PIC16F18326、PIC16F18346 など PIC16F18xxx シリーズのPICを使ってみたが A5 ポートが入力にも出力にも全く使えなかった。色々調べてみたが全く原因が分からない。チップの系統的な欠陥か、まがい物を掴まされたかとも考えたが秋月でまがい物を売っているとも思えない。

この事から、これまでA5端子(ポート)は使えないという前提で、使わないよう設計してきた。

これは何かおかしいと最近再度調べたら、マイクロチップ社のホームページのフォーラムの中に同様の投稿を探り当て、答えが分かった。

https://forum.microchip.com/s/topic/a5CV400000015P3MAI/t395592

原因はPICのコンフィグレーション情報のFEXTOSCがOFFになっていなかったのだ。

次の記述を見て、内部発信器を使うのでFEXTOSCは関係しないと無視してきたが、
 
FEXTOSCがOFFでないとA5ポートはクロック発信器関係の端子として強制的に割り当てられ通常の入出力には使えないようだ。ただ、この情報はPICのマニュアルを探しても明確な記述が見つからず、幾つかの記述から類推するしかない。

A5端子が使えない事で何度かTRY&FAIL⇒設計変更したが、答えがこんな事だったとは・・・。

 

2024年11月18日月曜日

久留米黒棒本舗

 黒棒は関東のスーパーで普通に売ってるので、たぶん全国のスーパーでも売ってるんだろうと思っているが、その工場(黒棒製菓)は久留米市(福岡県)にある。

工場に隣接して販売店(黒棒本舗)があって製品の他、工場で出た半端物を安く売っている。これが1袋に約400g入って312円と格安である。それに黒糖のコーティングが厚かったりしてなかなか美味い。(写真の下の硬貨は500円玉)

工場の近くを通る時に寄ってみると、いつもある訳ではないが50%以上の確率で入手できる(大量に買う人がいるらしく5袋を予め大袋に入れたものもある)。家族や身近な人はみんなこれを大好きなので、今回は6袋も買ってしまった。

同じくあいすまんじゅうや白くまを作っている丸永製菓も久留米市にあるが、こちらに寄った事はまだない、というか売店があるかも知らない。


2024年11月12日火曜日

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

サーボモータのコントローラに手動スイッチを付ける事となった。そこで秋月で買っておいたレバースイッチを付ける事とした。これは左右に各2段階、プッシュスイッチも付いていて色々使えそうだ。

このレバースイッチを付けるためには8ピンのPIC16F18313では端子が足りない。水平用と垂直用の2つのスイッチを付ける事を考えると単純には12個の端子が欲しい。そこで手持ちの20ピンのPIC16F18346を使うこととした。これはPIC16F18326の20ピン版である。勿体ない気もするが増えたPICの12ピンを全てスイッチに割り当てた。そしてハードは次の様に組み上がった。


ソフトはPIC16F18313で作ったソフトを少し改造して使った。PIC16F18346になったのでプログラムメモリーが3.5KBから28KBに、RAMが256Bから2KBに大きく広がり使い易くなった。

このハードに乗せるソフトは最初にPIC16F18313用に作ったものを、いくつかの点を手直しして上手く動かすことが出来たが、レバースイッチの2段階の操作で速度を制御するのは使い勝手が悪そうだったので別に速度切り替えのスイッチを追加する事とした。ここはジョイスティックにすれば良かったかもしれない。

 そしてこんな回路になった。

この回路(実装基板)の隠れた機能は3つのPICに対応している点である。20ピンのPIC16F18346だとフルの機能を使えるが、14ピンのPIC16F18326だとロータリーコードスイッチが使えず、PIC16F18313 だとレバースイッチも使えずリモート制御のみになる。一方3つのPICに対して(メモリー容量が許せば)プログラムはほぼそのまま使える点である。

この回路ですでに基板の設計とプログラミングは済んでいるが、まだロータリーコードスイッチを入手していないので検証が出来ていない。機能が確認できたら基板を発注する予定である。

 そして、ロータリーコードスイッチを追加してこうなった。

ソフトも幾つか手直しして動くようになった。

 (続く)

 


2024年10月24日木曜日

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

 サーボモータ(SG-90)をPIC16F18313で動かすための基本的な計算が出来たところで実際のプログラムを作る。サーボモータを動かすために必要なパルス波形は次のようなものである。

2つのパルスの周期(20ms)はTMR2で決める。2つのサーボモータの角度に対応する2つのパルス幅(0.5ms~2.4ms)はパルス幅変調器(PWM5及びPWM6)で決める。

 サーボモータがある角度にある時、突然別の角度を指示するとサーボモータは最速(仕様では0.12sec/60度=500度/秒)でこれに追従する。これが目的とする動作に合っているのか、またサーボモータの負荷を高め寿命を縮めることにならないか気になるところである。そこでTMR2+PWMで生成できる最小の分解能である3度毎にステップを進める事とする。もし20ms毎に割り込みをかけて3度進めると150度/秒となり、良さそうである。TMR2にはポストスケーラがあるので、これを使うとこの1倍から1/16倍までのスピード制御が可能であり、即ち9.4度/秒~150度/秒の速度制御が可能である。

ロジックとしてはTMR2(のポストスケーラ)により割込みがかかったときサーボが目的とする角度に達していない場合は要回転を意味するフラグを立てる。さらにパルスの立下りで(IOCの機能を使って)割り込みをかけ、要回転フラグが立っている場合は次のパルス幅に相当する値をPWMに書き込む。そのタイミングがパルスの立下り後である理由はパルスの立下り時に処理を始めると処理のための時間的余裕が十分あるからである。時間的には20ms以内に処理を終わらせればよいので問題は無いだろう。なおIOC(Interrupt On Change)とはPICのピンの信号の変化を捉えて割込みを起こす機能であり、立ち上がりと立下りを個別に捉え割り込みを起こす事ができる。通常は入力信号に対して使う機能だと思うが、ここでは出力信号に対して使っている。

ソフトの開発と並行して汎用基板にプロトタイプのハード(コントローラ)を作った。 大きさは概ね2cm×4cmに収まった。

基板に載っている部品はPIC16F18313と電源のパスコン、LEDと電流制限用抵抗だけで他に接続用に電源コネクタ、サーバモータ用3Pコネクタが2つ、ホストと繋ぐシリアル通信用コネクタが1つあるだけである。シリアルインターフェイスはUSBを介してTeraTermから文字ベースでテストできるようにした。

電源を入れると各部の初期化を行い、TME2やPWMを起動、1.45msのパルスを作ってサーボを中点まで移動、その後パルス幅を0としてサーボを休止、割り込み可としてSLEEPする。

RS-Kager2-Servo313-032 2024/10/23 for RS-Kager2 ver 0.27
 Copyright(C)2024 MYcrosLip
*** Init Servo.
*** Start Interrupt.
*** Start Servo.
*** Sleep Loop.

あとはシリアル通信で受信したコマンドを解釈してPWMを制御しサーボを3度ステップで動かす。目的の角度に達したらパルスを止める。3度進むのに必要な時間は7.5msであるから50Hzの1周期(20ms)以内に終わり、タイマーなどを使った遅延操作は不要である。

実装した主なコマンドは<nn>H、<nn>V、Z、<mm>Gである。Hは水平サーボ、Vは垂直サーボの軸を回転(指向)させるコマンドで<nn>は-90度~90度の範囲であり、Zは原点(0,0)に復帰、Gは速度制御(<mm>は引数で1~16)である。

次の実行例で、90Hは水平サーボを90度に向け、90Vは垂直サーボを90度に向け、Zで原点に戻っている。小文字のhやvは動作確認のため1ステップ進むごとに表示させている。

90Hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
90Vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Zhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhvhv

 サーボの動作中でも次のコマンドを受け付ける。この場合、実行中のコマンドの終了を待たずにキャンセルし、後で来たコマンドを処理する。この動作を2つのサーボに対して各々独立して行う(逆に言えば処理待ちキューを作らずに済ませたという事)。

これで外部から文字ベースでサーボを制御できるようになった。

(続く)

 


 

2024年10月19日土曜日

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

 出入り検知器にサーボ・モータを動かす機能を追加できないか相談を受けた。水平と垂直の2方向の動きをサーボで作る。そこでSG-90という最も安価なサーボを秋月で入手して動かしてみる事に。

SG-90にはSG90-HVという軸が360度回転するタイプもあるが、入手したSG-90は可動域が180度のタイプである。SG-90の角度を制御するには電源5Vを加え、次のような20ms周期のパルス幅変調の信号を制御端子に加え角度を制御する。

 角度は0.5ms~2.4msのパルス幅に対応して0度~180度に変化する。中点(90度)のパルス幅は1.45msである。パルスを0.05ms(50μs)単位で変化させると180度を39ステップ、即ち4.7度単位で制御する事ができる。SG-90のデッドバンド巾は1μs(本当?)なので問題にはならないだろう。

この幅のパルスを作る事は難しくない。問題は周期の50Hz(20ms)との関係である。ポイントは大きなデューティ比 0.5/20~1.45/20~2.4/20 を細かく制御する必要がある事である。これを整数比に直すと10/400~29/400~48/400 であり、20msの1/400である50μs単位で制御する事になるが、これは試算値であって実際のSG-90がこれをどれ程の精度で追従できるかは分からない。

8ピンのPIC16F18313には2個のPWM(パルス幅変調器)が内蔵されていて丁度良い。このPWMはタイマー2(TMR2)と組み合わせて使う。


TMR2はFosc/4のクロックで動く8ビットカウンタであり、1/1, 1/4, 1/16, 1/64 のプリスケーラが利用可能。これを使ってFosc/4=500KHz、プリスケーラ=1/64、カウンタの上限(PR2)を155に設定すると約50Hz(=500KHz/64/156)が取り出せる。なおTMR2のポストスケーラ(1/1~1/16)からは直接信号が取り出せず割り込み用にしか使えない。

TMR2と組み合わせて使うPWMのパルス幅は10ビットで指定する。つまり8ビットカウンタの1カウント値の1/4まで指定でき、これは約32μsステップ(=20ms/156/4)単位で指定できる事になる。これを使って改めてパルス幅の指定範囲を計算するとカウント値は 0.5ms÷32μs≒15、1.45ms÷32μs≒45、2.4ms÷32μs=75 という値となる。つまり90度で30カウント差だから1カウントが3度の回転に相当する。

(続く)