« 2015年3月 | メイン | 2015年6月 »

2015年5月30日 (土)

TFT LCDによるアナログメーター 3

<カテゴリー:PICマイコン

Aameter2_2

PC上で動作するコードジェネレーターのバグと、C言語のポインターの使い方でかなり苦労しましたが、左のような、アンテナアナライザーの表示画面ができました。 

なぜLCD上の疑似アナログメーターの表示にこだわるかと言えば、それは、マルチファンクション画面が得られるからです。 画面はこれで完成ではなく、アナログメーター部分を消して、周波数対SWRのグラフを描かせる事により、LCD表示のアナログメーターも生きてくる訳です。 しかし、ここまでの表示で、const用に使えるROMエリアを含めて85%くらい使っており、これ以上のグラフィックを仕込むとエラーになります。 SWRのグラフ表示は、実際にハードと結合した時の様子を見ながら考える事にします。

通常、プログラムの効率化の為、共通の関数を条件判断しながら、使い回ししますが、これをやると、条件判定の為、動作が少しだけ遅くなります。今回のプログラムでも、メーター指示や、数値の表示の中で、IF文が多くなると、目に見えてメーターの動きはおそくなりました。

対策としては、条件判定を必要最小限に抑える代わりに、関数をいくつも設けることにしました。ROMの容量アップになりますが、プログラム用の容量より、グラフィック用のROM容量がはるかに大きく、全体的にはあまり影響はありません。

残り15%のROM容量でどこまで出来るかは、これからの作業になりますが、ROM容量128Kバイトのマイコンは64pinのQFPですので、出来ることなら、この44pinの64Kに収めたいところです。 また、クロックも現在20MHzですが、これを32MHzまで上げる事にします。

このLCDの表示状態で、SWRやZ,R,Xをリアルタイムにデジタル表示すると、アナログメーターの指針の動作速度は、どんどん遅くなっていきますが、 その上で、周波数カウンターを動かすと、周波数カウンターの基本ゲート時間が10ミリ秒必要であり、メーターの指針の動きはもっと遅いものになりそうです。 改善策としては、周波数カウンターは、外付けPICマイコンで処理し、カウントした結果だけをもらうという案になりそうです。

また、RやXを表示させるためには、10000倍した整数計算では、その精度が不十分で、32bit浮動小数点による計算はマストですから、これもLCD表示マイコンから切り離した方がよさそうです。

これら、周波数カウンターやR、Xのベクトル計算も、LCD上でのグラフィック表示がなければ、8bitマイコンでも十分処理可能なものです。

これからハードの設計を始めますが、基本設計はほとんど出来ていますので、蛇の目基板を使い、いかにして手作りするかが、本当の課題です。 完成はいつの事やら。

アンテナアナライザーの製作(センサー回路) に続く。

2015年6月30日追記

ハードウエーアーが基板状態ですがほぼ完成し、LCDアナログメーターの改善を行う事が出来る時期になりました。 当初、メーターの振れ分解能は1度きざみでしたが、動きが粗く、とてもアナログメーターの動きをまねる事ができませんでしたので、LCDの1ピクセル単位の変化となる、0.25度きざみでドライブする事にしました。 しかし、0.25度きざみでそのまま駆動すると、ゼロから無限大までの移動時間は10秒を超えてしまいます。 動きはスムースですが、実用的では有りません。

Aa50meter3_2

そこで、目標の角度と、現在位置の差を計算し、T/Gに対して数度しか離れていない場合、0.25度きざみで送り、その倍の差が有る場合、0.5度きざみで送り、同様に差が倍になるごとに送る角度も2倍にし、最大で2度きざみで送るようにしました。 この細工により、T/G角度近くになると、指針の動きにブレーキがかかりますので、本物のメーターの動きに、より近くなりました。

結果は非常に良好で、7MHzのアンテナをつないで、実際にSWR最少周波数を探す操作をすると、かなりスムースに指針が追従し、なんなく共振点に周波数を合わせる事が出来るようになりました。 本物のアナログメーターには及びませんが、さほど違和感なしに操作できます。 これから完成度を上げていきますが、ROM容量が、目いっぱいの状態ですので、マイコンを変更するまでは、とりあえず、お預けとなりそうです。

左のLCD画像は最新の表示画像で、50Ωのダミー抵抗を装着した時の表示です。

アンテナアナライザーの製作(センサー回路) に続く。

INDEXに戻る

2015年5月12日 (火)

TFT LCDによるアナログメーター 2

<カテゴリー:PICマイコン

 8bitのPICマイコンでは容量不足で、まともにLCDの表示が出来なかった為、マイコンを16bitに替え、かつLCDも一回り大きな2.4インチサイズにして、実用サイズのLCDアナログメーターを実験中です。

16bitpic_pwb_4

16bitpic_lcd

マイコンはi/oに不足がありますが、とりあえず簡単に実験できそうな、PIC24FJ64GA004という16bit品と、前回と同じメーカーDisplaytechの、DT024CTFTという、320x240ピクセル2.4インチサイズで作ることにしました。 マイコンが16bit品になったので、コンパイラもXC16に変更必要です。そこで、開発環境も、MPLAB Xに変更する事にしました。 しかし、これが、くせもので、従来のやり方では、全く動きません。 すでに通り過ぎた方は、問題ないにしても、これから、XC16やMPLAB Xの環境でPIC24xxxの開発を始めようと思っている方に多少なりとも、役にたつならと、失敗と対応方法を紹介します。

まず、MPLAB Xですが、エジターの日本語が文字化けして読めません。 WEBで調べていくと、プロジェクトを作るときにEncodingの指定をやるのだそうですが、それを見落としてプロジェクトを作ってしまっているので、後から、Encodingを変更する方法を探す必要がありました。 

プロジェクトをオープンして、プロジェクト名の周りが青色になっている状態で、マウスを当て、右クリックすると、一番下にPropertiesがありますので、これをクリックします。出てきたダイアログの一番上にるGeneralの文字をクリックすると、中央下にEncodingの設定ランがあります。その中から、Shift_JISを選択すると、文字化けは直ります。

初期段階として、PICのソースファイルにConfig事項を書き並べて、チップの初期設定をおこないますが、HI-TECH CとXC8やXC16では全く書式が異なります。

HI-TECH Cによる16F1939のConfig記述例

 __CONFIG ( FOSC_INTOSC & WDTE_OFF & PWRTE_ON
 & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF
& FCMEN_OFF);
 __CONFIG ( WRT_OFF & VCAPEN_OFF & PLLEN_OFF & STVREN_OFF & BORV_LO
& LVP_OFF );

これに対して、XC16で24FJ64のconfig記述例

// コンフィギュレーション設定 Fosc=20MHz Xtal
#pragma config POSCMOD = HS, I2C1SEL = PRI, IOL1WAY = ON
#pragma config FCKSM = CSDCMD, FNOSC = PRI
#pragma config WUTSEL = LEG, IESO = OFF, WDTPS = PS1
#pragma config FWDTEN = OFF, ICS = PGx1, COE = OFF, BKBUG = OFF
#pragma config GWRP = OFF, GCP = OFF, JTAGEN = OFF

XC16をデフォルトでインストールすると、以下のホルダーの中に、各PICの品種ごとに、どのように設定するか説明があるのですが、書いてある単語が何を意味するのか判らず、結局、該当チップの英文データシートを読む必要が生じます。それも大変な作業で、今回のPIC24FJ64の設定がなんとなく判るまで2日間もかかりました。 それでも上の設定が正しいのかは?です。とりあえず動いいていますので、良しとします。

C:\Program Files (x86)\Microchip\xc16\v1.24\docs\config_docs

最近のPICマイコンは、i/oピンの多重化がすさまじく、何もしなければパラレルポートを使う事が出来ません。このマイコンも、端子機能はピン配置図に書かれている名称の左から順に優先度が高いと説明されていますが、一番右側に書かれたパラレルi/oをそのまま使う方法が判りません。

ほとんどのi/oで一番左側に書かれている機能はADです。 ADを使うか使わないかを最初に設定しないと、i/oをHに設定したのに、いつのまにかLになっているとかの異常動作に遭遇します。 HI-TECH CでもADは最初に設定する事が必要でしたが、16bitになって、ほとんど全てのi/oがAD対応になっていますので、面倒がらずに、全部設定が必要でした。 ADの設定を行うと、各ピンの一番右側に書かれた端子機能をそのまま使う事ができました。 

次にHI-TECH CではLATB1などのようにi/oのビット指定が出来るのですが、この単語ではエラーになります。これらの定義はincludeファイルの中にあるはずですが、そのファイルを見つける事ができませんでした。結局、WEBで調べてLATBbits.LATB1のように記述したら良いと判るまで、またまた2日間もかかってしまいました。 16bitをパラレルで一挙に書き込む場合はLATB = 0xFFFFでOKでした。

とりあえず、マイコンはソフトで書かれた通りi/oのH,Lの設定が出来るようになりましたが、今度は、LCDがまともに動作しません。 このメーカーのホームページにサンプルコードがありますが、このクラスのLCDは8bit RGBドライブオンリーで、マイコンからのパラレルドライブやシリアルドライブの実働例はありません。FAQなどを調べていくと、世界中のユーザーが困っているようです。 私の実験では、マイコンからのパラレル8bitドライブはなんとかなっても、シリアルドライブは全く不可というのが実態のように思えます。多分、自社でもテストした事がないのでしょう。

このような環境で、案の定、16bitドライブにしてもまともにカラーが出ません。悪戦苦闘の末判った事はRGBモード時設定するように説明されたカラーコードフォーマットの指定をマイコンからのパラレル接続でも行わないとダメという事でした。

このLCDは以下の初期設定で16bitパラレルドライブの基本的な動作は可能となります。

IM0をHとして、IM1-IM3はL(GND)にしておき、ハードリセットをかけた後のイニシャル処理です。

void init_LCD() {
 lcd_CMD(0x01);//ソフトリセット
 __delay_ms(120) ;
 lcd_CMD(0x11);//Sleep Out
 __delay_ms(120) ;
 lcd_CMD(0x13);
 lcd_CMD(0x0036);//Memoryアクセス(画面のスイープ方向設定)
 lcd_DATA(0x0048);//画面は縦置きOnly
 lcd_CMD(0x3a);//カラーモード書式設定
 lcd_DATA(0x55);//16bit(5-6-5)        この設定が必要でした。
 lcd_CMD(0x002A);//カラムアドレスセット
 lcd_DATA(0x0000);//SC[15-8] 0から
 lcd_DATA(0x0000);//SC[7-0]
 lcd_DATA(0x0000);//EC[15-8] 319まで
 lcd_DATA(0x00EF);//EC[7-0]
 lcd_CMD(0x002B);//ローアドレスセット
 lcd_DATA(0x0000);//SP[15-8] 0から
 lcd_DATA(0x0000);//SP[7-0]
 lcd_DATA(0x0001);//EP[15-8] 239まで
 lcd_DATA(0x003F);//EP[7-0]
  lcd_CMD(0x0029);//Display ON 検討中はこのタイミングで。
 lcd_CMD(0x002C);
 __delay_ms(200) ;
 
}

今回の配線図を下記からダウンロードできます。

マイコンとLCDは専用ラインでつながっていますので、CE端子は常時Lで良く、またLCDの内部情報の読み出しも行いませんので、RD端子も常時Hとしております。

LCDMeter0.pdfをダウンロード

Lcd320meter1

開発開始してから約1週間経過した時点で左のようなアナログメーターの表示に成功しました。

前回のドット数は160x128でしたが、今回は320x240でそれなりに分解能も向上しておりますが、単純に約4倍の面積に拡大しただけでは、このような綺麗なグラフィックにはなりません。 

まず、JW CADを使い、正確な目盛板を作成します。 JW CADのフォントは限られていますので、グラフィックの部分のみを作画して、これをスクリーンショットでGIF画像に変換します。 この時のサイズは面積比で16倍以上あります。 この画像をWindows標準のペイントで読み込み、文字を入れます。フォントも色も豊富にありますので、デザインは簡単です。

デザインが終わったら、実際のLCDに表示するピクセルサイズまでペイントで縮小します。 この状態での各ピクセルのカラーデータをそのまま取り込むという手法で実現できます。

PCでの画像処理は、その豊富なアプリのおかげで、簡単に実現できますので、これをマイコンが扱えるデータに変換する為に、変換プログラムを作る必要が生じます。 PICのマイコンとLCDをにらみながら、ちまちまソフト開発をやるはずでしたが、 このSWRメーターの目盛が表示できたのを境に、マイコンプログラムの開発ではなく、PCのアプリ開発がメインになってしまいました。

そして、さらに、1週間くらい過ぎた時点で、PCアプリが完成しました。

下の画像は、PCの画面上に表示された、LCD表示用カラーコードジェネレーターです。  LCDと同じピクセルサイズに縮小したグラフィックデータを読み込むと、C言語で扱えるLCDへ表示する為のデータファイルを出力します。 出力されたファイルを#include命令で読み込み使う事ができるようになります。  バグだらけのアプリでしたが、なんとか動作するようになりました。

Ccg0

 このアプリはTcl/TKと呼ばれるインタープリンターで作られておりますので、動作は遅いですが、コードジェネレーターですから、たとえ1分かかろうが問題ありません。  実際のところは数秒で出力されます。

バグだらけですが、ソースをダウンロードできます。Ccord_Generator4.tclをダウンロード

defaultcolor.txt を同じディレクトリーに置いてRUNさせて下さい。defaultcolor.txtをダウンロード

グラフィックデータをC言語で出力するのはOKですが、フォントデータを出力させる場合、都度ソースを微調整していましたので、このままでは機能しません。 取説が無いので作った本人も、もう忘れてしまいました。

このアプリはTcl/Tkというインタプリンターをインストールする必要があります。インストールの詳細は「Tcl/Tk」で検索してください。 ダウンロード元は全部英文で、個人情報の登録が必要です。

メーターの振れ角を66度として、0.5度きざみで指針データを作り、これをROM上に配置して指針の動きを表現するもので、PC上でのシュミレーションではうまくいってましたが、いざPIC24Fのマイコンに書き込む作業をしたところ、ROM不足でエラーとなってしまいました。

なぜなら、この指針用データが90Kバイトくらいあり、完全なメモリー不足でした。 本来は、もっと早く気付くべきところですが、アプリが完成して、コードを出力したら、そのファイル容量が170Kバイトくらいを示しましたので、やっと判った次第です。 データのスパンを1度ごとにして、容量を半分にしてみましたが、指針データ以外で24Kくらい使っていますので、やはり足りません。

現在のROM容量64Kに収まる範囲で可能な方式として、指針データは常に計算で出し、指針より少しだけ広い四角い範囲のグラフデータに、指針データを重ねると、ちょうどドット数の多いフォントと同じようなデータが作れますので、これをグラフ画面上に上書きすることにしました。

Lcdswrmeter2

左の画像は、そのようにしてメーター目盛の上に、指針とその周囲の目盛画像を上書きしたものです。最初の案より指針データを計算する分だけ動作が遅くなっています。

この目盛のSWR1.0から無限大までの指針移動時間は実測で、約3.3秒ありました。指針位置の計算はsin()と平方根で出していました。

Y座標は、半径やXの値を2乗してから、平方根ですから、かなり時間がかかりそうです。 そこで、平方根を止め、Xはsin()で、Yはcos()で計算させると、指針の速さは約2.7秒まで改善しました。

三角関数は時間がかかると思われますので、sin()の0度から90度までを予め、PCで計算し、その結果を10000倍した数値を整数として、配列に記憶させ、sin(deg)はそのまま取り出し、cos(deg)はsin(90-deg)で取り出す事にしました。   結果は約1.3秒まで改善しました。

関数のなかを見渡して、繰り返しループの中で、初期設定など、結果が変化しない処理事項を取り出し、ループの外に置くとか、見やすくするために置いた変数を固定値に変えるとかの作業を行った結果SWR1.0から無限大までの指針移動時間は約1秒まで改善出来ました。

Lcdswrmeter3

次に、一部、浮動小数点(double)を使用していた計算式を10000倍の整数計算した後、四捨五入した整数に直す方法で、全ての計算を整数で行った結果、ゼロからフルスケールまでの時間は約0.65秒となりました。

左の画像はその速さで指針が動いている時のショットです。動きが速いので、指針もボケて写っていますが、見た目のチラツキは少ないです。

アナログメーターの指針移動時間で違和感が無いのはゼロからフルスケールまで0.3秒くらいの移動時間ですから、あと半分くらいは短縮必要です。

しかし、 現在はメータードライブだけしかやっていませんので、例えば、SWRメーター以外にインピーダンスメーターも同時に表示したり、周波数カウンターの周波数表示など、負担が増えるばかりで、指針の移動スピードもどんどん遅くなってしまいます。

また、この方式の場合、チラツキは最少に抑えられますが、指針の移動スパンは1度以内に限られます。VUメーターではないので、かなり遅い追従時間でも問題は無いと思われますが、実際に作ってみないと、何とも言えません。

次回は、LCDの全画面表示にトライします。

TFT LCDによるアナログメーター 3 に続く。

INDEXに戻る

2015年5月 4日 (月)

TFT LCDによるアナログメーター1

<カテゴリー:PICマイコン

AadigitaltestPICのマイコンを使用して、アンテナチューナーのコントローラーやATUの製作を行ってきましたが、この過程で、SWR計も作ってきました。 PICマイコンに少し、慣れたころ、このマイコンのAD入力にCAA-500のインピーダンス検出DC信号や、SWR検出DC信号を加え、アンテナアナライザーによるインピーダンスやSWRのデジタル表示にトライし、RやXの表示も行えるところまで実験ができましたので、次の目標は、オール自作のアンテナアナライザーと決めました。 左の画像は、CAA500のセンサー基板に、PIC16F1939を使用した自作のマイコンボードとLCDディスプレーを接続し、マイコンで周波数や、SWR、インピーダンス、R、Xを表示させている実験風景です。

アンテナアナライザーのセンサー部分や、広帯域発振回路など、なんとかなりそうですが、これをメカニカルアナログメーターや、キャラクタ表示の液晶で実現してもMFJやコメットと同じなので、面白く有りません。  そこで、マイコンでは、無理と言われる、液晶表示の疑似アナログメーターの実験を始める事にしました。 最近の車のインパネは高精細度の液晶によるスピードメーターやタコメーターがすばらしいデザインの元で実装されております。またKENWOODの最新モデルにも、液晶表示のアナログメーターが実装され、デジタル駆動にもかかわらず、非常にわかりやすいアナログメーターとなっています。 これらの最新技術のLCDアナログメーターに及ばないにしても、安いマイコンと、安い液晶でどこまで、液晶表示のアナログメーターが実現できるかの実験記です。

使うマイコンは、少し役不足ですが、ATUに使ったPIC16F1939。 これで160x128ドットのTFT液晶をドライブします。 液晶は262K色対応で、普通の写真を表示させても、遜色のないカラー画像が表示できるという中国製です。

とりあえずは、TFT LCDを初期設定し、画像や、文字を表示できるところまでトライします。

この実験ボードの配線図です。TFT-LCD.pdfをダウンロード

実験に使うマイコンはROMもRAMもグラフィックLCDをドライブするには小さすぎますので、今回は、基本動作を得とくする事が目的となり、実践版は次の試作までお預けとします。

試用するLCDはDisplaytechのDT018ATFTという品番で、液晶ドライブIC ILI9163Cが内臓されています。 このILI9163Cという台湾製のICはインターネット上でも良くみかけるST7735とコンパチで、ST7735用のイニシャルルーチンでちゃんと初期設定されてしまいます。初期設定が成功したら、後は、ILI9163Cのデータシートを読みながら、ああでもない、こうでも無いと試行錯誤する事になりますが、いつのまにか、文字表示や自作したイメージデータの表示が出来るようになりました。

Pic_lcd_demo

左の画像は、なんとか表示できるようになったので、SWR計の目盛をLCD上に表示させたものです。SWR検出信号をADにつなげば、赤色の指針がSWRを指します。

メーターの目盛は3角関数とピタゴラスの定理を駆使して、描かれており、ブリッジの不平衡電圧を角度に変えて、目盛と同じ式で指針を表示していますので、指示誤差は有りません。

150x50ピクセルくらいの範囲で描画していますので、あまりきれいではありませんが、実験機としては十分です。

ただし、大きな問題があります。

動作がおそろしく遅いのです。

指針が移動するのに、0.5秒くらいかかります。1度移動しようが、60度移動しようが0.5秒です。 これでは、全く使いものにはなりません。  これは、指針も3角関数と、ピタゴラスの定理でXYドットをいちいち計算して表示していたのが最大の原因です。  

これを、指針のドットのみ1度ごとのXYデータの配列として記憶させて置き、測定された指針角度から、このイメージデータを呼び出し、表示させる事にしました。 角度データは80度分必要ですが、とりあえず10度分だけ作って振らせてみました。 指針は赤色で描画した後、一度白色で再描画し、指針を一度消し、次に新しい位置に、赤で描画するという事を繰り返します。 このドット単位での書き換え動作は、目盛と指針が重なった場所の目盛表示を復帰させるのも、ドット単位で行えますので、復帰させるドット情報も簡単に計算できます。 しかし結果は、かなり早くなりましたが、指針のチラツキが目立つようになりました。 まだまだ、改善が必要です。

次に、文字フォントと同じように8x16の書き換え可能なドットパターンを用意し、この範囲に含まれる目盛のドットに加えて、指針のドットも書き込み、これを指針角度に応じて、画面上に再描画させる動作を実験しました。この場合、指針の移動に伴い、旧指針を消すという動作と消えた目盛の復帰動作が不要になりますので、面を書き換える時間増より、コマンド切り替えの回数減少から、LCD側の動作速度がかなり早くなります。 また、ちらつきもほとんど無くなる事も判りました。 ただし、LCDにカラードットを書き込む前のドットパターン作成作業は複雑になりますので、マイコンのクロックを上げたり、16bit RISCタイプに変えるなど、対応が必要になると思われます。

次は、マイコンを16bit品に変え、かつLCDも320x240ドット品に変えて、動作速度の改善に取り組みます。

同じようなLCDをお使いになりたい時の為に、このLCD用の初期設定ルーチンだけですが、以下に示します。

void lcd_CMD(unsigned char CM) {//1-byteコマンド
      RS = 0;
      WR = 0;
      LATD =CM;
      WR = 1;
      RS = 1;
     }
void lcd_DATA(unsigned char DA) {
      WR = 0;
      LATD = DA;
      WR = 1;
     }

void init_LCD() {
      lcd_CMD(0x01);//ソフトリセット
       __delay_ms(120) ;
      lcd_CMD(0x11);//Sleep Out
      __delay_ms(120) ;
      lcd_CMD(0x36);
      lcd_DATA(0xC8);
      lcd_CMD(0x2A);
      lcd_DATA(0x00);
      lcd_DATA(0x00);
      lcd_DATA(0x00);
      lcd_DATA(0x9F);
      lcd_CMD(0x2B);
      lcd_DATA(0x00);
      lcd_DATA(0x00);
      lcd_DATA(0x00);
      lcd_DATA(0x7F);
      lcd_CMD(0x36);
      lcd_DATA(0xAC);
// lcd_CMD(0x29);//Display ON このコマンドは画面クリアーの後が良い。
      lcd_CMD(0x2C);
      __delay_ms(200) ;
 }

TFT LCDによるアナログメーター 2 に続く。

INDEXに戻る