From 6ca74738181b172fa0fcafa2b3676b5c32b4d91e Mon Sep 17 00:00:00 2001 From: Gentoo Date: Sat, 27 Mar 2021 10:51:36 +1100 Subject: added option for unlimited reads with no timeout --- arduino-serial-lib.c | 39 ++++++++++++++++++++++++++++++--------- arduino-serial-lib.h | 3 ++- arduino-serial.c | 29 ++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/arduino-serial-lib.c b/arduino-serial-lib.c index 39461ce..360e747 100644 --- a/arduino-serial-lib.c +++ b/arduino-serial-lib.c @@ -25,15 +25,15 @@ int serialport_init(const char* serialport, int baud) { struct termios toptions; int fd; - + //fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY); fd = open(serialport, O_RDWR | O_NONBLOCK ); - + if (fd == -1) { perror("serialport_init: Unable to open port "); return -1; } - + //int iflags = TIOCM_DTR; //ioctl(fd, TIOCMBIS, &iflags); // turn on DTR //ioctl(fd, TIOCMBIC, &iflags); // turn off DTR @@ -80,7 +80,7 @@ int serialport_init(const char* serialport, int baud) toptions.c_cc[VMIN] = 0; toptions.c_cc[VTIME] = 0; //toptions.c_cc[VTIME] = 20; - + tcsetattr(fd, TCSANOW, &toptions); if( tcsetattr(fd, TCSAFLUSH, &toptions) < 0) { perror("init_serialport: Couldn't set term attributes"); @@ -122,26 +122,47 @@ int serialport_read_until(int fd, char* buf, char until, int buf_max, int timeou { char b[1]; // read expects an array, so we give it a 1-byte array int i=0; - do { + 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( 1 * 1000 ); // wait 1 msec try again - timeout--; + --timeout; if( timeout==0 ) return -2; continue; } -#ifdef SERIALPORTDEBUG + +#ifdef SERIALPORTDEBUG printf("serialport_read_until: i=%d, n=%d b='%c'\n",i,n,b[0]); // debug #endif - buf[i] = b[0]; - i++; + buf[i] = b[0]; + ++i; } while( b[0] != until && i < buf_max && timeout>0 ); buf[i] = 0; // null terminate the string return 0; } +//return input forever +int serialport_read_unlimited(int fd, char* buf, char until, int buf_max) +{ + char b[1]; // read expects an array, so we give it a 1-byte array + 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( 1 * 1000 ); // wait 1 msec try again + continue; + } + buf[i] = b[0]; + ++i; + } while( b[0] != until && i < buf_max ); + + buf[i] = 0; // null terminate the string + return 0; +} + // int serialport_flush(int fd) { diff --git a/arduino-serial-lib.h b/arduino-serial-lib.h index a0731e1..aa43eb7 100644 --- a/arduino-serial-lib.h +++ b/arduino-serial-lib.h @@ -8,13 +8,14 @@ #ifndef __ARDUINO_SERIAL_LIB_H__ #define __ARDUINO_SERIAL_LIB_H__ -#include // Standard types +#include // Standard types int serialport_init(const char* serialport, int baud); int serialport_close(int fd); 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, int buf_max,int timeout); +int serialport_read_unlimited(int fd, char* buf, char until, int buf_max); int serialport_flush(int fd); #endif diff --git a/arduino-serial.c b/arduino-serial.c index 3f5987b..bf57f2b 100644 --- a/arduino-serial.c +++ b/arduino-serial.c @@ -43,6 +43,9 @@ * Added --timeout option * Added -q/-quiet option * + * Update XX April 2019 + * Added --receive_u option + * Fixed output issues */ #include // Standard input/output definitions @@ -67,6 +70,7 @@ void usage(void) " -S, --sendline=string Send string with newline to Arduino\n" " -i --stdinput Use standard input\n" " -r, --receive Receive string from Arduino & print it out\n" + " -R, --receive_u Same as --receive, but no timeout\n" " -n --num=num Send a number as a single byte\n" " -F --flush Flush serial port buffers for fresh reading\n" " -d --delay=millis Delay for specified milliseconds\n" @@ -121,11 +125,12 @@ int main(int argc, char *argv[]) {"eolchar", required_argument, 0, 'e'}, {"timeout", required_argument, 0, 't'}, {"quiet", no_argument, 0, 'q'}, - {NULL, 0, 0, 0} + {"receive_u", no_argument, 0, 'R'}, + {NULL, 0, 0, 0} }; while(1) { - opt = getopt_long (argc, argv, "hp:b:s:S:i:rFn:d:qe:t:", + opt = getopt_long (argc, argv, "hp:b:s:S:i:rRFn:d:qe:t:", loptions, &option_index); if (opt==-1) break; switch (opt) { @@ -188,17 +193,31 @@ int main(int argc, char *argv[]) if(rc==-1) error("error writing"); break; case 'r': + if( fd == -1 ) error("serial port not opened"); memset(buf,0,buf_max); // serialport_read_until(fd, buf, eolchar, buf_max, timeout); - if( !quiet ) printf("read string:"); - printf("%s\n", buf); - break; + printf("%s", buf); + fflush(stdout); + break; case 'F': if( fd == -1 ) error("serial port not opened"); if( !quiet ) printf("flushing receive buffer\n"); serialport_flush(fd); break; + //we just want to scan for input constantly with no timeout + case 'R': + while(1) + { + if( fd == -1 ) {error("serial port not opened"); break;} + memset(buf,0,buf_max); // + serialport_read_unlimited(fd, buf, eolchar, buf_max); + //'printf("%s\n", buf)' places *two* newlines after output and output cannot be redirected. + //remove DOS newline. NOTE; only one character output is supported like this + printf("%s", buf); + fflush(stdout); + } + break; } } -- cgit v1.2.3