今回はこのTRANSCEIVERの中枢であるコントローラーについて簡単に解説します。
Microprocessor
今回のコントローラーは、以前BlogにUPしたVFO Ver8.0を基にカスタマイズしています。
MPUは、Arduino Due を使用しました。今回のプロジェクトでは、ALL BANDで多機能であるため、I/Oが多く、十分なメモリ容量でスピードが速いものを必要としました。
主な仕様は以下の通り
Specification
Microcontroller AT91SAM3X8E
Operating Voltage : 3.3V
Input Voltage (recommended) : 7-12V
Input Voltage (limits) : 6-20V
Digital I/O Pins : 54 (of which 12 provide PWM output)
Analog Input Pins : 12
Analog Outputs Pins : 2 (DAC)
Total DC Output Current on all I/O lines : 130 mA
DC Current for 3.3V Pin : 800 mA
DC Current for 5V Pin : 800 mA
Flash Memory : 512 KB all available for the user applications
SRAM : 96 KB (two banks: 64KB and 32KB)
Clock Speed : 84 MHz
TFT Color LCD with Touch panel
今回のコントローラーで一番苦労したところが、タッチパネルのコントロールであった。
LCDは、ドライバーがILI9341でSPIインターフェース。これにタッチパネルが付いたものである。
Specification
Display Color RGB 65k color
Screen size 3.2inch
Driver ILI9341
Resolution 320x240 pixel
Interface 4 wire SPI
Touch panel Resistive touchscreen
Touch Driver TSC2046
Arduino Due周りの結線図を再度掲載する。DueとLCDの接続を赤くしてある。
特に苦労した部分について簡単に記載します。
USB Port Dueは2つのUSBポートがある。一つはPrograming Portで主にプログラムの書き込み、消去等にしよう。もう一つはNative Portで主にユーザープログラムで使う。
今回は筐体背面に両方のポートを付けた。Programing用とCAT通信用としている。
CATはメーカーによってコマンドが違うためどれかに決める必要がある。今回はHamLogの周波数設定程度なので、Yaesu FT-991,Kenwood TS-2000に対応できるようにした。(コンパイル時に選択)
スケッチは、mainルーチンで外部からUSB経由でシリアル信号を受信したかチェックし、文字列を判読し、情報を返信する単純なスケッチである。以下は参考スケッチです。
---------------------------------------------------------
byte CATbyte = 0;
void setup(){
SerialUSB(38400);}
void main(){
CATbyte = SerialUSB.available();
if (CATbyte >0){CATset();}
}
//----- CAT Controll(FT-991) -------------------------
void CATset(){
String CATinput = SerialUSB.readStringUntil(';');
SerialUSB.flush();
if (CATinput == "FA"){
SerialUSB.print("FA");
String freqtcat = freqt;
int mojicat=(freqtcat.length());
if (mojicat <9){
for (int i=9; i > mojicat; --i){
SerialUSB.print("0");
}
}
SerialUSB.print(freqtcat);
SerialUSB.print(";");
}
if(CATinput == "MD0"){
String modecat = String(mode);
SerialUSB.print("MD0");
SerialUSB.print(modecat);
SerialUSB.print(";");
}
else{
SerialUSB.print("?;");
}
}
----------------------------------------------------------
Touch panel
タッチパネルの処理には非常に苦労をした。製作までにかなりの時間を要したが、逐一記載すると非常に大変なので、結果だけを書くことにする。
タッチパネルには今回抵抗膜方式のもので、タッチしたときの抵抗変化で位置を特定する方式である。タッチパネルのドライバーはTSC2046、LCDはILI9341、MPUはArduino Due。
初めにタッチパネルのキャリブレーションが必要である。押した位置の抵抗値をLCDのPixelに変換する。これにより位置判断が可能となる。
キャリブレーションのスケッチは以下のライブラリーのサンプルスケッチにある。
https://github.com/marekburiak/ILI9341_due
[ uTouchCalibration.ino]が目的のスケッチである。
55行を今回のハードウェアに変更する。
URTouch myTouch(30, 28, 26, 24, 22);
↓
URTouch myTouch(6,5,4,3,2);
73行を使用するLCDの方向に合わせる。(90 or 270)
tft.setRotation(iliRotation270); // landscape
これをDueに書き込むと右の画面が表示される。画面のどこかをタッチすると次の画面が表示される。
この画面で左上ハイライトされた+をタッチする。中央の[PRESS]が[HOLD]に代わり[RELEASE]に変わる。すると今度は左中央がハイライトする。同じようにタッチして8か所すべてが終了すると最終の情報画面に変わる。
CAL_X
CAL_Y
CAL_Z
これがキャリブレーションで得られた情報である。

この情報はIDEのシリアルモニタにも出力される。
ここで、今回使うタッチパネル用ライブラリー
http://www.rinkydinkelectronics.com/library.php?id=93にあるURTouchを使用する。
このライブラリー内にある[URTouchCD.h]をエディターで開きオリジナルのXYZをコメントアウトし、シリアルモニタのXYZをコピー&ペーストし保存する。
これで使用するLCDのキャリブレーションが終了する。LCDを変更した場合はそのたびにキャリブレーションが必要となる。
参考スケッチ
実際のスケッチの抜きだしなのでよくわからないかもしれない。mainルーチンでパネルが押されたかどうか検出しx,y情報をサブルーチンに渡し処理を行う。URTouchライブラリーのexampleスケッチなど参考にしてください。
-------------------------------------------------------------
void main(){
if (myTouch.dataAvailable())
{
myTouch.read();
int x = myTouch.getX();
int y = myTouch.getY();
ProcessKeyTouch(x, y);
}
//----- Touch -----------------------------------------------
void ProcessKeyTouch(int x, int y)
{
// SerialUSB.end();
ucg.setFont(ucg_font_fub11_tr);
if (x >= 5 && x <= 5+key_width){ // Menu
if (y >= 210 && y <= 210+key_height){
key_rows = 2;
menu_sub();
}
}
if (x >= 5+1*80 && x <= 5+1*80+key_width){ // Band Set
if (y >= 210 && y <= 210+key_height){
key_rows = 3;
band_set();
}
}
if (x >= 5+2*80 && x <= 5+2*80+key_width){ // Step UP
if (y >= 210 && y <= 210+key_height){
fstepmem=fstepmem+1;
fstepset();
}
}
if (x >= 5+3*80 && x <= 5+3*80+key_width){ // Step Down
if (y >= 210 && y <= 210+key_height){
fstepmem = fstepmem-1;
fstepset();
}
}
if (x >= 5 && x <= 67){ // VFO
if (y >= 10 && y <= 30){
key_rows = 1;
vfo_menu();
}
}
if (x >= 77 && x <= 122){ // Mode
if (y >= 10 && y <= 30){
key_rows =2;
mode_menu();
}
}
while(x != -1 ){
myTouch.read();
x = myTouch.getX();
//y = myTouch.getY();
}
}
一部省略して書いたので少々わかりにくいかもしれませんが、ご容赦
以上 これでALL MODE TRANSCEIVERの解説は終了の予定。質問や、聞きたいことなどご要望があれば追記するかもしれません。メールまたはコメントにてお知らせください。
DE JA2NKD Ryuu