どうも、こんにちは。
現在私はArduinoを使って3関節の六足歩行ロボットを作成しています。
そこで、文字列を受信して、それによってサーボモータ(計18個)を動かすプログラムを試作しました。
動作を簡単に説明しますと、
①PC側から”[1,180,90,0]”といったような形式の文字列をシリアル通信によって受信。
②文字列を分割し、最初の文字を”ch”とし、それ以降の数値をそれぞれ”o[ch][1]”,”o[ch][2]”,”o[ch][3]”に格納。
③格納した数値を接続されたサーボモータへ出力。
プログラム↓
//------------------------------------------------------------------------------------
#include <string.h>
#include <Servo.h>
#define Wait (1000/200)
Servo servo[8][4];
//------------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println( "OK" );
servo[1][1].attach(22);
servo[1][2].attach(24);
servo[1][3].attach(26);
servo[2][1].attach(28);
servo[2][2].attach(30);
servo[2][3].attach(32);
servo[3][1].attach(34);
servo[3][2].attach(36);
servo[3][3].attach(38);
servo[4][1].attach(40);
servo[4][2].attach(42);
servo[4][3].attach(44);
servo[5][1].attach(46);
servo[5][2].attach(48);
servo[5][3].attach(49);
servo[6][1].attach(47);
servo[6][2].attach(45);
servo[6][3].attach(43);
}
//------------------------------------------------------------------------------------
void loop() {
////////////////////////////////////////////////////////開始
int DataSize = Serial.available();
int i = 0;
int o[8][4];
char m[256];
char *tp;
String s = "";
////////////////////////////////////////////////////////受信
//送信されてきたした文字列を1つの文字列として受信する。
if( DataSize > 0 ){
m[0] = Serial.read();
if(m[0] == '['){
delay(Wait);
for(i=1 ; i < 256 ; i++){
if(Serial.peek() != -1){
m[i] = Serial.read();
if(m[i] == ']'){ break; }
}
else{ i-=1; delay(Wait); }
}
//Serial.print("OK:");
int mSize = i;
for(i=0 ; i <= mSize ; i++){ s.concat(m[i]); }
Serial.println(s);//受け取り確認
////////////////////////////////////////////////////////格納
//受信した文字列を分解し、各変数に格納する。
for(i=0 ; i < mSize ; i++){ m[i]=m[i+1]; }
m[i-1] = ',';
/*
for(i=0 ; i < (mSize) ; i++){
Serial.println( m[i] );
}
*/
tp = strtok( m, "," );
int ch = atoi(tp);
//Serial.print( tp ); Serial.print( '/' );
Serial.println( ch );//受け取り確認
for(i=1 ; i <= 3 ; i++){
tp = strtok( NULL, "," );
o[ch][i] = atoi(tp);
//Serial.print( tp ); Serial.print( '/' );
Serial.println( o[ch][i] );//受け取り確認
}
////////////////////////////////////////////////////////伝達
//格納した数値を駆動命令としてサーボモータへ伝達する。
//if(ch < 6 && o[ch][1] < 180 && o[ch][2] < 180 && o[ch][3] < 180){
servo[ch][1].write(o[ch][1]);
servo[ch][2].write(o[ch][2]);
servo[ch][3].write(o[ch][3]);
//}
//else{ Serial.println( "No" ); }
////////////////////////////////////////////////////////終了
}
}
else{}//データが存在しなかった場合
}
//------------------------------------------------------------------------------------
こんな感じです。
で、ここからが本題なのですが、このプログラムを使用してみたところ、以下のようなエラーが出てうまくいきません。
java.io.IOException: Input/output error in writeArray
at gnu.io.RXTXPort.writeArray(Native Method)
at gnu.io.RXTXPort$SerialOutputStream.write(RXTXPort.java:1124)
at processing.app.Serial.write(Serial.java:517)
at processing.app.Serial.write(Serial.java:540)
at processing.app.SerialMonitor.send(SerialMonitor.java:200)
at processing.app.SerialMonitor.access$100(SerialMonitor.java:32)
at processing.app.SerialMonitor$3.actionPerformed(SerialMonitor.java:89)
at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
at javax.swing.JTextField.postActionEvent(JTextField.java:705)
at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
at java.awt.Component.processEvent(Component.java:6040)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
at java.awt.Component.dispatchEventImpl(Component.java:4502)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Window.dispatchEventImpl(Window.java:2475)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
具体的にいうと、最初の数回はうまくいっても、その途中でサーボが動かなくなります。
それどころか、途中でシリアルポートの通信が切れてしまうようで、IED内でもCOMを認識してくれません。
そのため、Arduinoのリセットボタンを押しても通信は回復せず、USBケーブルをさしなおさなければなりません。
また、モータの方も1秒おき程度に指定していない角度へ動いていくなど、妙な挙動を引き起こします。
この問題に心当たりがあれば何卒返信をお願いいたします。