serial - alex-aleyan/linux_wiki GitHub Wiki

Sources:

https://www.decisivetactics.com/support/view?article=crossover-or-null-modem-vs-straight-through-serial-cable \ http://pinouts.ru/NetworkCables/ethernet_10_100_1000_pinout.shtml \ http://www.tldp.org/HOWTO/html_single/Serial-HOWTO/ \ https://learn.sparkfun.com/tutorials/terminal-basics/all

Establishing Serial Connection Using SCREEN command:

  1. Settings should be:

    115200, 8 bits, no parity, 1 stop.   115-8N1. See sketch above…
    
  2. Next key-stroke can be used to kill the screen session that has frozen:v

    CTRL+A, K, YES to kill
    
  3. Launch serial communication using screen command:

    screen /dev/ttySX baud_rate,cs8|cs7,ixon|-ixon,ixoff|-ixoff,istrip|-istrip
    screen /dev/ttyS0 115200,cs8
    
    /dev/ttySX:         Linux serial port (e.g., /dev/ttyS0 [COM1] )
    baud_rate:          Usually 300, 1200, 9600 or 19200. This affects transmission as well as receive speed.
    cs8 or cs7:         Specify the transmission of eight (or seven) bits per byte.
    ixon or -ixon:      Enables (or disables) software flow-control (CTRL-S/CTRL-Q) for sending data.
    ixoff or -ixoff:    Enables (or disables) software flow-control for receiving data.
    istrip or -istrip:  Clear (or keep) the eight bit in each received byte.
    cstopb or -cstopv:
    
  4. Screen Command Cheat Sheet!

    –ctrl a c           -> cre­ate new win­dow
    –ctrl a A           -> set win­dow name
    –ctrl a w           -> show all win­dow
    –ctrl a 1|2|3|…   -> switch to win­dow n
    –ctrl a ”           -> choose win­dow
    –ctrl a ctrl a      -> switch between win­dow
    –ctrl a d           -> detach win­dow
    –ctrl a ?           -> help
    –ctrl a [           -> start copy, move cur­sor to the copy loca­tion, press ENTER, select the chars, press ENTER to copy the selected char­ac­ters to the buffer
    –ctrl a ]           -> paste from buffer
    
    –screen –DR            -> list of detached screen
    –screen –r PID         -> attach detached screen ses­sion
    –screen –dmS MySes­sion -> start a detached screen ses­sion
    –screen –r MySes­sion   -> attach screen ses­sion with name MySession
    
    –ctrl a S       -> cre­ate split screen
    –ctrl a TAB     -> switch between split screens
    
    –ctrl a Q       -> Kill all regions but the cur­rent one.
    –ctrl a X       -> remove active win­dow from split screen
    –ctrl a O       -> logout active win­dow (dis­able out­put)
    –ctrl a I       -> login active win­dow (enable output)
    

Establishing Serial Connection Using MINICOM command:

  1. Initialize MINICOM by placing this line in your ~/.bashrc (see minicom --help):

    echo 'export MINICOM="-w -m -c on" ' >> ~/.bashrc
    
  2. Go to: minicom -s -> Modem and dialing parameter -> clear content of A and B fields.

    1. Create your own configuration or modify the default one using:

      minicom -s # to configure and save as default
      
  3. Alternatively, create the minicom rc files (in /etc/minirc.host1):

    #set the serial port (on windows it has COM1 name)
    pu port /dev/ttyS1
    #Set the baudrate:
    pu baudrate 115200
    #Set 8 bid word
    pu bits 8
    #no parity:
    pu parity N
    #single stop bit:
    pu stopbits 1  
    #turn off modem initialization strings since the serial connection is not being established over a modem:
    pu minit
    pu mreset
    pu mhangup
    
  4. Launch minicom with default parameters by typing:

    minicom 
    

Establishing Serial Connection via file system:

  • To write to the serial interface

    sudo stty -F /dev/ttyUSB0 -a
    sudo stty -F /dev/ttyUSB0 speed 9600
    echo -e -n 'show interface summary\r' > /dev/ttyUSB0
    echo -e -n '\r' > /dev/ttyUSB0  # send RETURN key
    echo -e -n '\x03' > /dev/ttyUSB0 # send CTRL^C key stroke
    
#!/bin/bash
DEVICE=/dev/ttyUSB0

while true; do
    read -p "> " userString
    if [[ $userString = *[!\ ]* ]]; then
      echo -e -n "$userString\r" > $DEVICE
    else
      echo -e -n ' \r' > $DEVICE                                                
    fi  
done
root@localhost:tty_programming[<1313>]# cat tty1_write.c
#include <stdio.h>   /* Standard input/output definitions */                                                
#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 */

/*
	*  *  * 'open_port()' - Open serial port 1.
	*   *   *
	*    *    * Returns the file descriptor on success or -1 on error.
	*     *     */

int open_port(char *port)
{
int fd; /* File descriptor for the port */

// O_NOCTTY flag tells UNIX the program is not to be the CONTROLLING TERMINAL!
// O_NDELAY flag tells UNIX the program d.n. care what the state the DCD SIGNAL LINE is in.
fd = open( port, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);

  if (fd == -1)
		{
				/*
				*     *     * Could not open the port.
				*         *         */
				perror("open_port: Unable to open /dev/ttyf1 - ");
		}
		else fcntl(fd, F_SETFL, 0);

return (fd);
}

int set_tty_attribs(int fd, unsigned int speed)
{
		struct termios tty_options;

		if (tcgetattr(fd, &tty_options) < 0) {
				printf("Error from tcgetattr: %s\n", strerror(errno));
				return -1;
		}
		
		cfsetospeed(&tty_options, (speed_t) speed);
		//cfsetospeed(&tty_options, B115200);
		cfsetispeed(&tty_options, (speed_t) speed);
		//cfsetispeed(&tty_options, B115200);
		
		// ignore modem controls; insures the program does not become the owner of 
		// the port, subject to sporatic job control and hangup signals.
		tty_options.c_cflag |= (CLOCAL | CREAD); 

		tty_options.c_cflag &= ~CSIZE;
		tty_options.c_cflag |= CS8;

		//tty_options.c_cflag &= ~PARENB;
  //tty_options.c_cflag &= ~CSTOPB;

		//tty_options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
		//tty_options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
		//tty_options.c_oflag &= ~OPOST;

//		tty_options.c_cc[VMIN] = 1;
//		tty_options.c_cc[VTIME] = 1;

		if (tcsetattr(fd, TCSANOW, &tty_options) != 0) {
				printf("Error from tcsetattr: %s\n", strerror(errno));
				return -1;
		}

		return 0;
}

void set_mincount(int fd, int mcount)
{
		struct termios tty;

		if (tcgetattr(fd, &tty) < 0) {
				printf("Error tcgetattr: %s\n", strerror(errno));
				return -1;
		}

		tty.c_cc[VMIN] = mcount ? 1 : 0;
		tty.c_cc[VTIME] = 5;        /* half second timer */

		if (tcsetattr(fd, TCSANOW, &tty) < 0) printf("Error tcsetattr: %s\n", strerror(errno));
}

#define CNUM 23
int main(int argc, char **argv)
{
		char *portname = "/dev/ttyUSB0";
		int fd;
		int msgLen;
		unsigned char buf[512];

		if (argc >= 2) memcpy(buf, argv[1], strlen(argv[1])+1);
		//printf("After memcpy dest = %s\n", buf);
		
		fd = open_port( portname );

		set_tty_attribs(fd, B9600);

 	msgLen = write( fd, buf, strlen(buf)+1);
 	if (msgLen != CNUM) {
				printf("Error from write: %d, %d\n", msgLen, errno);
		}
		
		tcdrain(fd);

return 0;
}
  • To read the serial interface:
cat /dev/ttyUSB0
#!/bin/bash
DEVICE='/dev/ttyUSB0'
BAUDRATE=9600

stty -F $DEVICE $BAUDRATE
cat $DEVICE
  • Reading/Writing to serial interface via ''SCREEN'' command:
sudo screen /dev/ttyUSB0 115200
root@localhost:tty_programming[<1376>]# cat tty1_read.c
#include <stdio.h>   /* Standard input/output definitions */                                                
#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 */

/*
	*  *  * 'open_port()' - Open serial port 1.
	*   *   *
	*    *    * Returns the file descriptor on success or -1 on error.
	*     *     */

int open_port(char *port)
{
int fd; /* File descriptor for the port */

// O_NOCTTY flag tells UNIX the program is not to be the CONTROLLING TERMINAL!
// O_NDELAY flag tells UNIX the program d.n. care what the state the DCD SIGNAL LINE is in.
fd = open( port, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);

  if (fd == -1)
		{
				/*
				*     *     * Could not open the port.
				*         *         */
				perror("open_port: Unable to open /dev/ttyf1 - ");
		}
		else fcntl(fd, F_SETFL, 0);

return (fd);
}

int set_tty_attribs(int fd, unsigned int speed)
{
		struct termios tty_options;

		if (tcgetattr(fd, &tty_options) < 0) {
				printf("Error from tcgetattr: %s\n", strerror(errno));
				return -1;
		}
		
		cfsetospeed(&tty_options, (speed_t) speed);
		//cfsetospeed(&tty_options, B115200);
		cfsetispeed(&tty_options, (speed_t) speed);
		//cfsetispeed(&tty_options, B115200);
		
		// ignore modem controls; insures the program does not become the owner of 
		// the port, subject to sporatic job control and hangup signals.
		tty_options.c_cflag |= (CLOCAL | CREAD); 

		tty_options.c_cflag &= ~CSIZE;
		tty_options.c_cflag |= CS8;

		//tty_options.c_cflag &= ~PARENB;
  //tty_options.c_cflag &= ~CSTOPB;

		//tty_options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
		//tty_options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
		//tty_options.c_oflag &= ~OPOST;

//		tty_options.c_cc[VMIN] = 1;
//		tty_options.c_cc[VTIME] = 1;

		if (tcsetattr(fd, TCSANOW, &tty_options) != 0) {
				printf("Error from tcsetattr: %s\n", strerror(errno));
				return -1;
		}

		return 0;
}

void set_mincount(int fd, int mcount)
{
		struct termios tty;

		if (tcgetattr(fd, &tty) < 0) {
				printf("Error tcgetattr: %s\n", strerror(errno));
				return -1;
		}

		tty.c_cc[VMIN] = mcount ? 1 : 0;
		tty.c_cc[VTIME] = 5;        /* half second timer */

		if (tcsetattr(fd, TCSANOW, &tty) < 0) printf("Error tcsetattr: %s\n", strerror(errno));
}

#define CNUM 23
int main(int argc, char **argv)
{
		char *portname = "/dev/ttyUSB0";
		int fd;
		int msgLen;

		
		fd = open_port( portname );
		set_tty_attribs( fd, B9600 );

		
		tcdrain(fd);

		//simple noncanonical input 
		do {
				unsigned char buf[512];
				int rdlen;

				rdlen = read(fd, buf, sizeof(buf) - 1); 
				if (rdlen > 0) {
#ifdef DISPLAY_STRING
								buf[rdlen] = 0;
								//printf("Read %d: \"%s\"\n", rdlen, &buf[0]);
								printf("%s\n", buf);
#else //display hex                                                              
								unsigned char   *p; 
								printf("Read %d:", rdlen);
								for (p = buf; rdlen-- > 0; p++)
										printf(" 0x%x", *p);
										printf("\n");
#endif
				}
				else if (rdlen < 0) {
						printf("Error from read: %d: %s\n", rdlen, strerror(errno));
				}
				// repeat read to get full message 
		}
		while (1);
		
		//fcntl(fd, F_SETFL, 0);
return 0;
}

- Using custom bash script (make sure to copy your .Xauthority file to roots home directory) 
#!/bin/bash
DEVICE='/dev/ttyUSB0'
BAUDRATE=9600

echo $PWD

stty -F $DEVICE $BAUDRATE
gnome-terminal --title=RS232-TX -e "$PWD/serialWrite.sh" &
gnome-terminal --title=RS232-RX -e "$PWD/serialRead.sh" &
⚠️ **GitHub.com Fallback** ⚠️