秋月VFDで文字表示を行うプログラムを作成します。

フォーム、ラジオボタン、ボタンをダブルクリックし、イベントを登録します

2 F5ボタンを押し、プログラムを実行します。
3 GP1022かGP1058、自分が使用しているVFDの型番を選択します。
4 VFDが接続されているCOMポートを選び、接続ボタンを押します。

5 テキストボックスに文字を入れて送信ボタンを押し、VFDに文字が表示されることを確認します。

6 切断ボタンを押して、終了します。
シリアルポートを開きます。
this.serialPort.BaudRate = 19200;//通信速度 19200bps
this.serialPort.PortName = (string)this.comboBox1.SelectedItem;//ポート番号はコンボボックスから選択
this.serialPort.Open();//ポートオープン
通信速度は19200bpsで固定です。コンボボックスで選んだシリアルポートを開きます。
文字表示
秋月VFDには漢字ROMが搭載されており、日本語の表示が行えます。
漢字ROMコードはjisコードをベースにしたオリジナルのコードであるため、シフトJISコードからjisコードに変換した後、さらに漢字ROMオリジナルコードへ変換する必要があります。
//シフトjis->jis
byte[] byteMessage = Encoding.GetEncoding(50220).GetBytes(message);
//jis->vfd漢字ロムコード
byte[] vfdCode = toVFDCode(byteMessage);
jisから漢字ロムコードへの変換はこのメソッドで行っています。
private byte[] toVFDCode(byte[] jisCode)
jisと漢字ROMコードの対応表はマニュアルの図のとおりです

秋月VFDへデータを送信するには、コマンドフレームとデータフレームの2種類を送信する必要があります。ここでは0x04「送信したデータを即時表示する」というコマンドを送信しています。
実際に送信されるコマンドフレームの内容は

の7バイトです。
//アドレス
send[0] = 0x00;
//フレーム番号
send[1] = frame;
//コマンド
send[2] = 0x00;
アドレスはDont' careとのことなので、何を入れても動作に違いはありません。
フレーム番号はコマンドフレームの場合、常に0x00を送信します。
コマンドにはこれらの種類があります。


フレーム数にはこれから送信するデータフレームの総数を送信します。
データフレーム内のメッセージ部に入れられるデータは256バイトなので、漢字ROMコードへ変換されたバイト配列の総数からフレーム数を割り出します。
int nFrame = vfdCode.Length / 256 + 1;
this.send_commandFrame(0x04, (byte)nFrame);
SUMにはアドレスからフレーム数までのデータを合計した値を入れます。
int nSum = send[0] + send[1] + send[2] + send[3];
byteSum = BitConverter.GetBytes(nSum);
send[4] = byteSum[1];
send[5] = byteSum[0];
ENDは0xFEで固定です
send[6] = 0xEF;
データフレームの構成はこのようになっています

メッセージに、漢字ROMコードへ変換されたバイト配列を256バイトづつ入れて送信していきます。
フレーム番号はそのたびにカウントしていきます。
//FFHで埋める
for (int i = 0; i < 256; i++)
{
sendMessage[i] = 0xff;
}
int frameCount = 0;
int byteCount = 0;
for (int i = 0; i < vfdCode.Length; i++)
{
sendMessage[byteCount] = vfdCode[i];
byteCount++;
if (byteCount == 256 || i == vfdCode.Length - 1)
{
frameCount++;
byteCount = 0;
this.send_dataFrame(sendMessage, (byte)frameCount);
//FFHで埋める
for (int j = 0; j < 256; j++)
{
sendMessage[j] = 0xff;
}
}
}
データフレームのメッセージ内には、このようなコマンドを入れることが出来ます。

しかし、今回は文字をそのまま表示するだけなので、使用しません。
http://www.harukaze.ne.jp/tomekugi/win/index.html
1.プロジェクトの作成
Visual C#で「VFDTest」というWindowsフォームアプリケーションの新規プロジェクトを作成します。2.フォームの作成
フォーム上に、以下のようにコントロールを配置します
フォーム、ラジオボタン、ボタンをダブルクリックし、イベントを登録します

3.文字表示プログラム
form1.csに以下のプログラムを貼り付けますusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; using System.Collections; namespace VFDTest { public partial class Form1 : Form { private SerialPort serialPort = new SerialPort(); private Boolean is58 = false; public Form1() { InitializeComponent(); this.serialPort = new SerialPort(); } //フォームロード private void Form1_Load(object sender, EventArgs e) { this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; string[] ports = SerialPort.GetPortNames(); foreach (string port in ports) { this.comboBox1.Items.Add(port); } this.comboBox1.SelectedIndex = 0; //ラジオボタン this.radioButton1.Checked = true; this.is58 = false; this.button2.Enabled = false; this.button3.Enabled = false; } //接続 private void button1_Click(object sender, EventArgs e) { try { this.serialPort.BaudRate = 19200;//通信速度 19200bps this.serialPort.PortName = (string)this.comboBox1.SelectedItem;//ポート番号はコンボボックスから選択 this.serialPort.Open();//ポートオープン //GP1058の場合 if (this.is58 == true) { //画素数336x24 this.send_commandFrame(0x25, 0x00); } } catch (Exception ex) { //ポートオープンに失敗 MessageBox.Show(ex.ToString()); return; } //ボタン各種有効、無効 this.radioButton1.Enabled = false; this.radioButton2.Enabled = false; this.comboBox1.Enabled = false; this.button1.Enabled = false; this.button2.Enabled = true; this.button3.Enabled = true; } //切断 private void button2_Click(object sender, EventArgs e) { //ポートクローズ this.serialPort.Close(); //ボタン各種有効、無効 this.radioButton1.Enabled = true; this.radioButton2.Enabled = true; this.comboBox1.Enabled = true; this.button1.Enabled = true; this.button2.Enabled = false; } //コマンドフレーム送信 private void send_commandFrame(byte command, byte frame) { byte[] send = new byte[7]; byte[] byteSum = new byte[2]; send[2] = command; send[3] = frame; int nSum = send[0] + send[1] + send[2] + send[3]; byteSum = BitConverter.GetBytes(nSum); send[4] = byteSum[1]; send[5] = byteSum[0]; send[6] = 0xEF; if (this.serialPort.IsOpen == true) { try { this.serialPort.Write(send, 0, send.Length); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } //テキスト送信 private void send_Message(String message) { byte[] sendMessage = new byte[256]; //シフトjis->jis byte[] byteMessage = Encoding.GetEncoding(50220).GetBytes(message); //jis->vfd漢字ロムコード byte[] vfdCode = toVFDCode(byteMessage); int nFrame = vfdCode.Length / 256 + 1; if (vfdCode.Length > 4096) { MessageBox.Show("エラー:文字数オーバー"); return; } this.send_commandFrame(0x04, (byte)nFrame); //FFHで埋める for (int i = 0; i < 256; i++) { sendMessage[i] = 0xff; } int frameCount = 0; int byteCount = 0; for (int i = 0; i < vfdCode.Length; i++) { sendMessage[byteCount] = vfdCode[i]; byteCount++; if (byteCount == 256 || i == vfdCode.Length - 1) { frameCount++; byteCount = 0; this.send_dataFrame(sendMessage, (byte)frameCount); //FFHで埋める for (int j = 0; j < 256; j++) { sendMessage[j] = 0xff; } } } } //データフレーム送信 private void send_dataFrame(byte[] message, byte frame) { byte[] send = new byte[262]; byte[] byteSum = new byte[2]; //アドレス send[0] = 0x00; //フレーム番号 send[1] = frame; //コマンド send[2] = 0x00; //メッセージ for (int i = 3; i < 256 + 3; i++) { send[i] = message[i - 3]; } //サム計算 int nSum = 0; for (int i = 0; i < 256 + 3; i++) { nSum += send[i]; } byteSum = BitConverter.GetBytes(nSum); //SUM send[259] = byteSum[1]; send[260] = byteSum[0]; //END send[261] = 0xEF; if (this.serialPort.IsOpen == true) { this.serialPort.Write(send, 0, send.Length); } } //文字コード変換 jis->VFD独自コード private byte[] toVFDCode(byte[] jisCode) { ArrayList arrayVFDCode = new ArrayList(); byte[] byteVFDCode; Boolean isAscii = true; for (int i = 0; i < jisCode.Length; i++) { //アスキー、jis切り替え if (jisCode.Length - i >= 2) { if (jisCode[i] == 0x1b && jisCode[i + 1] == 0x24 && jisCode[i + 2] == 0x42) { isAscii = false; i += 2; continue; } else if (jisCode[i] == 0x1b && jisCode[i + 1] == 0x28 && jisCode[i + 2] == 0x42) { isAscii = true; i += 2; continue; } } if (isAscii) { //アスキーコード short tmp1, tmp2; tmp1 = jisCode[i]; tmp2 = (short)(tmp1 & 0xE0); tmp2 = (short)(tmp2 >> 5); tmp2--; tmp2 = (short)(tmp2 << 7); tmp1 = (short)(tmp1 & 0x1f); tmp2 = (short)(tmp2 | tmp1); tmp2 = (short)(tmp2 | 0x4000); tmp1 = (short)(tmp2 & 0x00FF); tmp2 = (short)(tmp2 >> 8); arrayVFDCode.Add((byte)tmp1); arrayVFDCode.Add((byte)tmp2); } else { short tmp1 = jisCode[i], tmp2 = jisCode[i + 1], tmp4 = 0; int flag = jisCode[i] >> 4; switch (flag) { case 2: //非漢字 tmp1 = (short)(tmp1 & 0x7F); tmp4 = (short)(tmp1 & 0x7); tmp1 = (short)(tmp2 >> 2); tmp1 = (short)(tmp1 & 0x18); tmp1 = (short)(tmp1 | tmp4); tmp1 = (short)(tmp1 << 7); tmp1 = (short)(tmp1 & 0xF9F); tmp2 = (short)(tmp2 & 0x1F); tmp2 = (short)(tmp2 | tmp1); tmp2 = (short)(tmp2 & 0xFFF); break; case 3: case 4: //3:漢字第一水準1 4:漢字第一水準2 tmp1 = (short)(tmp1 & 0x7F); tmp4 = (short)(tmp1 & 0xF); tmp1 = (short)(tmp1 >> 2); tmp1 = (short)(tmp1 & 0x30); tmp1 = (short)(tmp1 | tmp4); tmp1 = (short)(tmp1 << 7); tmp2 = (short)(tmp2 & 0x7F); tmp2 = (short)(tmp2 | tmp1); tmp2 = (short)(tmp2 & 0xFFF); break; case 5: case 6: //5:漢字第二水準1 6:漢字第二水準2 tmp1 = (short)(tmp1 & 0x7F); tmp4 = (short)(tmp1 & 0xF); tmp1 = (short)(tmp1 >> 1); tmp1 = (short)(tmp1 & 0x10); tmp1 = (short)(tmp1 | tmp4); tmp1 = (short)(tmp1 << 7); tmp2 = (short)(tmp2 & 0x7F); tmp2 = (short)(tmp2 | tmp1); tmp2 = (short)(tmp2 | 0x1000); break; case 7: //漢字第二水準3 tmp1 = (short)(tmp1 & 0x7F); tmp4 = (short)(tmp1 & 0x7); tmp1 = (short)(tmp2 >> 2); tmp1 = (short)(tmp1 & 0x18); tmp1 = (short)(tmp1 | tmp4); tmp1 = (short)(tmp1 << 7); tmp2 = (short)(tmp2 & 0x1F); tmp2 = (short)(tmp2 | tmp1); tmp2 = (short)(tmp2 | 0x1000); break; default: //その他 //スルー continue; } tmp1 = (short)(tmp2 & 0x00ff); tmp2 = (short)(tmp2 >> 8); //リストに追加 arrayVFDCode.Add((byte)tmp1); arrayVFDCode.Add((byte)tmp2); //2バイト分進めるために、先に+1しておく i++; } } byteVFDCode = new byte[arrayVFDCode.Count]; for (int i = 0; i < arrayVFDCode.Count; i++) { byteVFDCode[i] = (byte)arrayVFDCode[i]; } return byteVFDCode; } //テキストメッセージ送信 private void button3_Click(object sender, EventArgs e) { this.send_Message(textBox1.Text); this.textBox1.Text = "";//テキストボックスクリア } //ラジオボタン private void radioButton1_CheckedChanged(object sender, EventArgs e) { this.is58 = false; } //ラジオボタン private void radioButton2_CheckedChanged(object sender, EventArgs e) { this.is58 = true; } } }
実行
1 VFDに電源を入れ、PCに繋ぎます。2 F5ボタンを押し、プログラムを実行します。
3 GP1022かGP1058、自分が使用しているVFDの型番を選択します。
4 VFDが接続されているCOMポートを選び、接続ボタンを押します。

5 テキストボックスに文字を入れて送信ボタンを押し、VFDに文字が表示されることを確認します。

6 切断ボタンを押して、終了します。
解説
VFDにテキストボックスの文字を表示します。シリアルポートを開きます。
this.serialPort.BaudRate = 19200;//通信速度 19200bps
this.serialPort.PortName = (string)this.comboBox1.SelectedItem;//ポート番号はコンボボックスから選択
this.serialPort.Open();//ポートオープン
通信速度は19200bpsで固定です。コンボボックスで選んだシリアルポートを開きます。
文字表示
秋月VFDには漢字ROMが搭載されており、日本語の表示が行えます。
漢字ROMコードはjisコードをベースにしたオリジナルのコードであるため、シフトJISコードからjisコードに変換した後、さらに漢字ROMオリジナルコードへ変換する必要があります。
//シフトjis->jis
byte[] byteMessage = Encoding.GetEncoding(50220).GetBytes(message);
//jis->vfd漢字ロムコード
byte[] vfdCode = toVFDCode(byteMessage);
jisから漢字ロムコードへの変換はこのメソッドで行っています。
private byte[] toVFDCode(byte[] jisCode)
jisと漢字ROMコードの対応表はマニュアルの図のとおりです

秋月VFDへデータを送信するには、コマンドフレームとデータフレームの2種類を送信する必要があります。ここでは0x04「送信したデータを即時表示する」というコマンドを送信しています。
実際に送信されるコマンドフレームの内容は

の7バイトです。
//アドレス
send[0] = 0x00;
//フレーム番号
send[1] = frame;
//コマンド
send[2] = 0x00;
アドレスはDont' careとのことなので、何を入れても動作に違いはありません。
フレーム番号はコマンドフレームの場合、常に0x00を送信します。
コマンドにはこれらの種類があります。


フレーム数にはこれから送信するデータフレームの総数を送信します。
データフレーム内のメッセージ部に入れられるデータは256バイトなので、漢字ROMコードへ変換されたバイト配列の総数からフレーム数を割り出します。
int nFrame = vfdCode.Length / 256 + 1;
this.send_commandFrame(0x04, (byte)nFrame);
SUMにはアドレスからフレーム数までのデータを合計した値を入れます。
int nSum = send[0] + send[1] + send[2] + send[3];
byteSum = BitConverter.GetBytes(nSum);
send[4] = byteSum[1];
send[5] = byteSum[0];
ENDは0xFEで固定です
send[6] = 0xEF;
データフレームの構成はこのようになっています

メッセージに、漢字ROMコードへ変換されたバイト配列を256バイトづつ入れて送信していきます。
フレーム番号はそのたびにカウントしていきます。
//FFHで埋める
for (int i = 0; i < 256; i++)
{
sendMessage[i] = 0xff;
}
int frameCount = 0;
int byteCount = 0;
for (int i = 0; i < vfdCode.Length; i++)
{
sendMessage[byteCount] = vfdCode[i];
byteCount++;
if (byteCount == 256 || i == vfdCode.Length - 1)
{
frameCount++;
byteCount = 0;
this.send_dataFrame(sendMessage, (byte)frameCount);
//FFHで埋める
for (int j = 0; j < 256; j++)
{
sendMessage[j] = 0xff;
}
}
}
データフレームのメッセージ内には、このようなコマンドを入れることが出来ます。

しかし、今回は文字をそのまま表示するだけなので、使用しません。
リンク
とめくぎヨロズ製作所http://www.harukaze.ne.jp/tomekugi/win/index.html

