{"id":482,"date":"2012-10-17T12:42:15","date_gmt":"2012-10-17T12:42:15","guid":{"rendered":"https:\/\/raspberry-projects.com\/pi\/?p=482"},"modified":"2019-05-22T13:35:03","modified_gmt":"2019-05-22T13:35:03","slug":"using-the-uart","status":"publish","type":"post","link":"https:\/\/raspberry-projects.com\/pi\/programming-in-c\/uart-serial-port\/using-the-uart","title":{"rendered":"Using the UART"},"content":{"rendered":"\n<p>\nIf you are running Raspbian or similar then the UART will be used as a serial console. &nbsp;Using a suitable cable, such as the&nbsp;<a href=\"http:\/\/uk.farnell.com\/ftdi\/ttl-232r-3v3-we\/cable-usb-ttl-ser-conv-wire-end\/dp\/1740365\" target=\"_blank\" rel=\"noopener noreferrer\">TTL-232R-3V3-WE<\/a>, you can connect it to your PC and using some simple terminal software set to 115200-8-N-1 use the command line interface to the Raspberry Pi&nbsp;in the same way as if you we&#8217;re using a keyboard and screen connected to it. &nbsp;However that&#8217;s no use if you want to use the UART interface for your own application&nbsp;running on the RPi.\n<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Turning off the UART&nbsp;functioning as a serial&nbsp;console<\/h4>\n\n\n\n<p>See <a href=\"https:\/\/raspberry-projects.com\/pi\/pi-operating-systems\/raspbian\/io-pins-raspbian\/uart-pins\">here<\/a>. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Using The UART In Your C Code<\/h4>\n\n\n\n<p>(This is based on the example code&nbsp;<a href=\"http:\/\/www.raspberrypi.org\/phpBB3\/viewtopic.php?t=7500&amp;p=93257\" target=\"_blank\" rel=\"noopener noreferrer\">given here<\/a>). <\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Headers required<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n#include &lt;unistd.h>\t\t\t\/\/Used for UART\n#include &lt;fcntl.h>\t\t\t\/\/Used for UART\n#include &lt;termios.h>\t\t\/\/Used for UART<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"> Setting Up The UART<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>\t\/\/-------------------------\n\t\/\/----- SETUP USART 0 -----\n\t\/\/-------------------------\n\t\/\/At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively\n\tint uart0_filestream = -1;\n\t\n\t\/\/OPEN THE UART\n\t\/\/The flags (defined in fcntl.h):\n\t\/\/\tAccess modes (use 1 of these):\n\t\/\/\t\tO_RDONLY - Open for reading only.\n\t\/\/\t\tO_RDWR - Open for reading and writing.\n\t\/\/\t\tO_WRONLY - Open for writing only.\n\t\/\/\n\t\/\/\tO_NDELAY \/ O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status\n\t\/\/\t\t\t\t\t\t\t\t\t\t\tif there is no input immediately available (instead of blocking). Likewise, write requests can also return\n\t\/\/\t\t\t\t\t\t\t\t\t\t\timmediately with a failure status if the output can't be written immediately.\n\t\/\/\n\t\/\/\tO_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.\n\tuart0_filestream = open(\"\/dev\/serial0\", O_RDWR | O_NOCTTY | O_NDELAY);\t\t\/\/Open in non blocking read\/write mode\n\tif (uart0_filestream == -1)\n\t{\n\t\t\/\/ERROR - CAN'T OPEN SERIAL PORT\n\t\tprintf(\"Error - Unable to open UART.  Ensure it is not in use by another application\\n\");\n\t}\n\t\n\t\/\/CONFIGURE THE UART\n\t\/\/The flags (defined in \/usr\/include\/termios.h - see http:\/\/pubs.opengroup.org\/onlinepubs\/007908799\/xsh\/termios.h.html):\n\t\/\/\tBaud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000\n\t\/\/\tCSIZE:- CS5, CS6, CS7, CS8\n\t\/\/\tCLOCAL - Ignore modem status lines\n\t\/\/\tCREAD - Enable receiver\n\t\/\/\tIGNPAR = Ignore characters with parity errors\n\t\/\/\tICRNL - Map CR to NL on input (Use for ASCII comms where you want to auto correct end of line characters - don't use for bianry comms!)\n\t\/\/\tPARENB - Parity enable\n\t\/\/\tPARODD - Odd parity (else even)\n\tstruct termios options;\n\ttcgetattr(uart0_filestream, &amp;options);\n\toptions.c_cflag = B9600 | CS8 | CLOCAL | CREAD;\t\t\/\/&lt;Set baud rate\n\toptions.c_iflag = IGNPAR;\n\toptions.c_oflag = 0;\n\toptions.c_lflag = 0;\n\ttcflush(uart0_filestream, TCIFLUSH);\n\ttcsetattr(uart0_filestream, TCSANOW, &amp;options);<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Transmitting Bytes<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>\t\/\/----- TX BYTES -----\n\tunsigned char tx_buffer[20];\n\tunsigned char *p_tx_buffer;\n\t\n\tp_tx_buffer = &amp;tx_buffer[0];\n\t*p_tx_buffer++ = 'H';\n\t*p_tx_buffer++ = 'e';\n\t*p_tx_buffer++ = 'l';\n\t*p_tx_buffer++ = 'l';\n\t*p_tx_buffer++ = 'o';\n\t\n\tif (uart0_filestream != -1)\n\t{\n\t\tint count = write(uart0_filestream, &amp;tx_buffer[0], (p_tx_buffer - &amp;tx_buffer[0]));\t\t\/\/Filestream, bytes to write, number of bytes to write\n\t\tif (count &lt; 0)\n\t\t{\n\t\t\tprintf(\"UART TX error\\n\");\n\t\t}\n\t}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Transmit string function<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>\tuart_tx_string(\"Hello2\");\n\n\n\/\/************************************\n\/\/************************************\n\/\/********** UART TX STRING **********\n\/\/************************************\n\/\/************************************\nvoid uart_tx_string (string tx_string)\n{\n\tif (uart0_filestream != -1)\n\t\twrite(uart0_filestream, (char*)tx_string.c_str(), tx_string.length());\t\t\/\/Filestream, bytes to write, number of bytes to write\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Receiving Bytes<\/h5>\n\n\n\n<p>Because&nbsp;O_NDELAY has been used this will exit if there are no receive bytes waiting (non blocking read), so if you want to hold waiting for input simply put this in a while loop <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\t\/\/----- CHECK FOR ANY RX BYTES -----\n\tif (uart0_filestream != -1)\n\t{\n\t\t\/\/ Read up to 255 characters from the port if they are there\n\t\tunsigned char rx_buffer[256];\n\t\tint rx_length = read(uart0_filestream, (void*)rx_buffer, 255);\t\t\/\/Filestream, buffer to store in, number of bytes to read (max)\n\t\tif (rx_length &lt; 0)\n\t\t{\n\t\t\t\/\/An error occured (will occur if there are no bytes)\n\t\t}\n\t\telse if (rx_length == 0)\n\t\t{\n\t\t\t\/\/No data waiting\n\t\t}\n\t\telse\n\t\t{\n\t\t\t\/\/Bytes received\n\t\t\trx_buffer[rx_length] = '\\0';\n\t\t\tprintf(\"%i bytes read : %s\\n\", rx_length, rx_buffer);\n\t\t}\n\t}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Closing the UART if no longer needed<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>\t\/\/----- CLOSE THE UART -----\n\tclose(uart0_filestream);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Using minicom&nbsp;on the UART<\/h4>\n\n\n\n<p>Install minicom: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get install minicom<\/code><\/pre>\n\n\n\n<p>\nRunning minicom:\n<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>minicom -b 115200 -o -D \/dev\/serial0<\/code><\/pre>\n\n\n\n<p>To test the UART is working you can simply link the TX and RX pins to each other and verify minicom receives what you type. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Troubleshooting UART Problems<\/h4>\n\n\n\n<p>The above code works (we&#8217;ve used it for TX and RX). If you can&#8217;t get to to work for you and you&#8217;ve been through the steps to release the UART from being used for the console try the following: <\/p>\n\n\n\n<h5 class=\"wp-block-heading\">UART Name<\/h5>\n\n\n\n<p> The SoCs used on the Raspberry Pis have two built-in UARTs, a PL011 and a mini UART.<\/p>\n\n\n\n<p>\/dev\/serial0 is a symlink which always refers to the primary UART (if enabled).   This is the UART assigned to the Linux console (which depends on the Raspberry Pi model).<\/p>\n\n\n\n<p>\/dev\/serial1 is a symlink which always refers to the secondary UART (if enabled).<\/p>\n\n\n\n<p>\/dev\/ttyS0 refers to the mini UART  (Primary UART on RPi&#8217;s with wireless\/Bluetooth module, e.g. RPi3, RPi Zero W)  <\/p>\n\n\n\n<p>\/dev\/ttyAMA0 refers to the PL011 (Primary UART on RPi&#8217;s without wireless\/Bluetooth module)<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Permissions<\/h5>\n\n\n\n<p>This command will set read and write access permissions&nbsp;for all users on the UART &#8211; it shouldn&#8217;t be needed but can be used just to be sure there is not a permissions problem: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chmod a+rw \/dev\/serial0<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Baud Rate Error<\/h5>\n\n\n\n<p>Try using a slower BAUD rate (or a single 0xFF byte which only has the start bit low) and see if it works. &nbsp;We had a problem using 115k2 baud rate where our microcontroller communicating with the RPi could hit 113636baud or 119047baud. &nbsp;113636baud had the lowest error margin so we used it and TX from the RPi being received by the microcontroller&nbsp;worked fine. &nbsp;However when transmitting to the RPi nothing was ever received. Changing the microcontroller to use 119047baud caused RX to work. We then tested the RPi&nbsp;transmitting a byte of 0x00&nbsp;and measured the low state on a scope we got 78uS, showing an actual baud rate of 115384 from the RPi (8bits + the start bit all low). &nbsp;This was odd as 113636baud still had to lower error margin but that was the finding. <\/p>\n\n\n\n<p>Are you over or under clocking the RPi? If so do you need to adjust the baud rate to compensate for this? <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">General UART Programming Resources<\/h4>\n\n\n\n<p><a href=\"http:\/\/www.tldp.org\/HOWTO\/Serial-Programming-HOWTO\/x115.html\">http:\/\/www.tldp.org\/HOWTO\/Serial-Programming-HOWTO\/x115.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you are running Raspbian or similar then the UART will be used as a serial console. &nbsp;Using a suitable cable, such as the&nbsp;TTL-232R-3V3-WE, you can connect it to your PC and using some simple terminal software set to 115200-8-N-1 use the command line interface to the Raspberry Pi&nbsp;in the same way as if you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[],"class_list":["post-482","post","type-post","status-publish","format-standard","hentry","category-uart-serial-port"],"_links":{"self":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/482","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/comments?post=482"}],"version-history":[{"count":37,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/482\/revisions"}],"predecessor-version":[{"id":3065,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/posts\/482\/revisions\/3065"}],"wp:attachment":[{"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/media?parent=482"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/categories?post=482"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/raspberry-projects.com\/pi\/wp-json\/wp\/v2\/tags?post=482"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}