{"id":52378,"date":"2026-11-01T10:51:04","date_gmt":"2026-11-01T10:51:04","guid":{"rendered":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/"},"modified":"2026-11-01T10:51:04","modified_gmt":"2026-11-01T10:51:04","slug":"uart-and-serial","status":"publish","type":"siratek_tutorial","link":"https:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/","title":{"rendered":"UART and Serial Links"},"content":{"rendered":"<body><p><\/p>\n<h2>What this covers<\/h2>\n<p>The third bus, and the oldest. I2C and SPI were designed for chips on one board; a UART link is two wires between two independent devices, each with its own idea of the time.<\/p>\n<p>It is how the Bluetooth module, the GPS receiver and the SMS module all talk to an Arduino, and it is the same mechanism as the serial monitor you have been using since your first sketch. Those two facts collide on an Uno in a way that catches everybody once.<\/p>\n<h2>Before you begin<\/h2>\n<p>Nothing to buy. <em>Seeing What Your Program Is Doing<\/em> and <em>SPI, Faster and More Wires<\/em> are the pages either side of this one.<\/p>\n<h2>How it works<\/h2>\n<p>Two wires, crossed:<\/p>\n<table>\n<thead>\n<tr>\n<th>Wire<\/th>\n<th>Means<\/th>\n<th>Goes to<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>TX<\/code><\/td>\n<td>Transmit<\/td>\n<td>The <strong>other<\/strong> device\u2019s <code>RX<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>RX<\/code><\/td>\n<td>Receive<\/td>\n<td>The <strong>other<\/strong> device\u2019s <code>TX<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>That crossing is the thing to remember.<\/strong> I2C\u2019s <code>SDA<\/code> goes to <code>SDA<\/code>; SPI\u2019s <code>MOSI<\/code> goes to <code>MOSI<\/code>; UART\u2019s <code>TX<\/code> goes to <code>RX<\/code>. Wiring <code>TX<\/code> to <code>TX<\/code> connects two outputs together and nothing is ever received.<\/p>\n<p>There is no clock wire. That is the whole design and the source of everything else on this page.<\/p>\n<figure class=\"siratek-tutorial-figure\"><img decoding=\"async\" src=\"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/uart-and-serial-crossing.svg\" alt=\"A UART link with transmit crossing to receive in both directions and no clock wire, and the Uno's single hardware port on pins 0 and 1 already carrying the USB serial monitor\" loading=\"lazy\"><figcaption>TX goes to RX. There is no clock, so both ends must already agree on the speed.<\/figcaption><\/figure>\n<h3>No clock means both ends must agree in advance<\/h3>\n<p>With no clock to follow, the receiver has to know how fast bits will arrive before any arrive. It starts its own timer when the line first drops, and samples at intervals it decides.<\/p>\n<p>So both ends must be set to the same <strong>baud rate<\/strong> \u2014 bits per second. 9600 means a bit every 104 microseconds, and the receiver counts in those.<\/p>\n<p>Get it wrong and you do not get an error. You get <strong>plausible-looking rubbish<\/strong>, because the receiver is faithfully sampling a signal at the wrong moments. Characters like <code>\u00ff<\/code> and <code>?<\/code> and random punctuation are the signature, and if you see them the first thing to check is the number in <code>Serial.begin()<\/code> against the number in the monitor\u2019s corner.<\/p>\n<h3>Common rates, and what they are for<\/h3>\n<table>\n<thead>\n<tr>\n<th>Rate<\/th>\n<th>Where it turns up<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>9600<\/td>\n<td>The library\u2019s default, and most modules out of the box<\/td>\n<\/tr>\n<tr>\n<td>38400<\/td>\n<td>HC-05 modules in command mode<\/td>\n<\/tr>\n<tr>\n<td>57600<\/td>\n<td>Some GPS receivers<\/td>\n<\/tr>\n<tr>\n<td>115200<\/td>\n<td>ESP32 and ESP8266 boot messages, fast logging<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Faster is not better here. At 115200 on a long wire, or through a breadboard with poor contacts, errors appear that 9600 would not have produced. Use the rate the module wants, and raise it only when you need the throughput.<\/p>\n<h2>The Uno has exactly one UART, and the USB cable is using it<\/h2>\n<p>This is the paragraph the page exists for.<\/p>\n<p><code>D0<\/code> and <code>D1<\/code> are the ATmega328P\u2019s hardware serial pins. They are <strong>also<\/strong> wired to the USB chip that carries the serial monitor. One UART, two jobs.<\/p>\n<p>The consequences are immediate and confusing if you have not been told:<\/p>\n<ul>\n<li><strong>Anything plugged into <code>D0<\/code> and <code>D1<\/code> fights the USB connection.<\/strong> Both talk at once and both are corrupted.<\/li>\n<li><strong>Uploading a sketch fails<\/strong> while a module is connected to those pins, because the upload is itself a serial conversation. The error mentions <code>avrdude<\/code> and <code>stk500<\/code> and says nothing about your wiring.<\/li>\n<li><strong>The serial monitor shows the module\u2019s output mixed with your own prints<\/strong>, which looks like a software fault and is not.<\/li>\n<\/ul>\n<p>So: <strong>do not put a module on <code>D0<\/code> and <code>D1<\/code> on an Uno.<\/strong> Use the pins for the USB cable, and give the module a software serial port instead.<\/p>\n<p>A Mega has four hardware UARTs and an ESP32 has three, which is one of the real reasons to move a project to a bigger board. <em>Uno, Nano, Mega, Pro Mini or ESP32<\/em> covers that choice.<\/p>\n<h2>SoftwareSerial, and what it costs<\/h2>\n<p><code>SoftwareSerial<\/code> makes any two digital pins behave like a serial port, by bit-banging the timing in software.<\/p>\n<pre><code>\/\/ Siratek: a module on pins 10 and 11, with the USB serial left alone.\n\n#include &lt;SoftwareSerial.h&gt;\n\n\/\/ SoftwareSerial(RX, TX) - named from the ARDUINO's point of view.\n\/\/ So the Arduino's RX pin goes to the module's TX pin.\nSoftwareSerial module(10, 11);\n\nvoid setup() {\n  Serial.begin(9600);          \/\/ the USB cable, to your screen\n  module.begin(9600);          \/\/ the module, on pins 10 and 11\n\n  Serial.println(F(\"Siratek: anything the module says appears below.\"));\n}\n\nvoid loop() {\n  \/\/ Module to screen.\n  while (module.available()) {\n    Serial.write(module.read());\n  }\n\n  \/\/ Screen to module, so you can type commands at it.\n  while (Serial.available()) {\n    module.write(Serial.read());\n  }\n}<\/code><\/pre>\n<p>That sketch is a <strong>serial bridge<\/strong>, and it is the single most useful twenty lines in this part of the library. It lets you talk to an HC-05, a SIM800L or a GPS receiver by typing at it, before you write any logic at all. Every one of those tutorials starts by running something like it.<\/p>\n<p>Note the argument order once, because it is the other half of the crossing: <code>SoftwareSerial(RX, TX)<\/code> is named from the Arduino\u2019s side, so pin 10 is the Arduino\u2019s receive pin and must be wired to the <strong>module\u2019s transmit<\/strong> pin.<\/p>\n<h3>The three limits<\/h3>\n<p><strong>It is not reliable much above 38400.<\/strong> The bit timing is done by counting instructions, and at high rates there is not enough time between bits to be sure of anything. 9600 is solid, 38400 is usually fine, 115200 is not.<\/p>\n<p><strong>Only one software port can listen at a time.<\/strong> You may create several, but only the one you last called <code>.listen()<\/code> on receives. Two GPS receivers on two software ports will not both work.<\/p>\n<p><strong>It blocks interrupts while sending or receiving.<\/strong> A byte at 9600 baud takes about a millisecond, and during it <code>millis()<\/code> is not counting and your interrupts are not firing. In a sketch doing careful timing, that matters \u2014 <em>Responding Immediately with Interrupts<\/em> is where this collides with servos and <code>tone()<\/code>.<\/p>\n<p>If any of those bite, the answer is a board with more hardware UARTs rather than a cleverer library.<\/p>\n<h2>3.3 volts, again<\/h2>\n<p>A UART\u2019s idle state is the line held <strong>high<\/strong>, at whatever that device calls high. An Uno\u2019s high is 5 V; an ESP32\u2019s, a GPS module\u2019s and most SIM modules\u2019 is 3.3 V.<\/p>\n<p>The direction that matters is <strong>Arduino <code>TX<\/code> to module <code>RX<\/code><\/strong>: 5 V going into a 3.3 V input. The other direction is usually fine, because 3.3 V is high enough for the Uno to read as HIGH.<\/p>\n<p>So the common fix is one divider or one converter channel, on one wire. <em>Mixing 3.3 V and 5 V Safely<\/em> has the detail, and the module pages say which of them need it.<\/p>\n<h2>Check yourself<\/h2>\n<p><strong>Your module is on <code>D0<\/code> and <code>D1<\/code> and the upload fails. Why?<\/strong> The upload is a serial conversation on those same pins.<\/p>\n<p><strong>You see <code>\u00ff?\u00ff<\/code> in the monitor.<\/strong> The baud rates do not match.<\/p>\n<p><strong><code>SoftwareSerial module(10, 11)<\/code> \u2014 which pin goes to the module\u2019s <code>TX<\/code>?<\/strong> Pin 10, the Arduino\u2019s receive pin.<\/p>\n<h2>Troubleshooting<\/h2>\n<table>\n<thead>\n<tr>\n<th>Symptom<\/th>\n<th>Likely cause<\/th>\n<th>Check or fix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Nothing received at all<\/td>\n<td><code>TX<\/code> to <code>TX<\/code><\/td>\n<td>The two wires cross<\/td>\n<\/tr>\n<tr>\n<td>Rubbish characters<\/td>\n<td>Baud rates differ<\/td>\n<td>Both ends, same number<\/td>\n<\/tr>\n<tr>\n<td>Upload fails, <code>avrdude<\/code> error<\/td>\n<td>A module on <code>D0<\/code>\/<code>D1<\/code><\/td>\n<td>Unplug it to upload, then move it<\/td>\n<\/tr>\n<tr>\n<td>Monitor shows two sets of output mixed<\/td>\n<td>Module on the USB UART<\/td>\n<td>Use SoftwareSerial on other pins<\/td>\n<\/tr>\n<tr>\n<td>Works at 9600, fails at 115200<\/td>\n<td>SoftwareSerial\u2019s limit<\/td>\n<td>Stay at or below 38400<\/td>\n<\/tr>\n<tr>\n<td>Two software ports, only one works<\/td>\n<td>Only the listening one receives<\/td>\n<td><code>.listen()<\/code>, or a bigger board<\/td>\n<\/tr>\n<tr>\n<td>Servo jitters while data arrives<\/td>\n<td>SoftwareSerial blocks interrupts<\/td>\n<td>Hardware UART, or separate the timing<\/td>\n<\/tr>\n<tr>\n<td>Module ignores commands<\/td>\n<td>Missing line ending<\/td>\n<td>Many want carriage return and newline<\/td>\n<\/tr>\n<tr>\n<td>Module responds once, then stops<\/td>\n<td>Buffer overrun, 64 bytes<\/td>\n<td>Read it more often than it fills<\/td>\n<\/tr>\n<tr>\n<td>3.3 V module behaving oddly<\/td>\n<td>5 V on its <code>RX<\/code><\/td>\n<td>A converter on that one wire<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Next steps<\/h2>\n<ul>\n<li><strong>Easier first:<\/strong> <em>Seeing What Your Program Is Doing<\/em>, which is this bus without the wiring.<\/li>\n<li><strong>Related:<\/strong> <em>Mixing 3.3 V and 5 V Safely<\/em>, which nearly every UART module needs.<\/li>\n<li><strong>Use it:<\/strong> <em>Bluetooth Serial with an HC-05<\/em>, <em>Reading Position with a NEO-6M<\/em> and <em>Sending SMS Alerts with a SIM800L<\/em> are three modules, one bus and three sets of commands.<\/li>\n<\/ul>\n<h2>Sources and attribution<\/h2>\n<p>All text and code in this tutorial are original Siratek work.<\/p>\n<ul>\n<li>The single hardware UART on the ATmega328P, its sharing with the USB interface on <code>D0<\/code> and <code>D1<\/code>, the 64-byte receive buffer and the bit timing are properties of the chip and the Arduino core described in their documentation.<\/li>\n<li>The SoftwareSerial limits \u2014 one listening port, interrupt blocking, and unreliability at high rates \u2014 are documented behaviour of that library.<\/li>\n<\/ul>\n<p>Baud rates for particular modules are the usual defaults rather than measurements, and each module tutorial gives the figure for its own part. No third-party tutorial text, diagrams, photographs or code has been reproduced here.<\/p>\n<p><\/p>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>The third bus, and the oldest. I2C and SPI were designed for chips on one board; a UART link is two wires between two independent devices, each with its own idea of the time.<\/p>\n","protected":false},"featured_media":0,"template":"","siratek_tutorial_level":[],"class_list":["post-52378","siratek_tutorial","type-siratek_tutorial","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>UART and Serial Links - siratek<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"UART and Serial Links - siratek\" \/>\n<meta property=\"og:description\" content=\"The third bus, and the oldest. I2C and SPI were designed for chips on one board; a UART link is two wires between two independent devices, each with its own idea of the time.\" \/>\n<meta property=\"og:url\" content=\"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/\" \/>\n<meta property=\"og:site_name\" content=\"siratek\" \/>\n<meta property=\"og:image\" content=\"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/uart-and-serial-crossing.svg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/\",\"url\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/\",\"name\":\"UART and Serial Links - siratek\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/siratek.net\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/#primaryimage\"},\"image\":{\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/siratek.net\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/uart-and-serial-crossing.svg\",\"datePublished\":\"2026-11-01T10:51:04+00:00\",\"breadcrumb\":{\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/#primaryimage\",\"url\":\"https:\\\/\\\/siratek.net\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/uart-and-serial-crossing.svg\",\"contentUrl\":\"https:\\\/\\\/siratek.net\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/uart-and-serial-crossing.svg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/uart-and-serial\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/siratek.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tutorials\",\"item\":\"https:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"UART and Serial Links\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/siratek.net\\\/#website\",\"url\":\"https:\\\/\\\/siratek.net\\\/\",\"name\":\"siratek\",\"description\":\"Your Best Electronic Retail Shop\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/siratek.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"UART and Serial Links - siratek","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/","og_locale":"en_US","og_type":"article","og_title":"UART and Serial Links - siratek","og_description":"The third bus, and the oldest. I2C and SPI were designed for chips on one board; a UART link is two wires between two independent devices, each with its own idea of the time.","og_url":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/","og_site_name":"siratek","og_image":[{"url":"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/uart-and-serial-crossing.svg","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/","url":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/","name":"UART and Serial Links - siratek","isPartOf":{"@id":"https:\/\/siratek.net\/#website"},"primaryImageOfPage":{"@id":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/#primaryimage"},"image":{"@id":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/#primaryimage"},"thumbnailUrl":"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/uart-and-serial-crossing.svg","datePublished":"2026-11-01T10:51:04+00:00","breadcrumb":{"@id":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/#primaryimage","url":"https:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/uart-and-serial-crossing.svg","contentUrl":"https:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/uart-and-serial-crossing.svg"},{"@type":"BreadcrumbList","@id":"http:\/\/siratek.net\/index.php\/tutorials\/uart-and-serial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/siratek.net\/"},{"@type":"ListItem","position":2,"name":"Tutorials","item":"https:\/\/siratek.net\/index.php\/tutorials\/"},{"@type":"ListItem","position":3,"name":"UART and Serial Links"}]},{"@type":"WebSite","@id":"https:\/\/siratek.net\/#website","url":"https:\/\/siratek.net\/","name":"siratek","description":"Your Best Electronic Retail Shop","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/siratek.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial\/52378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial"}],"about":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/types\/siratek_tutorial"}],"version-history":[{"count":0,"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial\/52378\/revisions"}],"wp:attachment":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/media?parent=52378"}],"wp:term":[{"taxonomy":"siratek_tutorial_level","embeddable":true,"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial_level?post=52378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}