#include /* Terminal I/O support */ #include /* Error number definitions */ #include /* String function definitions */ #include /* Standard I/O */ #include /* File descriptor manipulation */ #define DEVICE "/dev/ttyUSB0" int open_port ( char* device ) { int f; struct termios tio; f = open ( DEVICE, O_RDWR | O_NOCTTY ); // Not using O_NDELAY, that caused ERR11: temp unavail. if ( f < 0 ) { perror(DEVICE); return(-1); } // Fixed settings: 9600bps, 8 bits, // no parity, no flow-control, // local mode, read enabled tio.c_cflag = B9600 | CS8 | CLOCAL | CREAD; tio.c_cflag &= ~CRTSCTS; tio.c_iflag = IGNPAR; tio.c_oflag = 0; tio.c_lflag = 0; // Non-canonical read, no other options. tio.c_cc[VMIN] = 3; // Expect 3 characters, always. tio.c_cc[VTIME] = 60; // Wait for a max of 6 seconds tcsetattr(f,TCSANOW,&tio); // Apply this now. return f; } int send_cmd ( int fd, char cmd ) { int res; char buf[7]; char status; tcflush(fd, TCIFLUSH); // Flush the serial input buffer. res = write( fd, &cmd , 1 ); // Send the command to the device if ( res < 0 ) return -1; // and return on failure. res = read( fd, buf, 5 ); if ( res < 0 ) { printf("SERIAL read error %d: %s\n", errno, strerror(errno)); return -1; } if ( res == 0 ) { printf ("Null read\n"); return -1; } buf[res] = 0x00; // A response is supposed to be precisely three characters. if ( res != 3 ) { return -1; } // And the first is supposed to be an echo of the given command. if ( buf[0] != cmd ) { printf("Error: echoed command not correct\n"); return -1; } // The second is (a ':' is ignored, and the third is checked. // The only valid responses are Locked, Open and Moving. status = buf[2]; if ( (status == 'O') || (status == 'L') || (status == 'M') ) return status; else return -1; } int get_state ( int fd ) { return send_cmd( fd, 's'); // Yashure. KISS } int set_state ( int fd, int state ) { int res; switch ( state ) { case 0: res = send_cmd ( fd, 'o'); break; case 1: res = send_cmd ( fd, 'l'); break; } if ( (res != 'L') && ( res != 'O' ) ) return -1; // FAIL // And, yes, I will call a status "Moving" a failed state-change attempt return 0; } int main ( int argc, char** argv ) { int fd; int res; int c; char buf[255]; fd = open_port( DEVICE ); if ( fd < 0 ) { perror(DEVICE); return(-1); } printf("Enter command character, followed by enter/return\n"); printf("Valid commands are:\n l - Lock\n o - Open \n s - Status\n i - Invalid simulation\n"); printf("ESC Enter exits"); printf("rdy>"); for(;;) { res = getchar(); if ( res == 10 ) continue; if ( res == 27 ) return 1; switch( res ) { case 'l': printf("Locking...\n"); if ( set_state( fd, 1 ) ) printf ( "set_state() failed\n"); break; case 'o': printf("Opening...\n"); if ( set_state( fd, 0 ) ) printf ( "set_state() failed\n"); break; case 's': printf("Requesting status...\n"); res = get_state( fd ); switch ( res ) { case 'O': printf("Open\n"); break; case 'L': printf("Locked\n"); break; case 'M': printf("Moving\n"); break; default: printf("Unknown status %d\n", res); } break; case 'i': printf("Sending invalid command...\n"); res = send_cmd( fd, (char)res ); printf("Back from attempt. Got %d back\n", res); default: break; } printf("rdy>"); } }