PCとArduinoをJavaでシリアル通信
お疲れ様です。高橋です。
先日作ったコレ。
よくよく考えると、書き込む際にいちいちArduinoに曲データを解釈させる必要性が無い事に、帰宅中ハタと気づいてしまいました。
PC上で生成したArduino用コードをいちいちArduinoに食わせるまでもなく、先日のバイナリルールに則って変換したバイト配列をシリアル通信でそのまま何か使って書き込めば良いのです。
そうすると、書き込み時に毎回Arduino側でスケッチを作成する必要も無いので、純然たる書き込みスケッチと読み込みスケッチさえあれば、もっと簡単。
Javaでシリアル通信
Arduino IDEはシリアルモニターがあるのですが、バイナリデータは書き込めないような感じです。PCで動く、ArduinoのCOMポートに対してシリアルでデータを書き込むためのツールが必要です。Androidアプリ開発用のためにEclipse環境が整っていましたので、Javaで作ることにしました。
基本設計は、
- smf2ymzで出力したArduino用コードをどっかに保存 (e.g. d:/Arduino/sample.txt)
- Arduinoとのシリアル通信用COMポートを設定する (e.g. COM3)
- bpsを設定する (e.g. 9600)
- シリアル通信用の準備
- ファイルを1行ずつ読み込み、バイト配列に変換する
- 書き込む
- 最後に終了用バイト配列を書き込む
という感じ。
ライブラリを調達
Javaでシリアル通信をする際、ライブラリが必須です。
Windows 64bit用のライブラリはhttp://fizzed.com/oss/rxtx-for-javaからダウンロード出来ました。
mfz-rxtx-2.2-20081207-win-x64.zipを展開すると、下記のようなファイル達が解凍されます。
Install.txtを読めばわかるのですが、jarを適当なパス(lib系)に配置し、dllも適当なパス(bin系)に配置します。
どこに配置すれば良いのか不明な場合は、JAVA_HOMEを確認するなり、
System.out.println(System.getProperty("java.library.path"));
を動かすなりして、調べます。
Javaでの実装
下記を作りました。
package serialTest;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class SerialWrite {
// -- bps
public static String COM_PORT = "COM3";
public static int BPS = 9600;
public static String FILE_PATH = "D:/Arduino/sample.txt";
public static void main(String arg[]) throws IOException {
BufferedReader br = null;
SerialPort port = null;
OutputStream out = null;
try {
/***************************************************
* create serial connector
***************************************************/
// create serial ID
CommPortIdentifier comID = CommPortIdentifier.getPortIdentifier(COM_PORT);
// open ID (application_name, timeout)
CommPort commPort = comID.open("SerialTest02", 2000);
// cast to port
port = (SerialPort) commPort;
/***************************************************
* configure serial port
***************************************************/
port.setSerialPortParams(BPS, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
out = port.getOutputStream();
/***************************************************
* write data to Serial
*
* read from Arduino code exported by kalshagar's library.
* https://kalshagar.wikispaces.com/Arduino+and+a+YMZ294
*
***************************************************/
br = new BufferedReader(new FileReader(FILE_PATH));
String line = "";
int intValue = 0;
int intAddress = 1;
char[] data = { 0x00, 0x00, 0x00 };
while ((line = br.readLine()) != null) {
// set command to byte #1.
if (line.indexOf("set_ch") >= 0) {
data[0] = 0x01;
// set channel to byte #2.
if (line.indexOf("ADDR_FREQ_A") >= 0) {
data[1] = 0x01;
} else if (line.indexOf("ADDR_FREQ_B") >= 0) {
data[1] = 0x02;
} else if (line.indexOf("ADDR_FREQ_C") >= 0) {
data[1] = 0x03;
}
intValue = readValue(line, ",", "\\)");
data[2] = (char) intValue;
} else if (line.indexOf("delay") >= 0) {
data[0] = 0x02;
intValue = readValue(line, "\\(", "\\)");
data[1] = (char) (intValue / 100);
data[2] = (char) (intValue % 100);
}
writeDataToSerial(intAddress, out, data);
intAddress += 3;
if (intAddress % 64 == 0) intAddress++;
}
data[0] = 0x03;
data[1] = 0x00;
data[2] = 0x00;
writeDataToSerial(intAddress, out, data);
} catch (Exception e) {
e.printStackTrace();
} finally {
br.close();
out.close();
port.close();
}
}
public static int readValue(String line, String regex1, String regex2) {
String[] ary01 = line.split(regex1, 0);
String[] ary02 = ary01[1].split(regex2, 0);
int intShort = Integer.parseInt(ary02[0]);
return intShort;
}
public static void writeDataToSerial(int intAddress, OutputStream out, char data[]) throws IOException {
System.out.print("Address [" + intAddress + "] data [");
System.out.print(Integer.toHexString(data[0]));
System.out.print(" ");
System.out.print(Integer.toHexString(data[1]));
System.out.print(" ");
System.out.println(Integer.toHexString(data[2]) + "]");
// out.write(data[0]);
// out.write(data[1]);
// out.write(data[2]);
}
}
実行結果
テキストから読み込んだ物は正常にバイト配列にする事が出来ました。
シリアル通信も多分問題ないけど、明日は書き込みスケッチの実装です。
以上、よろしくお願い致します。
関連記事
-
-
【完成】 電子オルゴール
お疲れ様です。高橋です。 電子オルゴールの制作が佳境に入り、とうとうカルトナージ …
-
-
aitendoのArduino用生シールド基板を1枚120円で買った。
お疲れ様です。高橋です。 今日もaitendoに行ってきたのですが、120円のシ …
-
-
汎用ロジックIC(NAND/NOR/AND/OR)試験機
お疲れ様です。高橋です。 単一の機能を持ったシンプルな、汎用ロジックICという物 …
-
-
電子オルゴール 回路図
お疲れ様です。高橋です。 電子オルゴールの回路図を書いてみました。 実体配線図よ …
-
-
EEPROM書き込みシールドの作成
お疲れ様です。高橋です。 先日成功したPCからのEEPROM書き込みですが、ジャ …
-
-
音階LED実装 #2
お疲れ様です。高橋です。 本日も昨日に引き続き半田付け。 今日の進捗 昨日の残り …
-
-
上司の離着席状態をクラウドに飛ばし、スマホで見れるようにした。
お疲れ様です。高橋です。 前回ブレッドボード上に構築した上司離着席検知システムで …
-
-
YMZシールド 再作成
お疲れ様です。高橋です。 YMZのノイズが超気になる YMZ294用の音楽を聞く …
-
-
MIDI INの実験
お疲れ様です。高橋です。 Arduino+YMZをMIDI化するための第一歩の実 …
-
-
上司離着席検知システムの作り方
お疲れ様です。高橋です。 上司離着席検知システムの作り方は下記の通りです。 必要 …




