卓上調整
メカが完成したので、マシンを卓の上に載せて
動作を確認し、調整します。
マシンはスタートスイッチを押した後、センサー情報を
判断して走行するので、センサー情報を与えて、どの様
にサーボモータで前輪を動かすのかを調べます。
パーソナルコンピュータ上のGUIで、センサー情報を
指定し、マイクロコンピュータに与え、8ビットの
データとしてマシン制御担当のFPGAに与えます。
GUI画面は、以下とします。
通信ポートと転送速度をコンボボックスで選択後
Connectボタンのクリックでマイクロコンピュータ
と接続します。
センサー情報出力は、コンボボックスの中から該当する
パターンを指定後、sendボタンをクリックします。
切断するときは、Disconnectボタンをクリックします。
Javaコードの構成は、以下としました。
トップレベルのコード(rstst.java)は、以下です。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import gnu.io.*;
import java.io.*;
// internal Device Test Board class
class DtbC
{
SerialPort port;
CommPortIdentifier comID;
String comName;
int baudRate;
InputStream in;
OutputStream out;
// open method
boolean rs_open(String Com_Name,int Baud_Rate)
{
comName = Com_Name;
baudRate = Baud_Rate;
// get port ID
try {
comID = CommPortIdentifier.getPortIdentifier(comName);
} catch(Exception e) {
JOptionPane.showMessageDialog(null,"Do not nortify !","DtbC.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
// already opened
if ( comID.isCurrentlyOwned() == false ) {
try {
// generate instance
port = (SerialPort)comID.open("DTB",2000);
// baud rate , data length , stop bit , parity
port.setSerialPortParams(baudRate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
// no flow control
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
// input and output stream
in = port.getInputStream();
out = port.getOutputStream();
} catch(Exception e) {
JOptionPane.showMessageDialog(null,"Do not open !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
} else {
JOptionPane.showMessageDialog(null,"Already opened !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
// close method
boolean rs_close()
{
if ( comID.isCurrentlyOwned() ) {
try {
port.close();
in.close();
out.close();
} catch(IOException e) {
JOptionPane.showMessageDialog(null,"Do not close !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
} else {
JOptionPane.showMessageDialog(null,"Already closed !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
// send string
void Serial_puts(String str)
{
byte[] data = str.getBytes();
try {
out.write(data);
out.flush();
} catch(Exception e) {
}
}
}
// internal Serial Class (super class => DtbC)
class Serial_Class extends DtbC
{
JComboBox cbxCom;
JComboBox cbxBaud;
JTextArea edtText;
JScrollPane scrPane;
// constructor
Serial_Class()
{
// generate text area
edtText = new JTextArea();
// generate scroll pane
scrPane = new JScrollPane(edtText);
scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// COM port ComboBox
cbxCom = new JComboBox();
cbxCom.addItem("COM1"); cbxCom.addItem("COM2");
cbxCom.addItem("COM3"); cbxCom.addItem("COM4");
cbxCom.addItem("COM5"); cbxCom.addItem("COM6");
cbxCom.addItem("COM7"); cbxCom.addItem("COM8");
cbxCom.addItem("COM9");
// default port
cbxCom.setSelectedItem("COM6");
// Buad rate ComboBox
cbxBaud = new JComboBox();
cbxBaud.addItem("4800") ;
cbxBaud.addItem("9600");
cbxBaud.addItem("19200");
// default baud rate
cbxBaud.setSelectedItem("9600");
}
// open method
void open()
{
boolean flag;
// convert COM name to string
String COM_Name = (cbxCom.getSelectedItem()).toString();
// get baud rate from ComboBox
int Baud_Rate = Integer.parseInt((cbxBaud.getSelectedItem()).toString());
// open
flag = rs_open(COM_Name,Baud_Rate);
// success
if ( flag ) {
try {
// register receive event handler
port.addEventListener(new SerialPortListener());
// add event monitor
port.notifyOnDataAvailable(true);
} catch(Exception e) {
}
edtText.append("Connected");
}
}
// close method
void close()
{
boolean flag;
// close
flag = rs_close();
// success
if ( flag ) { edtText.append("Disconnected"); }
}
// event listener
class SerialPortListener implements SerialPortEventListener
{
// event handler
public void serialEvent(SerialPortEvent Serial_event)
{
StringBuffer buffer = new StringBuffer();
int received_data = 0 ;
// receive completed
if ( Serial_event.getEventType() == SerialPortEvent.DATA_AVAILABLE ) {
// loop until get 'break'
while (true) {
try {
// get data from input stream
received_data = in.read();
// no charactor
if ( received_data == -1 ) break;
// store
if ( (char)received_data != '\r' ) {
buffer.append((char)received_data);
} else {
// get delimiter
// convert
edtText.append(buffer.toString());
// clear buffer
//buffer.delete(0,buffer.length()-1);
buffer.delete(0,buffer.length());
// post handling
edtText.setCaretPosition(edtText.getText().length());
//break;
}
} catch(IOException ex){
}
}
}
}
}
}
// internal Frame (window) class
class MFrame extends JFrame
{
Serial_Class serial;
JComboBox cbxSensor ;
// constructor
MFrame()
{
// call super class method
super("MCR-VC sensor test");
serial = new Serial_Class();
// generate pane
JPanel cp = new JPanel();
// set layout moe
cp.setLayout(null);
// add pane to frame
setContentPane(cp);
// generate scroll pane
JScrollPane sp = new JScrollPane(serial.edtText);
// enable vertical scroll bar
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// set scroll pane dimension
sp.setBounds(50,50,400,300);
// add scroll pane
cp.add(sp);
// show COM port
JLabel com_label = new JLabel("COM port:");
cp.add(com_label);
com_label.setBounds(50,20,100,20);
cp.add(serial.cbxCom);
serial.cbxCom.setBounds(120,20,80,20);
// show selected baud rate
JLabel baud_label = new JLabel("Baud rate : ");
cp.add(baud_label);
baud_label.setBounds(250,20,100,20);
cp.add(serial.cbxBaud);
serial.cbxBaud.setBounds(350,20,80,20);
// show selected sensor data
JLabel sensor_label = new JLabel("sensor data : ");
cp.add(sensor_label);
sensor_label.setBounds(50,400,80,20);
cbxSensor = new JComboBox();
cp.add(cbxSensor);
cbxSensor.setBounds(150,400,120,20);
cbxSensor.addItem("ALL_BLACK") ;
cbxSensor.addItem("TINY_RIGHT");
cbxSensor.addItem("RIGHT");
cbxSensor.addItem("BIG_RIGHT");
cbxSensor.addItem("CENTER") ;
cbxSensor.addItem("TINY_LEFT");
cbxSensor.addItem("LEFT");
cbxSensor.addItem("BIG_LEFT");
cbxSensor.addItem("LEFT_WHITE");
cbxSensor.addItem("RIGHT_WHITE");
cbxSensor.addItem("ALL_WHITE") ;
// generate Font
Font font = new Font("SansSerif",Font.PLAIN,16);
// add Font information to textarea
serial.edtText.setFont(font);
serial.edtText.setLineWrap(true);
serial.edtText.addKeyListener(new KeyInput());
serial.scrPane.setBounds(50,50,400,300);
cp.add(serial.scrPane);
// define button
JButton btnConnect = new JButton(new open_action());
btnConnect.setBounds(50,350,100,36);
cp.add(btnConnect);
JButton btnDisconnect = new JButton(new close_action());
btnDisconnect.setBounds(300,350,100,36);
cp.add(btnDisconnect);
JButton btnSend = new JButton(new send_action());
btnSend.setBounds(300,400,80,20);
cp.add(btnSend);
// register KeyInput class to KeyListener
serial.edtText.addKeyListener(new KeyInput());
}
// internal class (bntConnect)
class open_action extends AbstractAction
{
// constructor
open_action()
{
putValue(Action.NAME,"Connect");
}
// event method
public void actionPerformed(ActionEvent btnConnect_act)
{
serial.open();
}
}
// internal class (bntDisconnect)
class close_action extends AbstractAction
{
// constructor
close_action()
{
putValue(Action.NAME,"Disconnect");
}
// event method
public void actionPerformed(ActionEvent btnDisconnect_act)
{
serial.close();
}
}
// internal class (bntSend)
class send_action extends AbstractAction
{
// constructor
send_action()
{
putValue(Action.NAME,"Send");
}
// event method
public void actionPerformed(ActionEvent bntSend_act)
{
// 0 ALL_BLACK
// 1 TINY_RIGHT
// 2 RIGHT
// 3 BIG_RIGHT
// 4 CENTER
// 5 TINY_LEFT
// 6 LEFT
// 7 BIG_LEFT
// 8 LEFT_WHITE
// 9 RIGHT_WHITE
// 10 ALL_WHITE
int index ;
String stmp ;
// get index
index = cbxSensor.getSelectedIndex() ;
// generate code
stmp = "B" + index + "\r" ;
// show
serial.edtText.append(stmp+"\n");
// send
serial.Serial_puts(stmp);
}
}
// key event
class KeyInput extends KeyAdapter
{
String stmp;
String[] stmp_array;
int lineNum;
public void keyPressed(KeyEvent e)
{
// get key then echo to textArea
if ( e.getKeyCode() == KeyEvent.VK_ENTER )
{
//serial.edtText.append("\n");
stmp = serial.edtText.getText();
stmp_array = stmp.split("\n",0);
lineNum = stmp_array.length - 1;
// send serial port
serial.Serial_puts(stmp_array[lineNum]+"\r");
}
}
}
}
public class rstst
{
private final static int my_frm_width = 500 ;
private final static int my_frm_height = 500 ;
public static void main(String args[])
{
MFrame frame = new MFrame();
//
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set dimension
frame.setSize(my_frm_width,my_frm_height);
// show
frame.setVisible(true);
}
}
GUIの形態を決めるコード(MFrame.java)は、以下。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import gnu.io.*;
import java.io.*;
class MFrame extends JFrame
{
JTextArea edtText;
MFrame()
{
// call super class constructor
super("MCR machine test");
// generate pane
JPanel cp = new JPanel();
// set layout moe
cp.setLayout(null);
// add pane to frame
add(cp);
// generate text area
edtText = new JTextArea();
// enable word wrap
edtText.setLineWrap(true);
// generate scroll pane
JScrollPane sp = new JScrollPane(edtText);
// enable vertical scroll bar
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// set scroll pane dimension
sp.setBounds(50,50,400,300);
// add scroll pane
cp.add(sp);
// generate Font
Font font = new Font("SansSerif",Font.PLAIN,16);
// add Font information to textarea。
edtText.setFont(font);
// generate ComboBox
JComboBox cbxCom = new JComboBox();
// add items
cbxCom.addItem("COM1"); cbxCom.addItem("COM2");
cbxCom.addItem("COM3"); cbxCom.addItem("COM4");
cbxCom.addItem("COM5"); cbxCom.addItem("COM6");
cbxCom.addItem("COM7"); cbxCom.addItem("COM8");
// set location and dimension
cbxCom.setBounds(120,20,80,20);
// add ComboBox
cp.add(cbxCom);
// set default COM port
cbxCom.setSelectedItem("COM6");
// add label
JLabel com_label = new JLabel("COM port:");
com_label.setBounds(50,20,100,20);
cp.add(com_label);
// communication condition
JComboBox cbxBaud = new JComboBox();
// add items
cbxBaud.addItem("4800") ; cbxBaud.addItem("9600");
cbxBaud.addItem("19200"); cbxBaud.addItem("38400");
cbxBaud.addItem("57600");
cbxBaud.setBounds(350,20,80,20);
cp.add(cbxBaud);
// select 38400 bps
cbxBaud.setSelectedItem("38400");
// show selected baud rate
JLabel baud_label = new JLabel("Baud rate : ");
baud_label.setBounds(250,20,100,20);
cp.add(baud_label);
// define button
JButton btnConnect = new JButton(new open_action());
btnConnect.setBounds(50,400,150,40);
cp.add(btnConnect);
JButton btnDisconnect = new JButton(new close_action());
btnDisconnect.setBounds(300,400,150,40);
cp.add(btnDisconnect);
// register KeyInput class to KeyListener
edtText.addKeyListener(new KeyInput());
}
// internal class (bntConnect)
class open_action extends AbstractAction
{
// constructor
open_action()
{
putValue(Action.NAME,"Connect");
}
// event method
public void actionPerformed(ActionEvent btnConnect_act)
{
edtText.append("Connected\n");
JOptionPane.showMessageDialog(null,"Conneced","actionPerformed()",JOptionPane.INFORMATION_MESSAGE);
}
}
// internal class (bntDisconnect)
class close_action extends AbstractAction
{
// constructor
close_action()
{
putValue(Action.NAME,"Disconnect");
}
// event method
public void actionPerformed(ActionEvent btnDisconnect_act)
{
edtText.append("Disonnected\n");
JOptionPane.showMessageDialog(null,"Disconneced","actionPerformed()",JOptionPane.INFORMATION_MESSAGE);
}
}
// key event
class KeyInput extends KeyAdapter
{
//何かキーボードが押されたときに呼ばれるメソッド。
public void keyPressed(KeyEvent e)
{
//ENTERキーならば、テキストエリアに表示。
if ( e.getKeyCode() == KeyEvent.VK_ENTER )
{
edtText.append("Enterキーが押されました。");
}
}
}
}
通信オブジェクトのラッパであるコード(DtbC.java)は、以下。
(DtbCは、Data transfer block Classの略)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import gnu.io.*;
class DtbC
{
SerialPort port;
CommPortIdentifier comID;
String comName;
int baudRate;
InputStream in;
OutputStream out;
// open method
boolean rs_open(String Com_Name,int Baud_Rate)
{
comName = Com_Name;
baudRate = Baud_Rate;
// get port ID
try {
comID = CommPortIdentifier.getPortIdentifier(comName);
} catch(Exception e1) {
JOptionPane.showMessageDialog(null,"Do not nortify !","Serial_Base.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
// already opened
if ( comID.isCurrentlyOwned() == false ) {
try {
// generate instance
port = (SerialPort)comID.open("DTB",2000);
// baud rate , data length , stop bit , parity
port.setSerialPortParams(baudRate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
// no flow control
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
// input and output stream
in = port.getInputStream();
out = port.getOutputStream();
} catch(Exception e2) {
JOptionPane.showMessageDialog(null,"Do not open !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
} else {
JOptionPane.showMessageDialog(null,"Already opened !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
// close method
boolean rs_close()
{
if ( comID.isCurrentlyOwned() ) {
try {
port.close();
in.close();
out.close();
} catch(IOException e3) {
JOptionPane.showMessageDialog(null,"Do not close !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
} else {
JOptionPane.showMessageDialog(null,"Already closed !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
// send string
void Serial_puts(String str)
{
try {
byte[] data = str.getBytes();
out.write(data);
out.flush();
} catch(Exception e4) {
}
}
}
通信オブジェクトの本体(Serial_Class.java)は、以下。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import gnu.io.*;
import java.io.*;
class Serial_Class extends DtbC
{
JComboBox cbxCom;
JComboBox cbxBaud;
JTextArea edtText;
JScrollPane scrollPane;
// constructor
Serial_Class()
{
// generate text area
edtText = new JTextArea();
// generate scroll pane
scrollPane = new JScrollPane(edtText);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// COM port ComboBox
cbxCom = new JComboBox();
cbxCom.addItem("COM1"); cbxCom.addItem("COM2");
cbxCom.addItem("COM3"); cbxCom.addItem("COM4");
cbxCom.addItem("COM5"); cbxCom.addItem("COM6");
cbxCom.addItem("COM7"); cbxCom.addItem("COM8");
// default port
cbxCom.setSelectedItem("COM6");
// Buad rate ComboBox
cbxBaud = new JComboBox();
cbxBaud.addItem("4800") ; cbxBaud.addItem("9600");
cbxBaud.addItem("19200"); cbxBaud.addItem("38400");
cbxBaud.addItem("57600");
// default baud rate
cbxBaud.setSelectedItem("38400");
}
// open method
void open()
{
boolean flag;
// convert COM name to string
String COM_Name = (cbxCom.getSelectedItem()).toString();
// get baud rate from ComboBox
int Baud_Rate = Integer.parseInt((cbxBaud.getSelectedItem()).toString());
// open
flag = rs_open(COM_Name,Baud_Rate);
// success
if ( flag ) {
try {
// register receive event handler
port.addEventListener(new SerialPortListener());
// add event monitor
port.notifyOnDataAvailable(true);
} catch(Exception e) {
}
edtText.append("Connected\n\n");
}
}
// close method
void close()
{
boolean flag;
// close
flag = rs_close();
// success
if ( flag ) {
edtText.append("Disconnected\n\n");
}
}
// event listener
class SerialPortListener implements SerialPortEventListener
{
// event handler
public void serialEvent(SerialPortEvent Serial_event)
{
StringBuffer buffer = new StringBuffer();
int received_data;
received_data = 0;
// receive completed
if ( Serial_event.getEventType() == SerialPortEvent.DATA_AVAILABLE ) {
// loop until get 'break'
while (true) {
try {
// get data from input stream
received_data = in.read();
// no charactor
if ( received_data == -1 ) break;
// store
if ( (char)received_data != '\r' ) buffer.append((char)received_data);
// get delimiter
else {
// new line
buffer.append('\n');
// convert
edtText.append(buffer.toString());
// clear buffer
buffer.delete(0,buffer.length()-1);
// post handling
edtText.setCaretPosition(edtText.getText().length());
break;
}
} catch(IOException ex){
}
}
}
}
}
}
マイクロコンピュータとして、AtmelのATtiny2313を利用します。
回路図は、以下です。
20MHzで動作させ、シリアルインタフェースは小信号NPN
トランジスタを利用した簡易タイプにしました。
パーソナルコンピュータから与えられたコード番号を
基に、配列からビットパターンを引出して、ポートB
に出力します。
受信割込みで、パーソナルコンピュータが与えたコードを
取得します。コマンド到着を、フラグで通知します。
#include <avr/io.h>
#include <avr/interrupt.h>
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
#define FOSC 20000000
#define BAUD 9600
#define MYUBRR (FOSC/16/BAUD)-1
#define MASKFF 0xff
#define MASK0F 0x0f
#define MASKF0 0xf0
#define BUFSIZE 8
#define SENSOR_ALL_BLACK 0
#define SENSOR_TINY_RIGHT 1
#define SENSOR_RIGHT 2
#define SENSOR_BIG_RIGHT 3
#define SENSOR_CENTER 4
#define SENSOR_TINY_LEFT 5
#define SENSOR_LEFT 6
#define SENSOR_BIG_LEFT 7
#define SENSOR_LEFT_WHITE 8
#define SENSOR_RIGHT_WHITE 9
#define SENSOR_ALL_WHITE 10
volatile UBYTE sbuf[BUFSIZE] ;
volatile UBYTE sindex;
volatile UBYTE uflag ;
volatile UBYTE cmd ;
volatile UBYTE select ;
volatile UBYTE spat[16] = {0x00,0x0C,0x06,0x03,
0x18,0x30,0x60,0xC0,
0xF0,0x0F,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF};
#define NO 0
#define YES NO+1
/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void user_initialize(void);
void show_help(void);
UBYTE rs_get_digit(UBYTE x);
void rs_putchar(UBYTE x);
void rs_puts(UBYTE *x);
/*------*/
/* main */
/*------*/
int main(void)
{
/* initialize */
user_initialize();
/* enable interrupt */
sei();
/* loop */
while ( ON ) {
/* handling */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* branch */
if ( cmd == '?' ) {
show_help();
}
if ( cmd == 'B' ) {
select = rs_get_digit(*(sbuf+1));
select = select * 10 + rs_get_digit(*(sbuf+2));
PORTB = *(spat+select);
}
}
}
/* dummy */
return 0 ;
}
/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{
/* PORT D */
PORTD = 0b00000001 ; /* 00000001 */
DDRD = 0b11111110 ; /* oooooooi */
/* PORT B */
PORTB = 0b00000000 ; /* 00000000 */
DDRB = 0b11111111 ; /* oooooooo */
/* clear flags */
uflag = OFF ;
/* others */
cmd = 0 ;
select = 0 ;
/* initialize serial */
{
/* clear index */
sindex = 0 ;
/* clear buffer */
*(sbuf+0) = 0 ;
/* set Baud Rate Registers */
UBRRL = MYUBRR ;
/* Enable receive interrupt , receive module and transmit module */
UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN) ;
}
}
/* UART receive interrupt */
ISR(USART_RX_vect)
{
UBYTE ch ;
/* get 1 charactoer */
ch = UDR ;
/* store */
*(sbuf+sindex) = ch ;
sindex++ ;
/* judge */
if ( ch == '\r' ) {
uflag = ON ;
sindex = 0 ;
}
}
void show_help(void)
{
rs_puts( (UBYTE *)"B -> pattern" ) ;
rs_puts( (UBYTE *)"? -> Help" ) ;
}
UBYTE rs_get_digit(UBYTE x)
{
volatile UBYTE result ;
/* default */
result = 0 ;
if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10; };
if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10; };
return result ;
}
void rs_putchar(UBYTE x)
{
while ( !(UCSRA & (1 << UDRE)) ) {}
UDR = x ;
}
void rs_puts(UBYTE *x)
{
while ( *x != '\0' ) {
rs_putchar( *x ) ;
x++ ;
}
rs_putchar('\r');
rs_putchar('\n');
}
路面情報をテキストファイルに入れ、それを与えることで
卓上調整をより簡単にしたいと考えました。
テキストファイルの1行に入れる情報は、次の書式としました。
センサーデータ(文字列) 継続時間(msの倍数)
テキストファイルの内容は、以下のようにします。
CENTER 1000
ALL_BLACK 1500
TINY_RIGHT 1000
RIGHT 3000
BIG_RIGHT 1000
TINY_LEFT 1000
LEFT 2000
BIG_LEFT 1000
ALL_WHITE 1500
RIGHT_WHITE 1500
LEFT_WHITE 1500
ALL_WHITE 1500
CENTER 1000
Javaコードを拡張して、テキストファイルから情報を入力し
センサー情報をマイコンに自動転送するボタンを用意します。
コードは、以下です。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import gnu.io.*;
import java.io.*;
// internal Device Test Board class
class DtbC
{
SerialPort port;
CommPortIdentifier comID;
String comName;
int baudRate;
InputStream in;
OutputStream out;
// open method
boolean rs_open(String Com_Name,int Baud_Rate)
{
comName = Com_Name;
baudRate = Baud_Rate;
// get port ID
try {
comID = CommPortIdentifier.getPortIdentifier(comName);
} catch(Exception e) {
JOptionPane.showMessageDialog(null,"Do not nortify !","DtbC.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
// already opened
if ( comID.isCurrentlyOwned() == false ) {
try {
// generate instance
port = (SerialPort)comID.open("DTB",2000);
// baud rate , data length , stop bit , parity
port.setSerialPortParams(baudRate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
// no flow control
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
// input and output stream
in = port.getInputStream();
out = port.getOutputStream();
} catch(Exception e) {
JOptionPane.showMessageDialog(null,"Do not open !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
} else {
JOptionPane.showMessageDialog(null,"Already opened !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
// close method
boolean rs_close()
{
if ( comID.isCurrentlyOwned() ) {
try {
port.close();
in.close();
out.close();
} catch(IOException e) {
JOptionPane.showMessageDialog(null,"Do not close !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
} else {
JOptionPane.showMessageDialog(null,"Already closed !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
// send string
void Serial_puts(String str)
{
byte[] data = str.getBytes();
try {
out.write(data);
out.flush();
} catch(Exception e) {
}
}
}
// internal Serial Class (super class => DtbC)
class Serial_Class extends DtbC
{
JComboBox cbxCom;
JComboBox cbxBaud;
JTextArea edtText;
JScrollPane scrPane;
// constructor
Serial_Class()
{
// generate text area
edtText = new JTextArea();
// generate scroll pane
scrPane = new JScrollPane(edtText);
scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// COM port ComboBox
cbxCom = new JComboBox();
cbxCom.addItem("COM1"); cbxCom.addItem("COM2");
cbxCom.addItem("COM3"); cbxCom.addItem("COM4");
cbxCom.addItem("COM5"); cbxCom.addItem("COM6");
cbxCom.addItem("COM7"); cbxCom.addItem("COM8");
cbxCom.addItem("COM9");
// default port
cbxCom.setSelectedItem("COM6");
// Buad rate ComboBox
cbxBaud = new JComboBox();
cbxBaud.addItem("4800") ;
cbxBaud.addItem("9600");
cbxBaud.addItem("19200");
// default baud rate
cbxBaud.setSelectedItem("9600");
}
// open method
void open()
{
boolean flag;
// convert COM name to string
String COM_Name = (cbxCom.getSelectedItem()).toString();
// get baud rate from ComboBox
int Baud_Rate = Integer.parseInt((cbxBaud.getSelectedItem()).toString());
// open
flag = rs_open(COM_Name,Baud_Rate);
// success
if ( flag ) {
try {
// register receive event handler
port.addEventListener(new SerialPortListener());
// add event monitor
port.notifyOnDataAvailable(true);
} catch(Exception e) {
}
edtText.append("Connected");
}
}
// close method
void close()
{
boolean flag;
// close
flag = rs_close();
// success
if ( flag ) { edtText.append("Disconnected"); }
}
// event listener
class SerialPortListener implements SerialPortEventListener
{
// event handler
public void serialEvent(SerialPortEvent Serial_event)
{
StringBuffer buffer = new StringBuffer();
int received_data = 0 ;
// receive completed
if ( Serial_event.getEventType() == SerialPortEvent.DATA_AVAILABLE ) {
// loop until get 'break'
while (true) {
try {
// get data from input stream
received_data = in.read();
// no charactor
if ( received_data == -1 ) break;
// store
if ( (char)received_data != '\r' ) {
buffer.append((char)received_data);
} else {
// get delimiter
// convert
edtText.append(buffer.toString());
// clear buffer
//buffer.delete(0,buffer.length()-1);
buffer.delete(0,buffer.length());
// post handling
edtText.setCaretPosition(edtText.getText().length());
//break;
}
} catch(IOException ex){
}
}
}
}
}
}
// internal Frame (window) class
class MFrame extends JFrame
{
Serial_Class serial;
JComboBox cbxSensor ;
String[] stmpx ;
String[] cmdval = new String[11] ;
String[] cmd = new String[11] ;
// constructor
MFrame()
{
// call super class method
super("MCR-VC sensor test");
serial = new Serial_Class();
// generate pane
JPanel cp = new JPanel();
// set layout moe
cp.setLayout(null);
// add pane to frame
setContentPane(cp);
// generate scroll pane
JScrollPane sp = new JScrollPane(serial.edtText);
// enable vertical scroll bar
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// set scroll pane dimension
sp.setBounds(50,50,400,300);
// add scroll pane
cp.add(sp);
// show COM port
JLabel com_label = new JLabel("COM port:");
cp.add(com_label);
com_label.setBounds(50,20,100,20);
cp.add(serial.cbxCom);
serial.cbxCom.setBounds(120,20,80,20);
// show selected baud rate
JLabel baud_label = new JLabel("Baud rate : ");
cp.add(baud_label);
baud_label.setBounds(250,20,100,20);
cp.add(serial.cbxBaud);
serial.cbxBaud.setBounds(350,20,80,20);
// make table
//String[] cmd = new String[11] ;
{
cmd[ 0] = "ALL_BLACK" ; cmd[ 1] = "TINY_RIGHT" ;
cmd[ 2] = "RIGHT" ; cmd[ 3] = "BIG_RIGHT" ;
cmd[ 4] = "CENTER" ; cmd[ 5] = "TINY_LEFT" ;
cmd[ 6] = "LEFT" ; cmd[ 7] = "BIG_LEFT" ;
cmd[ 8] = "LEFT_WHITE" ; cmd[ 9] = "RIGHT_WHITE" ;
cmd[10] = "ALL_WHITE" ;
}
//String[] cmdval = new String[11] ;
{
cmdval[ 0] = "B00" ; cmdval[ 1] = "B01" ;
cmdval[ 2] = "B02" ; cmdval[ 3] = "B03" ;
cmdval[ 4] = "B04" ; cmdval[ 5] = "B05" ;
cmdval[ 6] = "B06" ; cmdval[ 7] = "B07" ;
cmdval[ 8] = "B08" ; cmdval[ 9] = "B09" ;
cmdval[10] = "B10" ;
}
// show selected sensor data
JLabel sensor_label = new JLabel("sensor data : ");
cp.add(sensor_label);
sensor_label.setBounds(50,400,80,20);
cbxSensor = new JComboBox();
cp.add(cbxSensor);
cbxSensor.setBounds(150,400,120,20);
for (int i = 0 ; i < 11 ; i++ ) {
cbxSensor.addItem(cmd[i]) ;
}
// generate Font
Font font = new Font("SansSerif",Font.PLAIN,16);
// add Font information to textarea
serial.edtText.setFont(font);
serial.edtText.setLineWrap(true);
serial.edtText.addKeyListener(new KeyInput());
serial.scrPane.setBounds(50,50,400,300);
cp.add(serial.scrPane);
// define button
JButton btnConnect = new JButton(new open_action());
btnConnect.setBounds(50,350,100,36);
cp.add(btnConnect);
JButton btnDisconnect = new JButton(new close_action());
btnDisconnect.setBounds(300,350,100,36);
cp.add(btnDisconnect);
JButton btnSend = new JButton(new send_action());
btnSend.setBounds(300,400,80,20);
cp.add(btnSend);
JButton btnAuto = new JButton(new auto_action());
btnAuto.setBounds(300,440,80,20);
cp.add(btnAuto);
JButton btnClear = new JButton(new clear_action());
btnClear.setBounds(300,440,80,20);
cp.add(btnClear);
// register KeyInput class to KeyListener
serial.edtText.addKeyListener(new KeyInput());
}
// internal class (bntConnect)
class open_action extends AbstractAction
{
// constructor
open_action()
{
putValue(Action.NAME,"Connect");
}
// event method
public void actionPerformed(ActionEvent btnConnect_act)
{
serial.open();
}
}
// internal class (bntDisconnect)
class close_action extends AbstractAction
{
// constructor
close_action()
{
putValue(Action.NAME,"Disconnect");
}
// event method
public void actionPerformed(ActionEvent btnDisconnect_act)
{
serial.close();
}
}
// internal class (bntSend)
class send_action extends AbstractAction
{
// constructor
send_action()
{
putValue(Action.NAME,"Send");
}
// event method
public void actionPerformed(ActionEvent bntSend_act)
{
int index ;
String stmp ;
// get index
index = cbxSensor.getSelectedIndex() ;
// generate code
stmp = cmdval[index] + "\r" ;
// show
serial.edtText.append(stmp+"\n");
// send
serial.Serial_puts(stmp);
}
}
// internal class (bntAuto)
class auto_action extends AbstractAction
{
// constructor
auto_action()
{
putValue(Action.NAME,"Auto");
}
// event method
public void actionPerformed(ActionEvent btnAuto_act)
{
String xstmp ;
int i ;
int j ;
int xdelay ;
boolean flag ;
String stmp ;
// clear
stmp = "" ;
try {
FileReader in = new FileReader("txt.txt");
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
stmp += line ;
stmp += " " ;
}
br.close();
in.close();
// store
stmpx = stmp.split(" ");
} catch (IOException e) {
//
}
for (i = 0 ; i < stmpx.length ; i++ ) {
xstmp = stmpx[i] ;
// search
flag = false ;
for (j = 0 ; j < 11 ; j++ ) {
if ( xstmp.equals(cmd[j]) ) { flag = true ; }
if ( flag == true ) break ;
}
// send
if ( flag == true ) {
serial.edtText.append(cmdval[j]+"\n");
// send serial port
serial.Serial_puts(cmdval[j]+"\r");
} else {
// delay
xdelay = Integer.valueOf(xstmp).intValue();
try {
Thread.sleep(xdelay);
} catch (InterruptedException e){
}
serial.edtText.append(xstmp + "\n");
}
}
}
}
// internal class (bntClear)
class clear_action extends AbstractAction
{
// constructor
clear_action()
{
putValue(Action.NAME,"Clear");
}
// event method
public void actionPerformed(ActionEvent btnClear_act)
{
serial.edtText.setText("");
}
}
// key event
class KeyInput extends KeyAdapter
{
String stmp;
String[] stmp_array;
int lineNum;
public void keyPressed(KeyEvent e)
{
// get key then echo to textArea
if ( e.getKeyCode() == KeyEvent.VK_ENTER )
{
//serial.edtText.append("\n");
stmp = serial.edtText.getText();
stmp_array = stmp.split("\n",0);
lineNum = stmp_array.length - 1;
// send serial port
serial.Serial_puts(stmp_array[lineNum]+"\r");
}
}
}
}
public class rstst
{
private final static int my_frm_width = 500 ;
private final static int my_frm_height = 500 ;
public static void main(String args[])
{
MFrame frame = new MFrame();
//
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set dimension
frame.setSize(my_frm_width,my_frm_height);
// show
frame.setVisible(true);
}
}
センサー情報の文字列とコマンドを配列に入れ
指定されたセンサー情報から、コマンド文字列
を生成し、継続時間をsleepで作ります。
新たに構築した調整環境を使うと、早速バグが出ました。
センサー情報でサーボを動かしますが、動かした後、中央
にステアリングを戻していません。
自動車の運転と同じで、進路を変えたなら、ステアリングを
中央に戻さないと、その状態を維持します。これではライン
トレースになりません。
サーボモータで、ステアリングを中央から動かしたなら
然るべき時間後に、中央に戻します。
NORMAL、CRANK、LANE_CHANGEの3モードの中で、ステアリング
を中央に戻す操作は、LANE_CHANGEで必要になります。
NORMAL、CRANKでは、センサー情報に応じたサーボモータと
DCモータの制御をかけるだけでよいこともわかりました。
目次
前
次