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]); } }
実行結果
テキストから読み込んだ物は正常にバイト配列にする事が出来ました。
シリアル通信も多分問題ないけど、明日は書き込みスケッチの実装です。
以上、よろしくお願い致します。
関連記事
-
-
ArduinoIDE1.6.4+ATTiny13Aで赤外線リモコン(難航)
お疲れ様です。高橋です。 先日から引き続いて、ATTiny13Aで赤外線リモコン …
-
-
電子オルゴール 基板実装 #1
お疲れ様です。高橋です。 Pro Mini互換機を贅沢に使った電子オルゴールの仮 …
-
-
マウスを入力I/Fとして使うのを断念してみた。
お疲れ様です。高橋です。 先日の「マウスを分解してみた」でマウスを分解し、ケーブ …
-
-
FM音源YM2203をArduinoで鳴らしたい #3
お疲れさまです。高橋です。 昨年8月にブレッドボード上で動作したFM音源YM22 …
-
-
ブレッドボード上のYMZ294をユニバーサル基板化してみたが。
お疲れ様です。高橋です。 ArduinoからYMZを鳴らしているブレッドボードが …
-
-
赤外線リモコンをケースに格納
お疲れ様です。高橋です。 先日作ったATtiny13Aの赤外線リモコンを、ケース …
-
-
aitendoで買った4桁7セグLEDを使う
お疲れ様です。高橋です。 aitendoの4桁7セグLED aitendoで1個 …
-
-
100均で買ったボリュームコントロール付きステレオ延長コードを、バブ型スピーカーに搭載してみた。
お疲れ様です。高橋です。 先日作ったバブ型スピーカーですが、実は裏側がとても汚い …
-
-
【完成】 耳コピミキサー
お疲れ様です。高橋です。 作成途中だった耳コピミキサー、やっと完成しました。 思 …
-
-
音階LEDの再設計
お疲れ様です。高橋です。 本日帰宅途中に電車をぼーっと待っている時、ふと、音階L …