スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

TeraTermの簡易グラフィック出力

今日はTeraTermのグラフィック出力をテストする.
シリアル通信経由でのデバッグやデータダンプ用にWindows-XP以降はHyperTerminalが無くなったので,フリーソフトのTeraTermを使っているユーザは多いと思う.
16bit,32bitマイコンではデータ量が大きくなるため,数値データ列をいちいちエクセルにコピペしてグラフ化するのが面倒だった(具体的には長~いデータをマウスでドラッグするのが面倒!).
もっとマイコンからダイレクトにグラフ描画やXYプロットなんかができないものか・・・

そんな矢先,ふとO-Familyさんの Tektronix 4010(4014) グラフィック・ターミナルへ描画の記事を見つけ,さっそく試してみることに.




こんな感じで別ウィンドウが開きグラフィック表示できる.(TeraTermのバージョンは4.84.)

使い方はTeraTermのSetUP→Terminalと進み,設定ダイアログの中ほどに[Auto Switch VT<->TEK]にチェック.
カラー表示したい時はTEKウィンドウメニューのSetup→Windowと進み[color emuration]にチェック.
扱えるのは基本的に点と直線のみ.色は16色と超シンプル.
いわゆるASCIIコードのエスケープシーケンスでベルを鳴らしたりするのと同じ感覚で使えるため,マイコンで簡単に描画できる.

O-FamilyさんのライブラリはAVR用のアセンブラだったので,これをC言語でSH4A用に書き換えた.
上記スクリーンを出力した際のコードを参考に載せておく.
※spi_put()の関数は自分がSPI-USB変換を使っているためSPI出力関数です.
SCI,UARTなどお使いのシリアル出力関数に適宜置き換えてください.
TEK4010コマンドの詳細は こちらのフォーラム を参考にしました.
/*
TeraTermのTek4010描画エミュレータを使いグラフィック表示を行う
TeraTermのVer4.84以上推奨
sci.c もしくは hspi.cを先にインクルードしておくこと

*/
int Get_RGB(int r,int g,int b)
{
int colour;
r=(r<<16)&0xFF0000;
g=(g<< 8)&0x00FF00;
b=(b<< 0)&0x0000FF;
colour=(r+g+b)&0xFFFFFF;
return colour;
}
//*************RGB888→bgr111***********************
int rgb888tobgr111(int colour) {
int r = (colour >> 23) & 1;
int g = (colour >> 15) & 1;
int b = (colour >> 7) & 1;
return (b << 2) | (g << 1) | (r << 0);
}
//**********表示色を変えるエスケープシーケンス*******************
//TEKウィンドウの[SetUP]→[Window]ダイアログの中の[color Emuration]にチェックを付けておく
void Change_ForeGround_Color(int color)
{
int c;
c=30+rgb888tobgr111(color);
spi_printf("\033[%dm", c);
}
//*********文字背景色を変えるエスケープシーケンス***************************
//
void Change_BackGround_Color(int color)
{
int c;
c=40+rgb888tobgr111(color);
spi_printf("\033[%dm", c);
}

//**********TEK4010モードへ入る*********
void Enter_Tek4010(void)
{
spi_putc(0x1B);
spi_putc('[');
spi_putc('?');
spi_putc('3');
spi_putc('8');
spi_putc('h');
}
//**********TEK4010モードから出る*********
void Exit_Tek4010(void)
{
spi_putc(0x1B);
spi_putc('[');
spi_putc('?');
spi_putc('3');
spi_putc('8');
spi_putc('l');
}

//************画面クリア**************************
void Tek_Clr(void)
{
spi_putc(0x1B); //ESC アルファモードへ戻す
spi_putc(0x0C); //FF
spi_putc(0x0D); //CR
spi_putc(0x0A); //LF
}
//*************文字描画モード(アルファモード)に戻す*************

void Tek_Alpha(void)
{
spi_putc(0x1F); //US アルファモードへ戻す
}
//**********グラフィックモードへ切り替え**********
void Tek_Graph(int vector_no)
{
spi_putc(0x1D); //GS
spi_putc(0x1B); //ESC
spi_putc(vector_no|0x60); //線種を選ぶ
}

/*
直線を引く[xs,ys]→[xg,yg]
座標は左下が[0,0] 幅1023 高さ778まで.
データは10bit+TagBitの構成で全部で8byte送信.

線種の番号
0:標準実線
1:点線
2:一点鎖線
3:短い鎖線
4:長い鎖線
8:Bold実線

*/
void Tek_Line(int xs,int ys,int xg,int yg,int line_no)
{
unsigned char x0,y0,x1,y1;
Tek_Graph(line_no); //グラフィックモードに移行(線種を指定)

x0=(unsigned char)(xs&0x1F); //下位5byteを取り出す
x0=x0|0x40; //Tag-Bitをセット
y0=(unsigned char)(ys&0x1F); //下位5byteを取り出す
y0=y0|0x60; //Tag-Bitをセット

x1=(unsigned char)((xs>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
x1=x1|0x20; //Tag-Bitをセット
y1=(unsigned char)((ys>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
y1=y1|0x20; //Tag-Bitをセット

spi_putc(y1); //座標送信
spi_putc(y0); //座標送信
spi_putc(x1); //座標送信
spi_putc(x0); //座標送信


x0=(unsigned char)(xg&0x1F); //下位5byteを取り出す
x0=x0|0x40; //Tag-Bitをセット
y0=(unsigned char)(yg&0x1F); //下位5byteを取り出す
y0=y0|0x60; //Tag-Bitをセット

x1=(unsigned char)((xg>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
x1=x1|0x20; //Tag-Bitをセット
y1=(unsigned char)((yg>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
y1=y1|0x20; //Tag-Bitをセット

spi_putc(y1); //座標送信
spi_putc(y0); //座標送信
spi_putc(x1); //座標送信
spi_putc(x0); //座標送信

Tek_Alpha(); //キャラクタモードに戻す
}

/*
Dotを打つ
始点・終点を同じ座標にしたLine引き
*/
void Tek_Dot(int xs,int ys)
{
unsigned char x0,y0,x1,y1;

spi_putc(0x1D); //GS

x0=(unsigned char)(xs&0x1F); //下位5byteを取り出す
x0=x0|0x40; //Tag-Bitをセット
y0=(unsigned char)(ys&0x1F); //下位5byteを取り出す
y0=y0|0x60; //Tag-Bitをセット

x1=(unsigned char)((xs>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
x1=x1|0x20; //Tag-Bitをセット
y1=(unsigned char)((ys>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
y1=y1|0x20; //Tag-Bitをセット

spi_putc(y1); //座標送信
spi_putc(y0); //座標送信
spi_putc(x1); //座標送信
spi_putc(x0); //座標送信

spi_putc(y1); //座標送信
spi_putc(y0); //座標送信
spi_putc(x1); //座標送信
spi_putc(x0); //座標送信
Tek_Alpha(); //キャラクタモードに戻す
}

/*
文字の位置を指定する
この関数のの後,文字を出すと文字の原点(左下)がこの位置に合わせられる
*/
void Tek_Char_PosSet(int xs,int ys)
{
unsigned char x0,y0,x1,y1;

spi_putc(0x1D); //GS
x0=(unsigned char)(xs&0x1F); //下位5byteを取り出す
x0=x0|0x40; //Tag-Bitをセット
y0=(unsigned char)(ys&0x1F); //下位5byteを取り出す
y0=y0|0x60; //Tag-Bitをセット

x1=(unsigned char)((xs>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
x1=x1|0x20; //Tag-Bitをセット
y1=(unsigned char)((ys>>5)&0x1F); //上位byteを5個右シフトしたあと下位5byteを取り出す
y1=y1|0x20; //Tag-Bitをセット

spi_putc(y1); //座標送信
spi_putc(y0); //座標送信
spi_putc(x1); //座標送信
spi_putc(x0); //座標送信
Tek_Alpha(); //キャラクタモードに戻す
}

//************十字カーソルマークを任意座標中心に表示************
void Tek_Cross_Cursor(int xs,int ys)
{
int length=10; //カーソルの長さ
Tek_Line(xs-length/2,ys,xs+length/2,ys,0); //ラインを引く
Tek_Line(xs,ys-length/2,xs,ys+length/2,0); //ラインを引く
}

//************四角形の描画(左下座標,右上座標の2点で囲まれる四角)************
void Tek_Box(int xs,int ys,int xg,int yg,int line_no)
{
Tek_Line(xs,ys,xg,ys,line_no); //ラインを引く
Tek_Line(xg,ys,xg,yg,line_no); //ラインを引く
Tek_Line(xg,yg,xs,yg,line_no); //ラインを引く
Tek_Line(xs,yg,xs,ys,line_no); //ラインを引く
}


void Test_Tek_Graphic(void)
{
int size_x,size_y;
int x,y;
float c;
int i,total,no;
int color1,color2,color3;

size_x=1023; //Tek-Windowの横サイズ
size_y=778; //vTek-Windowの縦サイズ

color1=Get_RGB(255,0,0); //赤
color2=Get_RGB(0,255,0); //緑
color3=Get_RGB(0,0,255); //青

Enter_Tek4010(); //Tekウィンドウを起動(無くてもOK?)

Tek_Clr(); //画面クリア
// Change_BackGround_Color(Get_RGB(255,255,255)); //背景色を白にセット

Tek_Line(0,10,400,10,0); //ラインを引く(始点[x,y],終点[x,y],ラインの種類)
Tek_Char_PosSet(420,5); //文字の位置(左下原点)を指定
spi_puts("Line0\n\r"); //文字を出力

Tek_Line(0,30,400,30,1); //ラインを引く(始点[x,y],終点[x,y],ラインの種類)
Tek_Char_PosSet(420,25); //文字の位置(左下原点)を指定
spi_puts("Line1\n\r"); //文字を出力

Tek_Line(0,50,400,50,2); //ラインを引く(始点[x,y],終点[x,y],ラインの種類)
Tek_Char_PosSet(420,45); //文字の位置(左下原点)を指定
spi_puts("Line2\n\r"); //文字を出力

Tek_Line(0,70,400,70,3); //ラインを引く(始点[x,y],終点[x,y],ラインの種類)
Tek_Char_PosSet(420,65); //文字の位置(左下原点)を指定
spi_puts("Line3\n\r"); //文字を出力

Tek_Line(0,90,400,90,4); //ラインを引く(始点[x,y],終点[x,y],ラインの種類)
Tek_Char_PosSet(420,85); //文字の位置(左下原点)を指定
spi_puts("Line4\n\r"); //文字を出力


Tek_Box(0,0,size_x,size_y,2); //四角形(左下[x,y],右上[x,y],線種)


Tek_Line(0,400,size_x,400,1); //ラインを引く

total=size_x;
for(i=0;i<=total;i++){
c=(float)i/(float)total; //
x=i; //DotのX座標
y=400+(int)(100.0*sinf(c*PI*10.0)); //DotのY座標
Change_ForeGround_Color(color1); //Dotの色を変える
Tek_Dot(x,y); //Dotを打つ

y=400+(int)(100.0*sinf(c*PI*20.0)); //DotのY座標
Change_ForeGround_Color(color2); //Dotの色を変える
Tek_Dot(x,y); //Dotを打つ

y=400+(int)(100.0*sinf(c*PI*30.0)); //DotのY座標
Change_ForeGround_Color(color3); //Dotの色を変える
Tek_Dot(x,y); //Dotを打つ

wait_msec(1); //描画が途切れる場合,適宜ウェイトを入れると改善
}

Change_ForeGround_Color(Get_RGB(255,0,255));
// Change_BackGround_Color(Get_RGB(255,0,255));
x=30;
y=600;
Tek_Cross_Cursor(x,y);
Tek_Char_PosSet(x,y);
spi_puts("Color TEST\n\r"); //メッセージを表示

spi_puts("\033[39m"); //前景をデフォルト色に戻す
spi_puts("\033[49m"); //背景をデフォルト色に戻す
x=30;
y=size_y-40;
Tek_Cross_Cursor(x,y);
Tek_Char_PosSet(x,y);
spi_puts("Tek4010 Graphic Test For Tera-Term!\n\r"); //メッセージを表示

Exit_Tek4010(); //Tekウィンドウを終了する(通常のTeraTermウィンドウに戻す)

spi_puts("This message is displayed in main window of TeraTerm!!\n\r"); //このメッセージはTEKウィンドウではなく,通常のTeraTermウィンドウに表示

}

スポンサーサイト
プロフィール

もやね

Author:もやね
長野県在住の会社員(メカニカル・エンジニア).
ロボットは完全な趣味としてやってます.
E-mail:
mo_ya_ne[a]yahoo.co.jp
[a]⇒@

最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
FC2カウンター
ブログ内検索
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。