From 8c1844393f695e47058bed64f9bc13b31745df1b Mon Sep 17 00:00:00 2001 From: "tod.kurt" Date: Tue, 11 May 2010 02:25:13 +0000 Subject: added arduino-serial --- ArduinoSerial/ArduinoSerial.java | 136 +++++++++++++++++ ArduinoSerial/makeit.sh | 10 ++ ArduinoSerial/runit.sh | 6 + ArduinoSerial/rxtxlib/RXTXcomm.jar | Bin 0 -> 59464 bytes ArduinoSerial/rxtxlib/librxtxSerial.jnilib | Bin 0 -> 271860 bytes arduino-serial.c | 236 +++++++++++++++++++++++++++++ 6 files changed, 388 insertions(+) create mode 100644 ArduinoSerial/ArduinoSerial.java create mode 100755 ArduinoSerial/makeit.sh create mode 100755 ArduinoSerial/runit.sh create mode 100644 ArduinoSerial/rxtxlib/RXTXcomm.jar create mode 100755 ArduinoSerial/rxtxlib/librxtxSerial.jnilib create mode 100644 arduino-serial.c diff --git a/ArduinoSerial/ArduinoSerial.java b/ArduinoSerial/ArduinoSerial.java new file mode 100644 index 0000000..33dd8b1 --- /dev/null +++ b/ArduinoSerial/ArduinoSerial.java @@ -0,0 +1,136 @@ +/** + * + * + * + */ + + +import gnu.io.*; +import java.io.*; +import java.util.*; + + + +public class ArduinoSerial implements SerialPortEventListener +{ + public boolean debug = false; + + static int rate = 57600; + static final int databits = 8; + static final int parity = SerialPort.PARITY_NONE; + static final int stopbits = SerialPort.STOPBITS_1; + + public SerialPort port = null; + public String portname = "/dev/tty.usbmodem000014FD1"; + + /** the serial input stream, normally you don't need access to this */ + public InputStream input; + /** the serial output stream, normally you don't need access to this */ + public OutputStream output; + + + public static void main(String[] args) { + new ArduinoSerial(args); + } + + public ArduinoSerial(String[] args) { + + boolean connected = open_port(); + + if( connected ) { + + while( true ) { + try { + String msg = "abcdefghijklmnopqrstuvwxyz\r\n"; + //{ 'a','b','c','d','e','f','g','i','j'}; + byte[] msgbytes = msg.getBytes(); + //System.out.println("writing..."); + output.write('h'); + output.write('e'); + output.write('l'); + output.write('l'); + output.write('o'); + output.write(msgbytes); + Thread.sleep(100); + } catch (Exception e) { // null pointer or serial port dead + e.printStackTrace(); + } + } + } + else { + logmsg("not connected"); + } + } + + /** + * + */ + private boolean open_port() { + boolean success = false; + try { + Enumeration portList = CommPortIdentifier.getPortIdentifiers(); + while (portList.hasMoreElements()) { + CommPortIdentifier portId = + (CommPortIdentifier) portList.nextElement(); + if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { + //System.out.println("found " + portId.getName()); + if (portId.getName().equals(portname)) { + //logmsg("open_port:"+ portId); + port = (SerialPort)portId.open("arduino serial", 2000); + //port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); + port.disableReceiveThreshold(); + port.enableReceiveTimeout(3000); + port.setSerialPortParams(rate, + SerialPort.DATABITS_8, + SerialPort.STOPBITS_1, + SerialPort.PARITY_NONE); + input = port.getInputStream(); + output = port.getOutputStream(); + //port.setSerialPortParams(rate,databits,stopbits,parity); + port.addEventListener(this); + port.notifyOnDataAvailable(true); + logmsg("port "+portname+" opened successfully"); + success = true; + } + } + } + + } catch (Exception e) { + logmsg("connect failed: "+e); + port = null; + input = null; + output = null; + } + + return success; + } + + + /** + * callback for SerialPortEventListener + * (from processing.serial.Serial) + */ + synchronized public void serialEvent(SerialPortEvent serialEvent) { + try { + logmsg("serialEvent:"+serialEvent+", nvail:"+input.available()); + if (serialEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) { + while (input.available() > 0) { + System.out.print( (char)input.read() ); // HACK + } // while + } + } catch (IOException e) { + logmsg("serialEvent " + e); + } + } + + /** + * just a little debug + */ + public void logmsg(String msg) { + if(debug) + System.err.println("ArduinoSerial("+System.currentTimeMillis()+ + "):"+ msg); + } + + +} diff --git a/ArduinoSerial/makeit.sh b/ArduinoSerial/makeit.sh new file mode 100755 index 0000000..27f7b76 --- /dev/null +++ b/ArduinoSerial/makeit.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# pick one +JAVAC=javac +#JAVAC=/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Commands/javac +#JAVAC=/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Commands/javac + + +$JAVAC -classpath .:rxtxlib/RXTXcomm.jar *.java +#javac -Xlint:unchecked -classpath .:rxtxlib/RXTXcomm.jar *.java diff --git a/ArduinoSerial/runit.sh b/ArduinoSerial/runit.sh new file mode 100755 index 0000000..6c14eb5 --- /dev/null +++ b/ArduinoSerial/runit.sh @@ -0,0 +1,6 @@ +#!/bin/sh + + +java -Djava.library.path=rxtxlib -classpath .:rxtxlib/RXTXcomm.jar $* +#jamvm -Djava.library.path=rxtxlib -classpath .:rxtxlib/RXTXcomm.jar:/opt/local/share/java/glibj.jar $* + diff --git a/ArduinoSerial/rxtxlib/RXTXcomm.jar b/ArduinoSerial/rxtxlib/RXTXcomm.jar new file mode 100644 index 0000000..84e5f01 Binary files /dev/null and b/ArduinoSerial/rxtxlib/RXTXcomm.jar differ diff --git a/ArduinoSerial/rxtxlib/librxtxSerial.jnilib b/ArduinoSerial/rxtxlib/librxtxSerial.jnilib new file mode 100755 index 0000000..b15dfa5 Binary files /dev/null and b/ArduinoSerial/rxtxlib/librxtxSerial.jnilib differ diff --git a/arduino-serial.c b/arduino-serial.c new file mode 100644 index 0000000..0646f23 --- /dev/null +++ b/arduino-serial.c @@ -0,0 +1,236 @@ +/* + * Arduino-serial + * -------------- + * + * A simple command-line example program showing how a computer can + * communicate with an Arduino board. Works on any POSIX system (Mac/Unix/PC) + * + * + * Compile with something like: + * gcc -o arduino-serial arduino-serial.c + * + * Created 5 December 2006 + * Copyleft (c) 2006, Tod E. Kurt, tod@todbot.com + * http://todbot.com/blog/ + * + * + * Updated 8 December 2006: + * Justin McBride discoevered B14400 & B28800 aren't in Linux's termios.h. + * I've included his patch, but commented out for now. One really needs a + * real make system when doing cross-platform C and I wanted to avoid that + * for this little program. Those baudrates aren't used much anyway. :) + * + * Updated 26 December 2007: + * Added ability to specify a delay (so you can wait for Arduino Diecimila) + * Added ability to send a binary byte number + * + * Update 31 August 2008: + * Added patch to clean up odd baudrates from Andy at hexapodia.org + * + */ + +#include /* Standard input/output definitions */ +#include +#include /* Standard types */ +#include /* String function definitions */ +#include /* UNIX standard function definitions */ +#include /* File control definitions */ +#include /* Error number definitions */ +#include /* POSIX terminal control definitions */ +#include +#include + +void usage(void); +int serialport_init(const char* serialport, int baud); +int serialport_writebyte(int fd, uint8_t b); +int serialport_write(int fd, const char* str); +int serialport_read_until(int fd, char* buf, char until); + +void usage(void) { + printf("Usage: arduino-serial -p [OPTIONS]\n" + "\n" + "Options:\n" + " -h, --help Print this help message\n" + " -p, --port=serialport Serial port Arduino is on\n" + " -b, --baud=baudrate Baudrate (bps) of Arduino\n" + " -s, --send=data Send data to Arduino\n" + " -r, --receive Receive data from Arduino & print it out\n" + " -n --num=num Send a number as a single byte\n" + " -d --delay=millis Delay for specified milliseconds\n" + "\n" + "Note: Order is important. Set '-b' before doing '-p'. \n" + " Used to make series of actions: '-d 2000 -s hello -d 100 -r' \n" + " means 'wait 2secs, send 'hello', wait 100msec, get reply'\n" + "\n"); +} + +int main(int argc, char *argv[]) +{ + int fd = 0; + char serialport[256]; + int baudrate = B9600; // default + char buf[256]; + int rc,n; + + if (argc==1) { + usage(); + exit(EXIT_SUCCESS); + } + + /* parse options */ + int option_index = 0, opt; + static struct option loptions[] = { + {"help", no_argument, 0, 'h'}, + {"port", required_argument, 0, 'p'}, + {"baud", required_argument, 0, 'b'}, + {"send", required_argument, 0, 's'}, + {"receive", no_argument, 0, 'r'}, + {"num", required_argument, 0, 'n'}, + {"delay", required_argument, 0, 'd'}, + {NULL, 0, 0, 0} + }; + + while(1) { + opt = getopt_long (argc, argv, "hp:b:s:rn:d:", + loptions, &option_index); + if (opt==-1) break; + switch (opt) { + case '0': break; + case 'd': + n = strtol(optarg,NULL,10); + usleep(n * 1000 ); // sleep milliseconds + break; + case 'h': + usage(); + break; + case 'b': + baudrate = strtol(optarg,NULL,10); + break; + case 'p': + strcpy(serialport,optarg); + fd = serialport_init(optarg, baudrate); + if(fd==-1) return -1; + break; + case 'n': + n = strtol(optarg, NULL, 10); // convert string to number + rc = serialport_writebyte(fd, (uint8_t)n); + if(rc==-1) return -1; + break; + case 's': + strcpy(buf,optarg); + printf("read string '%s'\n", buf); + rc = serialport_write(fd, buf); + if(rc==-1) return -1; + break; + case 'r': + serialport_read_until(fd, buf, '\n'); + printf("read: %s\n",buf); + break; + } + } + + exit(EXIT_SUCCESS); +} // end main + +int serialport_writebyte( int fd, uint8_t b) +{ + int n = write(fd,&b,1); + if( n!=1) + return -1; + return 0; +} + +int serialport_write(int fd, const char* str) +{ + int len = strlen(str); + int n = write(fd, str, len); + if( n!=len ) { + printf("couldn't write whole string\n"); + return -1; + } + return 0; +} + +int serialport_read_until(int fd, char* buf, char until) +{ + char b[1]; + int i=0; + do { + int n = read(fd, b, 1); // read a char at a time + if( n==-1) return -1; // couldn't read + if( n==0 ) { + usleep( 10 * 1000 ); // wait 10 msec try again + continue; + } + buf[i] = b[0]; i++; + } while( b[0] != until ); + + buf[i] = 0; // null terminate the string + return 0; +} + +// takes the string name of the serial port (e.g. "/dev/tty.usbserial","COM1") +// and a baud rate (bps) and connects to that port at that speed and 8N1. +// opens the port in fully raw mode so you can send binary data. +// returns valid fd, or -1 on error +int serialport_init(const char* serialport, int baud) +{ + struct termios toptions; + int fd; + + //fprintf(stderr,"init_serialport: opening port %s @ %d bps\n", + // serialport,baud); + + fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1) { + perror("init_serialport: Unable to open port "); + return -1; + } + + if (tcgetattr(fd, &toptions) < 0) { + perror("init_serialport: Couldn't get term attributes"); + return -1; + } + speed_t brate = baud; // let you override switch below if needed + switch(baud) { + case 4800: brate=B4800; break; + case 9600: brate=B9600; break; +#ifdef B14400 + case 14400: brate=B14400; break; +#endif + case 19200: brate=B19200; break; +#ifdef B28800 + case 28800: brate=B28800; break; +#endif + case 38400: brate=B38400; break; + case 57600: brate=B57600; break; + case 115200: brate=B115200; break; + } + cfsetispeed(&toptions, brate); + cfsetospeed(&toptions, brate); + + // 8N1 + toptions.c_cflag &= ~PARENB; + toptions.c_cflag &= ~CSTOPB; + toptions.c_cflag &= ~CSIZE; + toptions.c_cflag |= CS8; + // no flow control + toptions.c_cflag &= ~CRTSCTS; + + toptions.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines + toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl + + toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw + toptions.c_oflag &= ~OPOST; // make raw + + // see: http://unixwiz.net/techtips/termios-vmin-vtime.html + toptions.c_cc[VMIN] = 0; + toptions.c_cc[VTIME] = 20; + + if( tcsetattr(fd, TCSANOW, &toptions) < 0) { + perror("init_serialport: Couldn't set term attributes"); + return -1; + } + + return fd; +} -- cgit v1.2.3