2021年1月25日月曜日

PICのADC2の要注意点

 年末年始にADC2と格闘していたのは既に書いたとおりですが、
あるアプリにて更に問題点が露呈した為、ここに記載します。

PIC内蔵のA/Dコンバーターは10bitもしくは12bitに対し、
データー出力のレジスターは16bit。
そこで必ず、4bitもしくは6bit分が0で埋まることになります。
その0埋めをMSB側にするかLSB側にするかを設定するのが、
ADFMという設定ビットです。

通常はADFMをセットして、MSB側を0で埋める使い方が多いかと。
しかし10bitのA/Dコンバーターの下位2bitを誤差領域とみなし、
上位8bitだけを使用するというようなケースでは、
ADFMをクリアーするのは有用ですね。

ところがこの場合、ADC2内で積算処理すると、
ADACCがオーバーフローする場合が有ります。
ADACCが24bit長の場合は問題にならないと思いますが、
ADACCが16bit長のADC2では、ADC2内で積算してはダメです。

この解決策としてはADFMをセットしてデーターサンプリングと積算を行い、
その後のプログラムにてMSB側にデーターをシフトするという流れにしましょう。

2021年1月21日木曜日

泉天空の湯

ビッグサイトへお出かけするついでに、入浴&マッサージをと思い、
大江戸温泉物語へ行く気満々だったのですが、
なんと緊急事態宣言の影響で休業中とのこと。

ちと脱力しつつ、マッサージだけでも受けられるところを探していたら、
もっと近いところに温浴施設を発見!
それが今回の泉天空の湯 有明ガーデンです。

ビッグサイトの用事を済ませ、いざ泉天空の湯へ。
ビッグサイトからなら徒歩でも十分行ける距離。
大江戸温泉物語より断然アクセス良いですね。

このお店は有明ガーデンという複合施設の中に入ってます。
有明ガーデンは大きくて駅からの案内も随所に有るので迷いません。
しかし残念なことに、泉天空の湯の入口が判りづらいというオチ。
途中まではSPAの方向を示す矢印案内があるのですが、
有明ガーデン内に入ると、それが無くなってしまいます。
おかけで、1周ぐるっと見回ることになっちゃいました(笑)

泉天空の湯はシアター棟の裏側に有る建物内に存在します。
ビッグサイト方面から来ると、この建物の入口が ちと判りづらいので、
となりのショッピング棟から渡り廊下を通って泉天空の湯へ行くのが良いかも。

そんなこんなで到着しまして、いざ入館。
靴を脱いで下駄箱へ。
下駄箱の鍵にICチップが付いてて、それで館内の精算を行うシステム。
まず下駄箱の鍵をフロントに渡してチェックイン処理。
タオルセットと館内着で1650円ですが、チェックインはあくまで、
ICチップへの登録処理のみ。
精算は全て退館時に行いますのでチェックイン時の支払いは無し。

泉天空の湯は2フロアー構成。
浴室とリラクゼーションは上のフロアーに有りますので、
まず上のフロアーに上がり、脱衣所へ。
脱衣所のロッカーは下駄箱の鍵とは無関係のフリースタイル。
好きなところを選んで使えます。

荷物と衣類をロッカーに入れ、いざ浴室へ。
まず最初は かけ湯ですが、湯温が高めで ちとビックリ。
かけ湯の温度が高いと体にショックが大きいわけで、
かけ湯の意味が半減するような気がするのですが、どうなんでしょ?

浴槽の種類は そこそこ有りますね、ここ。
天然温泉は露天風呂の浴槽2つ。
2つの違いは湯温です。

内湯の方はバイブラとか炭酸泉とか諸々。
内湯の方は全般的に湯温が抑え目で、私としては好印象。

洗い場の水圧が ちょっと弱めな感じです。
シャワーは まぁなんとかなるものの、
カランの方はお湯の出が弱くて、洗面器にお湯を溜めるのに手間が。

歯を磨こうと思いきや、ここは歯ブラシが置いてないんですね。
ちょっと残念な感じ。
ちなみに髭剃り用のカミソリは置いてあります。

お風呂から上がり、マッサージへ。
マッサージルームの手前に岩盤浴コーナーが有りましたが、
岩盤浴は別料金とのこと。
私は岩盤浴に興味無いので特に問題有りませんが。

マッサージは無難にボディーの40分コース。
んーーー、上手とは言いがたい感じかなぁ。
また利用したいかと聞かれると疑問を感じるところ。

下フロアーに降りると、飲食コーナーがあります。
食事用のエリアと、ドリンク/軽食用のエリアとに分かれてますが、
カウンターは全く一緒(笑)
今回は食事後に入館したのでどちらもスルー。

飲食コーナーの更に奥に、リラックスラウンジという休憩コーナーがあります。
TV付きのリクライニングチェアーが並んでる他、
マットレスが積み上がってるゴロ寝コーナーも。
ブランケットも備えられてるので、ここで仮眠も出来ますが、
熟睡できるほど暗くないという点と、飲食コーナーの音が丸聞こえで騒がしいので、
実際ここで熟睡するのは厳しい気がします。

最後は自動精算機で支払いです。
機械にICチップをかざし、利用額を払います。
もちろんクレジットカードも利用ですが、電子マネーはNGでした。

支払いを済ますと出口ゲートを通るためのQRコード用紙も出てきます。
それをゲートにかざして通過し、下駄箱コーナーへ。
退館という流れです。

施設が新しいので、どこもかしこも綺麗。
本来は24時間営業らしいので、お台場で一晩過ごすなら選択肢の1つになるかも?
ただ熟睡は厳しいので、そこだけは割りきりが必要かと。
きちんと寝たいのなら、隣接するホテルを使えということなんでしょうけど・・・・(笑)

余談になりますが、入館時に「ヴィラフォンテーヌ・ヴィラージュ」の
会員登録を勧められました。
隣接するホテルの方の会員システムなのですが、
入会すると泉天空の湯が割引になると言われまして、
入会金も会費も無いので、それなら入会しておこうと思ったものの、
実はこれ、全くムダな代物(笑)
会員割引で入館すると確かに若干安くなるんですが、館内着が付かなくなるんですね。
で館内着を追加してもらうと、通常料金と同額になるという・・・・・・・
館内着無しで利用したい人には有用かもしれません。

2021年1月17日日曜日

フォトカプラーをマイコンに接続

 非常に初歩的な内容なのですが、実際に問題ある設計を見かけたので、
念のために記載しておきます。

マイコンで外部機器からの信号を受け取る際に、
フォトカプラーを噛ますことはよく有りますね。
電圧が違う回路だったり、絶縁が必要だったりと、目的は様々。

しかし大抵の場合、基本的な回路は下記のような構成かと。


 









フォトカプラーがOFFの時はプルアップ抵抗でハイレベルになっていますが、
フォトカプラーがONになるとローレベルになるという動作ですね。

ここで使用するフォトカプラー、速度も要求されないような条件だと、
TLP785等のもっとも基本的なタイプを使用されると思われます。
ここにTLP627等のダーリントン出力のフォトカプラーを使用してはいけません

ダーリントン出力は出力ON時の残電圧が高いので、
マイコン側入力のローレベル規定に達しない可能性があります。

マイコンが5Vで動作している場合には さほど問題にならないと思いますが、
最近の流れは低電圧化なので、低電圧動作のマイコンでは要注意です。

2021年1月7日木曜日

PICのピン振りの修正

 V/AプローブのPICマイコン部で、回路図レベルの間違いが露見。
今回は その修正のお話です。

こういう話を書くならば回路図を載せるところなんですが、
V/Aプローブは未完成ということもあり、まだ回路図が公開できません。
内容がわかりづらくて御免なさい。

V/AプローブにはPIC16F18456というマイコンが載っています。
これで各種制御を行っているわけです。

PICマイコンですから当然ながら内蔵A/Dコンバーターも有るわけですが、
外付けA/Dコンバーターも使用しておりまして、
PICとのインターフェースはSPIバスを使用しております。

それとは別に、V/Aプローブをデーター収集用機器と接続する為の外部インターフェースとして、
SPIのようなバスを用意しております。
「SPIのような」と書いているのは、動作的にはSPIバスそのものなのですが、
電気的な仕様が通常のSPIバスと異なっているからでして、
PICマイコン側は標準で内蔵されているMSSPを使っております。

回路設計上、外部インターフェースはSPI1系統、
A/DコンバーターはSPI2系統に割り振っておりました。

昔のPICマイコンでは、各周辺機能のI/Oピンは割り振りが固定なので、
繋ぎ間違えていた場合は基板上でジャンパーを飛ばして修正していたわけですが、
最近のPICマイコンではPPSという機能で、周辺機能の接続ピンを任意指定できるので、
昔よりは かなり楽に回路設計を進めることが出来ます。
V/Aプローブも同様に、ラフに回路設計しておりました。

V/Aプローブのファームを書き始めまして、
PICのPPSにてピン振りを始めたところ、問題が発生。
回路図通りにピンが割り当てられないことが判ったのです。

PPSって実は、どこでも好きなピンに割り振れるよ、と言う超便利な仕様ではなくて、
割り振れないピンというのが一部有るんですね。
例えば28ピンパッケージのPICマイコンならば、I/OピンはポートA、ポートB、ポートC、ポートEの
4つに分類されておりますが、ポートEはMCLRなので割り当て不可として、
残りのポートA~Cの内、どれか2つに割り振り可能になっています。

具体的な話をしますと、V/AプローブのSPI1系統は回路図上でポートBに繋いでおりました。
SCK1やSDI1、SDO1は問題無かったものの、SS1のみがポートBに割り当て不可だったのです。
ポートBに割り当て不可というのは、ポートAかポートCならば割り当て可能という話。
これがPICマイコンのPPSの仕様上の制約なのです。

ちなみにSPI2系統は全てポートCに繋いでいたので、割り当ても問題ありませんでした。

基板を改造してジャンパー飛ばすのは避けたいなぁと思い、対策検討。
すると、以下の3つの方法がありました。

(1)SS信号の動きをソフト経由で他ピンに渡す
ソフトで入力ピンの状態を監視し、SS入力信号が変化したらソフトウェアで、
正しいSS入力ピンの状態を動かすという方法です。
前提として、SPI動作中でも各ポートの単純I/Oが生きてることが必要です。
EUSARTのI/Oを割り振られたピンは、単純I/Oの入出力が切り離されるので、
将来的にSPIも 同様の仕様になる可能性はあるかもしれません。
もしそうなった場合、この方法は使えなくなってしまいますね。

(2)SPI1とSPI2を交換する
実は今回、V/Aプローブで使ったのがこれ。
SPI1とSPI2は機能的には全く同一のもの。
なので交換しても問題ありません。
ということで、A/DコンバーターではSPI1を、外部インターフェースではSPI2を使うことに。
するとピン割り当ても全て問題無くなりました。

V/Aプローブでは外付A/DコンバーターのアクセスにSS信号を使う必要がありません。
PIC側がマスターになるからです。
なので今回は うまく行ったという話でして、
SPI1もSPI2も両方スレーブというような案件の場合は この方法だと解決しません。

(3)CLCを活用する
案外汎用性ありそうな方法としてCLCを使う手を思いつきました。
CLCというのはPICのI/Oピンをハードロジック回路に繋ぎ、
ソフトウェアを介さずにちょっとしたロジック処理を行うことができるという代物。
簡易PLDと呼べばいい感じかな?
これもPPS経由で任意のピンに入出力を割り当てできるので、
ジャンパー線の代わりに、PIC内部でピン間接続を行うことが可能になります。
ジャンパー線のように双方向で信号を流したり、
アナログ信号を送ったりということはできませんが、
PICの汎用性の高さを物語る上で、面白い方法の1つかと思います。

2021年1月2日土曜日

PICのADC2格闘 その3

 前回の話でADRPTとADCRSの設定については解決したはずですが、
それでもまだ、出力される値が何か変なのでした。

(3)Errataの問題

ここで念のため、ERRATAを確認してみることにしました。
今までの経験で、ERRATAの不具合にぶつかったことはほとんど無いので、
あんまり期待はしていなかったわけですが・・・・・・

すると、なんとADC2には3つの不具合が載ってました。
この内、ADGOビットに関する不具合はリビジョンA2までで、
私が使ってるリビジョンA3の石では修正済み。

2つ目の不具合はスリープ動作関連ですが、
私はスリープ機能を使っていないので、これも問題になりません。

最後はA/Dコンバーターの基準電圧として、
PIC内蔵の定電圧源(=FVR)を使用する場合の不具合。
これは完全にヒットです。
というか、PICの内蔵A/Dコンバーターを使う上で、
基準電圧源を外付けする人が どれだけ居るのやら・・・・・・・
大概の人は、この不具合がヒットすると思われます。

で、実際に内容を確認してみると、基準電圧にFVRを使用すると、
データーに誤差が出るらしい。
どれくらいの誤差とかまでは記載無いので、ちょっと曖昧ですね。
対策としてはtADを8μs以上にすること、だそうな。

えーと、マニュアルの434ページを見る限り、8μsを超える設定ってNGなんですが・・・・
頭を抱えつつ、今度は558ページの仕様を確認すると、
tADの設定範囲は1~9μsとなっています。
ということは、8~9μsの値に設定すれば大丈夫ということか??

とりあえず、その値に直してみようと手をつけたところで、1つ気付きました。
A/Dコン用の専用発振器が使えないやん。
ケース バイ ケースでメインクロックを変更できるようにと、
A/Dコンバーターの動作クロックに専用発振器を使うようにしてました。
しかしこの発振器、周波数をユーザーが変更不可なのです。
この専用発振器を使った場合のtADは約2μsだそうな。
なのでERRATAの対策を行うには
専用発振器を諦め、メインクロックを使うしかない
と。

仕方無いところなので、メインクロック使用に切換え、
tADを約9μsに設定いたしました。

で、結果はどうかなと・・・・・・・ 変わらん。orz

(4)アクイジョンタイムとプリチャージ時間

ここから色々と試行錯誤しているうちに気付いたのですが、
平均化の為の積算回数が増えるほど、出力される値が減っていくとな。
誤差が出るのではなく、値が減っていくんですね。

そこで、積算前の値も同時に見比べてみることにしました。
以前の記事でADRESの存在意義に異を唱えておきながら、
まさかここでADRESが必要になるとは・・・・・・・orz

気を取り直し、ADRESの値と平均化処理後の値を同時にモニターしてみると、
ADRESの値が だんだん減っていってる!!
そりゃー、平均化後の値が少なくなってしまうわけですね。

ここからがまた試行錯誤になっちゃったわけですが、結論としては、
アクイジョンタイムとプリチャージ時間を設定するとダメ。

Errtaに不具合が載っていないということは、
石自体には問題無いということなんでしょうね。
ということは、他の設定とかも絡んでる可能性が大ですね。
しかしこれ、ADC2の入力部を詳しく把握する必要があるので、
現時点ではスルーすることにします。
当然のことながら有効な機能だから実装されてるわけでしょうから、
ちゃんとした使い方が解れば使用していきたいところなので、
その内 時間があるときにでも手を付けてみることにしましょう。

 

ということで、これでやっと想定どおりの動きをしてくれるようになりました。
長かったぁ・・・・・・・・

余談ですが、PIC16F18456のADC2、ADACCが24bit長に拡張されてました。
さすが問題あると気付いてたようですね。(笑)
おかげで12bitのA/Dコンでもガッツリ積算できます。
むしろこっちの方が128回まで積算かけられる分、18F47K40より優秀という話に。
ちなみに128回というのはADCRSから来る制限。
ADACCが24bit長なら12bitのデーターは4096回まで積算できるはずですが、
あいかわらずADCRSが3ビット長なので、2^7 = 128 という上限になっちゃってます。

実はそれよりも、PIC16F18456のErrataが出てきてない方が気になってます。
今までの例からチップに不具合が無いとは思えないので・・・・・・
早くErrataがリリースされて欲しいなぁ。

2021年1月1日金曜日

PIC18Fで丸め処理を含む8除算

 内容が重い話を続けて書いてると気分転換したくなったので、
少しだけ違うことを書いてみます。

ビットシフト使って割り算を行い、端数を四捨五入する丸め処理を行う方法です。
もちろん他にも方法は有ると思うので、これが正解というわけではありません。

ターゲットの石はPIC18F47K40等のPIC18Fシリーズとします。
16Fシリーズだと命令が異なる為、そのまま使えません。

16ビット長のデーターを8で割る例です。
上位がDATA-H、下位をDATA-Lと仮定。

1)    RRCF    DATA-H,1,0
2)    RRCF    DATA-L,1,0
3)    RRCF    DATA-H,1,0
4)    RRCF    DATA-L,1,0
5)    RRCF    DATA-H,1,0
6)    RRCF    DATA-L,1,0
7)    CLRF    WREG,0
8)    ADDWFC    DATA-L,1,0
9)    ADDWFC    DATA-H,1,0
10)    MOVLW    
0x1F
11)    ANDWF    DATA-H,1,0

説明しやすいように、頭に行番号をつけておきました。

まず、1行目~6行目でビットシフトを使って8除算。

7行目~9行目が丸め処理です。
4行目まででデーターが奇数だった場合、
6行目の処理後にキャリービットが立っているわけです。
このキャリービットが端数と見なせるので、キャリービットが寝てれば切り捨て、
ビットが立っていれば切り上げすればいいわけです。
それを7行目と8行目で実行しています。
DATA-Lの切り上げ処理の結果、繰り上がりが発生する場合もあるので、
9行目で繰り上がりの処理を行っています。

最後、DATA-HのMSB側3ビットには不要データーが入るので、
10行目と11行目でそれを除去しています。


2021/1/25 追記
上記のコードだと問題有る点を発見。
元DATAがか0xFFFFの場合、処理後のDATAが0x2000になってしまいます。
(正しくは0x1FFF)

DATAがフルスケール値の場合のみ、繰り上げをスルーする処理が必要ですね。

PICのADC2格闘 その2

(1)データー出力レジスタの間違いの話

 前回の話の続き、バースト平均化モードでは目的達成不可と判明したので、
今度は平均化モードで挑戦することに。

平均化モードでは個々のサンプリングのトリガーがこちら側で制御可能。
ならば一定間隔を空けてトリガーを掛け、全体で20msになる様、調整してやれば良いはず。
とは言え、20msをソフト的に設定することは出来ないので、
PICのI/Oピンからタイミング信号を出し、オシロスコープで時間を測ります。

この目論見は成功。
トリガー間隔を微調整することで目標の20msに合わせることが出来ました。
と・こ・ろ・が・・・・・・・・・・・あくまで感覚的な話なのですが
なんとなく平均化されていないような感触がするんです。
というのも、データー値の変動が平均化前と一緒っぽい。

改めてマニュアルを調べてて私の勘違いに気が付きました。
単発のデーターと平均化処理したデーターが出てくるレジスタは別物だった!!

平均化処理も何もしていない素のデーターというのはADRESというレジスタに入ります。
このレジスタ名は従来のADCの出力データーレジスタと同一。
なので、ADC2の出力データーレジスタも てっきりADRESだと思い込んでました。

しかし実際には平均化処理データーが出てくるのはADFLTRというレジスタでした。
なんと紛らわしいことやら。
平均化処理を使っててもADRESからデーターを読むことが可能ですが、
そんな使い方する人は ほぼ皆無でしょう。
ならばデーター出力のレジスタは統一して欲しかったところです。
この辺りからADC2のインテリジェンス性に疑問を感じ始めたところ。

(2)ADRPTとADCRSの謎

出力レジスタの間違いに気付き、早速修正を行いまして、いざ再実行。
すると・・・・・・・やっぱり値が変。 orz

あれこれ試して、やっと原因が判明しました。
それはマニュアルに記載されている下の式。

ADRPT = 2^ADCRS

これだけ見ると、ADRPTを設定すればADCRSにも値がセットされる様に思われます。
しかし両方とも読み書き可能なレジスタだし、そもそも2^ADCRSは2のべき乗値。
ADRPTからADCRSへの変換は不可能でしょうから、
ADCRSを設定するとADRPTに値が入るという解釈かと。

と、このように漠然と解釈していたのですが、全く違いました。
この2つのレジスタは目的が異なるもので、
それぞれ設定してやる必要がありました。

ADRPTは平均化処理の際のサンプリング回数を設定するもの。
それに対しADCRSはサンプリングにて積算されたデーターを
ADFLTRレジスタに出力する際に割り算する値を設定するのでした。

だから上の式の意味は、「ADRPT」と「2^ADCRS」が同じ値の時に、
平均化処理が成り立つんだよ、という意味なのでした。
なんという紛らわしい記載や。 orz

そもそもですよ、平均化するという動作モードならば、
常にこの2つの値は同一になっていなければならないじゃないですか。
ならばこれをユーザーがレジスタ設定で合わせるという仕様はおかしいわけです。
この時点で確信しました。
ADC2はインテリジェントなユニットではないと。

上に書いた様に、2^ADCRSは2のべき乗値ですから、
ADRPTの値も好きな値を使うわけにいきません。
ADCRSは3bit長なので、設定可能値は0~7。
2^0 = 0
2^1 = 2
2~2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
具体的に2^ADCRSの値は上記8つしか選べないわけです。
で、ADRPTもこれに合わせる必要があるわけですから、
ADRPTの値も8種類しか選べません。

もう、最初のADC2への期待がボロボロと音とを立てて崩れてます。(;;

気を取り直して、サンプリング回数128回の設定で試してみることに。
ADCRS = 7、ADRPT = 128 という設定ですね。

いざ動かしてみると平均値データーが明らかに変!!

予想されるデーター値はだいたい判っていたのですが、とんでもなく値が異なっていました。
今度は何や。(;;

これですが、ADC2の内部構成に問題が有りました。
サンプリングデーターが積算されていくレジスタはADACCなのですが、
このレジスタ、16bit長しかありません。
今回使っているA/Dコンバーターは10bitなので、
10bit長のデーターを128回積算するとADACCが溢れてしまうのです。
なんという設計仕様。orz

なので今回の場合は64回までしか積算してはいけないというオチだったのです。
こんなのユーザーが考えて設定値に制限加えなければならないなんて、
ADC2は なんと頭の悪いユニットなのでしょう。(;;
PIC16F18456の場合、A/Dコンバーターは12bitなので、
積算回数は16回が上限ということになるんでしょうねぇ、きっと。

気を取り直して、ADCRSに6、ADRPTに64を設定したら、
それっぽいデーターが出力されるようになりました。
とは言え、こんな罠のような仕様があるならば、ADC2で平均化処理せずに、
ソフトウェアで処理した方が よほど安心な気がします。
積算回数の上限も無くなるし、ソフトで処理してもそんなに重くはないです。
ADC2の平均化モードは 存在価値に かなりの疑問を感じます。

1つ、確実に判明している問題として、平均化処理時の割り算計算についてです。
真っ当な計算ユニットであれば、割り算時に発生する端数の丸め処理も、きちんと行うはず。
しかしADC2の場合、ADCRSの設定値に従ってビットシフトするだけで、
端数の丸め処理を行っていません。
(マニュアルにも記載が無いので、念のために実機確認してみましたが、
やはり丸め処理は行われていませんでした。)
偶数をビットシフトで割る場合は端数が出ないので問題になりませんが、
奇数の場合は端数が出てくるので、ちょっと問題があります。

具体例を挙げますと、10進数で111という値を4で割ります。
単純:計算なら 111 ÷ 4 = 27.75 となりますね。
これをビットシフト方で割り算してみましょう。
10進の111 => 2進で1101111
4で割るというのは、右側に2ビットシフトすることになりますので、
1101111を2ビットシフトすると11011。
11011を10進に戻すと27です。
27.75が27として出力されてしまうわけです。
簡易計算ならともかく、真っ当な計算ユニットとしては、これは問題でしょう。
とりあえず、今回はADC2を利用する前提の話なので、
この問題はスルーいたしますが、後日改めて対策することにします。

余談になりますが、対策するとしたら以下の2つの方法が考えられます。
・1つ目は平均化処理を全てソフトで処理する。
・2つ目は、ADC2を積算モードで動かし、ソフトで割り算処理を行う。
・3つ目として、ADCRSの値を1少ない値に設定し、丸め処理を含めた割り算をソフトで行う。

3つ目の方法は捻り技になるかもしれません。
ADCRSの値を1少なくすると、平均値の2倍の値が出力されます。
上記の計算例なら、2進の1101111を4ではなく2で割ることになるので、
計算結果は110111、つまり55という値が得られます。
これをソフトにて丸めも含めて÷2の処理すると28という値が出るわけです。

ともあれ、とりあえず平均化モードは動くようになったぽいので、
一安心かと思いきや、今度は別な問題が浮かび上がってきました。
それについては次回へ。

(続く)