(1)PIC 新 PWM でサーボを動かしてみる。

CCP タイプでなく PIC 12F 1572 の新タイプ High - Precision 16 - Bit PWMs
言語はアセンブラ
サーボは SG - 90 で XY マウントにつけ、Y 軸に赤レーザをつけて周囲を照射する。
操作は JOY ステイック


サーボ 2 個と XY マウントのセットは Amazon で¥679
上側 Y 軸のサーボとホーンの固定方法がモチモチになるので、サーボ固定ネジを加減締めにした。
この値段ですので文句ありません。

波長 650 nm の赤レーザは 3 V の別電源で点灯、クラスVA で 直視は 危険



(2)マスター目標

@初めての PIC 12F 1572 を動かす

Aサーボを新 PWM モジュールで動かす

BXY - JOY ステイックの AD 変換

CPICkit 3 と ICSP



(3)設定値や問題点

サーボ駆動には CCP PWM を 4 個 ( DUTY が 4 個 ) 搭載の PIC 12F 1501 などがあるが、設定上、Fosc 1 MHz で 周期 16 ms がギリギリで、20 ms にするには 500 KHz に下げるなど、いまいちヤル気が起こらなかった。
PIC 12F 1572 は High - Precision 16 - Bit PWMs とあり 3 個の独立 16 ビット PWM である。
内臓 32 MHz も可能ということでやってみることに。

@Fosc は 16 MHz ( Tosc 0.0625 μs ) とする。

APWM クロック ( PWMxCLK ) が設定でき、Tosc × プリスケーラ 8 = 0.5 μs とする。
CCP の × 4 がないが、うまく行くか?

Bサーボ周期は 20 ms なので、20 ms ÷ 0.5 μs = 40000 カウント = ( 設定値 39999 + 1 )

Cサーボ角度信号は 0.5 ms 〜 1.45 ms 〜 2.4 ms なので、0.5 μs の PWM クロックでは 1000 〜 2900 〜 4800 カウントとなる。
機械的余裕を見て 1200 〜 2800 〜 4400 とする。これが DUTY 値になる。

DAD は 10 ビットで やり方は既に経験済みで問題なしだが、10 ビット全てを使うのは初めて。
ステイックが短いのでうまく操作できるか?

EAD 値を DUTY に変換
AD 値 1024 で DUTY 4400、 AD 値 0 で DUTY 1200 に換算が必要で、換算式は DUTY = 3.125 × AD + 1200 となる。

アセンブラ で 3.125 倍するには、3.125 = 4 − 0.5 - 0.25 - 0.125 = 4 倍 - 1/2 倍 - 1/4 倍 - 1/8 倍なので、16 ビット左右シフトと 16 ビット加減算で行う。
DUTY = 3.125 × AD + 1200 = ( 4 AD + 1200 ) - ( AD / 2 + AD / 4 + AD / 8 )

XC - 8 コンパイラ の C 言語だと レベル変換関数の 1 〜 2 行で済むようであるが、処理が見えないのはプログラムしたという満足感が減るようで、C の勉強も気乗りしない。
関数のアセンブリソースが公開されているサイトはないかしら?

FPWM の起動と停止は、どういう手順になっているか?

GICSP で書き込む。
RA 3 ( MCLR / VPP ) を MCLR でなく、起動ボタン入力とし、10 KΩでハードプルアップしているが問題ないか?


(4)回路図

電源は PIC とサーボで別電源、GND 共通

RA 3 は起動ボタン、再度押しで停止の交互動作

RA 5 の LED は遅延タイマの時間確認やブレークポイントなどのデバック表示で使い、最終は起動サイクル中で点灯させる。

レーザは別途 3 V 単独電源から配線

RA 2、4 は AD 入力、 0.1μF はサーボのビビリ抑制

書込時は、PIC とサーボの電源を外し 、サーボコネクタを外している。
PICkit 3 を抜いてから電源とコネクタを接続している。



(5)MPLAB X IDE v2.26 ソースプログラム

初めての PIC なのでまず、WEB で製作記事を探したが見当たらない。

しょうがないので、英文データシート の PWM 部を、Google 翻訳の力を借りて対訳文を作成した。
初め、最終版と違う Preliminary 版を DL したので 2 度手間になった。
無料翻訳も相当レベルがあがっているが、もう一息。翻訳オプションでマイコン辞書追加などできないかね?

p12f 1572.inc ファイルは、PC 内でファイル検索するとすぐに見つかった。
これを眺めていると、新しい機能や全体が大体わかるのでプログラム順をイメージできる。
PWM が 3 個あり、モードも各 4 個、さらに オフセット 4 種、設定値は 16 ビット ( 8 ビット H、L )、やたら長い名前のレジスタが多くウンザリする。

最初、使い慣れた MPLAB IDE で NEW Project したが、この PIC が出てこないので、不慣れな MPLAB X IDE ですることに。

@BANK が 31個 ( 実質 10 個 ) もあるので 擬似命令 BANKSEL を使用する。
BANK 27 と BANK 31 の違いは?だが BANKSEL なので気にしなくていい。

AOSCCON
32 MHzは、 8 MHz を × 4 PLL するらしいが、英文が読み切れないのと早すぎの感じがしたので、無難な 16 MHz を選択した。
SCS<1:0> は 1X でも 00 でもいいみたい。

BTRISA ・・・問題なし

COPTION_REG ・・・Pull - UP 関連のみ

DADCON 1・・・TAD は、 TABLE 15 - 1 ( 網掛部がよく見えない ) より FOSC / 64 → 4 μs ( 16 MHz )、VREF + → VDD

EPWMxCON ・・・PWM 1 → EN、OE、active high、Standard PWM mode
以後 x 1 と x 2 が同じ設定

FPWMxCLKCON ・・・PWM クロック PS 8、HFINTOSC
式 22 - 1 の Period = { ( PWMxPR + 1 )・Prescale }/ PWMxCLK の Prescale 項があるのが理解できない。

GPWMxLDCON ・・・英文が読みきれていないが、リロードのここでデータをラッチに送り、PWM が出力される。
LDT = 0 にしておき、LDA = 1 にする。 LDA は、カウント一致でクリアされるようである。

HPWMxPH ・・・PHASE 値 ( 用途意味不明 )、電源 ON 時不定値なので 0 を入れる。
3 色 LED が意識された各モードのようだが、使いかたがよくわからない。

IPWMxDC ・・・DUTY 値 ; Microchip は、DUTY CYCLE と CYCLE をつけているが、つけるとどうも違和感がする。

JPWMxPR ・・・周期値

KPWMxTMR ・・・ 16 ビットタイマ値の内容表示、CCP のようにタイマ ON などの設定はなく自動で動く?

L とりあえず動いた PWMXY1.asm ( 拡張子は.txt に変えてある。 DL した時は、メモ帳でなく、ワードパッド以上で開くとデコボコしない )



(6)デバッグ


XY マウントは、テープで固定しておかないと転げ回る。

レーザは、 凸 形プラ端材に φ 8 を開けて差込んでから Y 軸に接着、赤く点灯しているのに黄色に写っている。

JOY ステイック本体は、基板に接着、足ピッチが狭いので基板に長穴を開けて足に直接配線した。
JOY ステイック基板と、普通ボリウム基板を作り、コネクタ差替え式にしておけばよかった。

爆撃機の回転銃座のような滑らかな動きが出来るフライホイル式ボリウムメカがないかしら?



@ビルド
データ保存後のトンカチアイコンのビルドで、かなりの頻度で Failed がでる。
ファイルが見つからないようなコメントが出るが、真の理由が書いてないので何も出来ない。
asm を無理やり修正し、保存し直してビルドしていると、そのうち成功するという情けない状態

不慣れで、Project フォルダの階層が多くなったり、名前がやたら長くなったり、ファイル名に勝手に X が追加されたり、asm ファイルの新規追加が思うようにできていないからかな?
asm ファイルもプロジェクトのどこに格納されているのか以前と違うようで不安一杯である。

AICSP で書込
秋月の PICkit 3 用書込アダプタには、 VPP - VDD 間に 10 KΩ が接続されていたので、内部プルアップをやめ、外付け 10 KΩプルアップとした。
なぜ こうしてあるのか?

MPLAB - X - IDE V 2.26 で ビルド → PICkit 3 で書込 が完了したとき、RA 3 ( 起動ボタン ) が入力されるときがある。 LOW に一瞬落ちる?
チャタ防止 10 ms 後ラッチなので考えられないのだが?

PICkit 3 User’s Guide に
A pull - up resistor ( typically around 10 k ) is recommended to be connected from the VPP/MCLR line to VDD so that the line may be strobed low to reset the device.

VPP / MCLRラインと VDD を 10 KΩ で接続することを推奨します。デバイスをリセットするために may be ストローブ LOW
とあり、LOW ストローブ信号してもいい?と言っているのかできると言っているのか悩ましいが、まわりには PICkit しかなく、PICkit が信号を出すと解釈すれば理解できる。 これは PICkit をデバッガとして使うときに RA 3 が MCLR ピンなら、リセット用に LOW を出すことができると言っているようである。
内部プルアップが有効でない時があるのか?

Pickit 3 から 5 V を供給しているが、書込み完了後 PICkit 3 を挿したままだと RUN しているのかな?→ している。
基板側から給電した場合も、書込み完了後 RUN するはず。

PIC 電源、サーボ電源、サーボコネクタは、 PICkit 3 を抜いたあと接続しているので問題ないと思う。
RA 3 はリセット以外に使わないほうが無難だとは思うが、禁止されてるわけではなくちゃんと起動停止入力として動作している。

新 PWM なので何度も書込みが予想されるので ICSP にした。これが大正解で、PIC は 1 回挿したのみで気分的、ハード的に非常に楽だった。
多 PIN PIC の場合、2 〜 3 本を専用にし、書込、レジスタ表示などが出来るといい。

B最初、起動ボタン → LED 点灯の簡単動作が反応なし、初めから大苦戦したが、INITIAL の中で BANKSEL が 1個ぬけていた。

CFosc の確認は、ループ遅延タイマで RA 5 の緑 LED をチカチカさせ、オシロで ON / OFF 時間を確認、バッチリ 16 MHz になっていた。
同時に遅延タイマプログラムも OK となり、これで勇気 100 倍となる。

DPWM 信号が出ていた。
PIC 電源接続時点で、サーボコネクタの信号ピンにオシロを当てると、キレイな波形が出ていた。
エーッと思い、計測すると 周期 20 ms、パルス幅 1.4 ms、これはイニシャルで 設定したニュートラル位置 ( DUTY 2800 ) の PWM 波であった。
手こずると思っていたのに、拍子抜けであった。
ワクワクしながらサーボのコネクタをつなぐと、シャッと音がしてニュートラル位置に動いた。
しばし感激にひたる ・・・


これは ニュートラルではなく、AD 最大時の波形である。
計測では 周期 20 ms、DUTY 2.2 ms ( 4400 × 0.5 μs = 2200 μs ) で ピッタリ


PWM の起動手順がよくわからなかったので、データシートで PWM に関係するレジスタを全てこうだろうとイニシャルで設定した。
イニシャルで LDA もセットしたため、ニュートラル値がラッチされたもので、その後 LDA がセットされないので初回ラッチ値を出力したままとなった。
このときサーボは、サーボロック状態で、ビビリはまったくなかった。

LDA とは、Load Buffer Armed bit とあり、Armed は聞きなれないが、「 兵役につかせる 」 のような意味みたい。

EAD 取込
起動ボタンを押すと、AD 取込が開始され、ニュートラル停止時にサーボがビビっていたので、ボリウム入力に 0.1 uF をつけるとビビリが納まった。

AD 取込と DUTY 更新サイクルは 5 ms としたが特に不具合はない。

XY - JOY ステイック の動作は思い通りだつたが、AD のMAX 値でサーボの機械的限度を超えたので、余裕を取り直した。
サーボはストッパで止まると思っていたが、グルグル連続回転した。単価が ¥300 程度なので壊しても気が楽。

JOY ステイック の操作は、スプリングリターンなのと操作軸が短いので予想通り難しいが、バルカンファランクスのように首を振って照射するので一応満足。
照射点を 1 点に止めるには独立のリターンなしボリウムでないと無理。

FAD 値を DUTY 値に変換
アセンブラの DUTY = 3.125 × AD + 1200 プログラムは数回のTEST を経て決まったもので、結果的にはうまく行っている。
機械余裕値をシビアにすると、多くは近似式となるので、シフト命令で丁度ピッタリ式にしてやれば良いようである。
結果的に機械余裕値が大きくなるかも知れないが、実際はホーンの長さで何とかなるので、思うよりラフでいい。
16 ビットは精度の心配はないが、ステップ数が増える。今回のAD 値 → DUTY 値 サブルーチンで 約 60 ステップ

PIC PWM の WEB 記事に C 言語が多いのは、このレベル変換処理が四則演算式で書けるからと思われる。
16 ビット整数の減算 3 回、加算 1 回、掛算 1 回、割算 1 回 とするとアセンブラでも 500 ステップぐらい、 C コンパイラではどのくらいになるのかな?
メモリが 2 K ステップなので収まらなければ、せっかくの 16 ビットが生かせないことになる。

G起動/停止の現状
電源投入時イニシャル動作としてニュートラル位置に動き、サーボロック停止

起動中で XY がニュートラル時、起動ボタンを押すと、AD 取込をやめ、緑 LED OFF → ニュートラルでサーボロック停止
起動中で XY がある位置にある時、起動ボタンを押す → ある位置でサーボロック停止

PWM 出力を完全に OFF するには、PWMxCON の EN、OE などを OFF し、BCF PORTA、X などが考えられる。( 未 TEST )

PIC CCP PWM の 巷 WEB 記事には、停止の方法が書いていないのが多いが、出力が Hi のままではないか?
どこかでこの Hi を なかなか Low に出来ないという記事を読んだ覚えがある。
タイマ ON ビットをクリア、CCP レジスタの該当ビットをクリア、BCF PORT などしてもうまくいかないという。

CCP PWM では、DUTY を 0 にして、自然停止 ( 出力 0 ) させるのがいいようである。
停止が最大 1 周期間遅れるので、緊急を要する場合は動力遮断など別の方法も必要

データシートや WEB 記事には起動までしか書いてないのが多いが、停止方法も書いといて欲しい。
リセットしたり、電源を切れば停止するよ ・・では実機には使えない。

H新 PWM で停止時の出力 OFF を TEST してみた。
停止時に、 DUTY を 0 にして、LDA = 1 にすれば出力 OFF となった。
PWMxCON は変更していない。

PWM 0FF サイクルと MAIN 起動終了が同時進行だが、気持ち悪ければ、PWM の出力 OFF を見てから ( レジスタ PWMOUT を見ればいい ) MAIN 起動を終了してやればいい。






(7)感想

目標の初等段階は達成できた。

@PWM は Phase、Offset の具体的使用法や 4 モード、3 個の同期など不明だらけで、まだまだ。
CCP タイプに比べ、周期の選択肢が豊富で、シンプルであり、使い易い。
サーボモータは、周期やDUTY 仕様が明確であり制御しやすいが、DC ブラシモータの PWM 駆動では、周期などが明確でなく、動いても適切な周期であるかの判断が難しい。
この 新方式は、周期が自由に設定できるので、DC ブラシモータの最適周期を TEST するのに使える。


AICSP は便利だが少ピン PIC では兼用になるので、互いの干渉に注意が必要だが PICkit 3 の入出力タイミング図などがないのでよくわからない。
書込み後に RA 3 入力が入る件がはっきりしていない。
書込み終了と同時に RUN しているが、0 番地から走らせるには、書込み後の 1 回だけ、RA 3 をリセット端子として使い、LOW ストローブ信号を出していると思われるがどうか?

BMPLAB X の操作性が?
エディタからプログラマに移動するのに直感では不可能、以前の MPLAB のほうがやりやすかったよう。
プロジェクト管理が厳密になった分、ドラッグ & ペーストが出来ないなど融通が効かなくなったようである。
MPLAB X は 項目選択後プロパテイから望みの操作へ ・・・ が基本のようである。






(8)参考資料

@ PIC - TECH / PIC マイコンアセンブラテクニック / 16 ビットシフト、16 ビット加減算

A AN 526 Microchip 算術演算 アプリケーションノート

B MICROCHIP ADVANCED PART SELECTOR / 仕様や付属機能から型番検索
CPU → 8 Bit、PWM Max Resolution → 16 Bit、ADC → 2 で PIC 12F 1572 も出てくるが、多ピンでこの PWM のがないみたい。
オシロがない場合、多ピン PIC で LCD 表示をしないとデバッグがつらい。






(9)その他

@フライホイル式ボリウムメカをやってみた。


100 均おもちゃトラックのフリクションギヤのタイヤ軸にプーリをつけてボリウムをまわしてみた。

回転オモリを回すがボリウムの回転が重いのでフリクションせず、スムーズに回らない。
回りだすと照点はスーッと移動するが、回転の軽いポテンショかもっと大きい回転オモリでないと無理のよう。

ゴムベルトを外して大きいプーリを直接まわすと、楽に照点を希望位置に移動できた。




AC 言語でのレベル変換方法を調べてみた。


AD 値 X を DUTY 値 Y に変換するのに比例関係の直線グラフを利用する。

太直線の範囲で X → Y を求める。

小数でなく整数の + - × ÷ で計算する。

ABCDXY を変数として全て計算させると調整時に楽だが、3200 / 1024 = 25 / 8 などとできるところまでやって PIC の計算負荷を減らしてやるといい。







---- 2018.05.19 ----