summaryrefslogtreecommitdiffstats
path: root/arduino-serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'arduino-serial.c')
-rw-r--r--arduino-serial.c201
1 files changed, 67 insertions, 134 deletions
diff --git a/arduino-serial.c b/arduino-serial.c
index 0646f23..3f3f35f 100644
--- a/arduino-serial.c
+++ b/arduino-serial.c
@@ -1,5 +1,5 @@
/*
- * Arduino-serial
+ * arduino-serial
* --------------
*
* A simple command-line example program showing how a computer can
@@ -7,9 +7,14 @@
*
*
* Compile with something like:
- * gcc -o arduino-serial arduino-serial.c
+ * gcc -o arduino-serial arduino-serial-lib.c arduino-serial.c
+ * or use the included Makefile
*
- * Created 5 December 2006
+ * Mac: make sure you have Xcode installed
+ * Windows: try MinGW to get GCC
+ *
+ *
+ * Originally created 5 December 2006
* Copyleft (c) 2006, Tod E. Kurt, tod@todbot.com
* http://todbot.com/blog/
*
@@ -27,54 +32,64 @@
* Update 31 August 2008:
* Added patch to clean up odd baudrates from Andy at hexapodia.org
*
+ * Update 6 April 2012:
+ * Split into a library and app parts
+ *
*/
-#include <stdio.h> /* Standard input/output definitions */
+#include <stdio.h> // Standard input/output definitions
#include <stdlib.h>
-#include <stdint.h> /* Standard types */
-#include <string.h> /* String function definitions */
-#include <unistd.h> /* UNIX standard function definitions */
-#include <fcntl.h> /* File control definitions */
-#include <errno.h> /* Error number definitions */
-#include <termios.h> /* POSIX terminal control definitions */
-#include <sys/ioctl.h>
+#include <stdint.h>
+#include <string.h> // String function definitions
#include <getopt.h>
-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);
+#include "arduino-serial-lib.h"
+
+
+const int buf_max = 256;
-void usage(void) {
+//
+void usage(void)
+{
printf("Usage: arduino-serial -p <serialport> [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"
+ " -s, --send=string Send string to Arduino\n"
+ " -S, --sendline=string Send string with newline to Arduino\n"
+ " -r, --receive Receive string from Arduino & print it out\n"
" -n --num=num Send a number as a single byte\n"
+ " -F --flush Flush the serial port buffers for fresh reading\n"
" -d --delay=millis Delay for specified milliseconds\n"
+ " -q --quiet Don't print out as much info\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");
+ exit(EXIT_SUCCESS);
+}
+
+//
+void error(char* msg)
+{
+ fprintf(stderr, "%s\n",msg);
+ exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
- int fd = 0;
- char serialport[256];
- int baudrate = B9600; // default
- char buf[256];
+ int fd = -1;
+ char serialport[buf_max];
+ int baudrate = 9600; // default
+ char buf[buf_max];
int rc,n;
+ char quiet=0;
if (argc==1) {
usage();
- exit(EXIT_SUCCESS);
}
/* parse options */
@@ -84,20 +99,27 @@ int main(int argc, char *argv[])
{"port", required_argument, 0, 'p'},
{"baud", required_argument, 0, 'b'},
{"send", required_argument, 0, 's'},
+ {"sendline", required_argument, 0, 'S'},
{"receive", no_argument, 0, 'r'},
+ {"flush", no_argument, 0, 'F'},
{"num", required_argument, 0, 'n'},
{"delay", required_argument, 0, 'd'},
+ {"quiet", no_argument, 0, 'q'},
{NULL, 0, 0, 0}
};
while(1) {
- opt = getopt_long (argc, argv, "hp:b:s:rn:d:",
+ opt = getopt_long (argc, argv, "hp:b:s:S:rFn:d:q",
loptions, &option_index);
if (opt==-1) break;
switch (opt) {
case '0': break;
+ case 'q':
+ quiet = 1;
+ break;
case 'd':
n = strtol(optarg,NULL,10);
+ if( !quiet ) printf("sleep %d millisecs\n",n);
usleep(n * 1000 ); // sleep milliseconds
break;
case 'h':
@@ -109,128 +131,39 @@ int main(int argc, char *argv[])
case 'p':
strcpy(serialport,optarg);
fd = serialport_init(optarg, baudrate);
- if(fd==-1) return -1;
+ if( fd==-1 ) error("couldn't open port");
+ serialport_flush(fd);
break;
case 'n':
+ if( fd == -1 ) error("serial port not opened");
n = strtol(optarg, NULL, 10); // convert string to number
rc = serialport_writebyte(fd, (uint8_t)n);
- if(rc==-1) return -1;
+ if(rc==-1) error("error writing");
break;
+ case 'S':
case 's':
- strcpy(buf,optarg);
- printf("read string '%s'\n", buf);
+ if( fd == -1 ) error("serial port not opened");
+ sprintf(buf, (opt=='S' ? "%s\n" : "%s"), optarg);
+
+ if( !quiet ) printf("send string:%s\n", buf);
rc = serialport_write(fd, buf);
- if(rc==-1) return -1;
+ if(rc==-1) error("error writing");
break;
case 'r':
- serialport_read_until(fd, buf, '\n');
- printf("read: %s\n",buf);
+ if( fd == -1 ) error("serial port not opened");
+ memset(buf,0,buf_max); //
+ serialport_read_until(fd, buf, '\n', buf_max);
+ if( !quiet ) printf("read string:");
+ printf("%s\n", buf);
+ break;
+ case 'F':
+ if( fd == -1 ) error("serial port not opened");
+ serialport_flush(fd);
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;
-}