UART or Universal Asynchronous Receiver Transmitter, is one of the most common communication protocols out there. It allows for 2 devices to be connected and also for them to both send and receive data at the same time. In this video, we will be going over an example of this by connecting 2 Picos and controlling the onboard LED on one with commands from another, and as we will see, this is incredibly easy in a MicroPython environment.


UART, or Universal Asynchronous Receiver Transmitter, is one of the most commonly used device-to-device communication protocols out there. UART is a great tool which allows us to get two devices to talk to each other, and you can get them to work together in tandem to do things that you can't do on only one. To get two devices to talk to each other with UART, you're going to need two connections on each device. One wire to send data on, and another one to receive data on. These are called the Transmitter Pins, TX, or the Receiver Pin, RX.

Now UART is something called a Full Duplex System, which is a really fancy way of saying that both devices can communicate with each other at the same time. They can both send and receive data simultaneously. And we will see that in a future video, this is not the case for all communication protocols, because with something like I2C, you can only have one device talking at a time. Now both devices need to agree on how fast they're going to send and receive data between each other, and this is called the Board Rate. And so when we set up our devices, we need to ensure that they share the same board rate. And there are a whole bunch of standard rates out there, but you'll most commonly encounter 9600 and 115,200.

Now there are many different ways that you might use UART in your projects, but we're going to jump into a really great example of getting two Picos to talk to each other, so we can see what's going on in a MicroPython environment. If you want to follow along, you're going to need two Picos, any variance will do, and some jumper wires, and that's it. We're just going to go ahead and code everything from scratch, but if you want the final code, it can be found on our course page on our site, link in the description for our YouTube audience.

First, we're going to start with our hardware connections. I'm just going to whack them in there for now. And all we're going to need to do is connect up the TX and RX pins. And this is something that catches a lot of people off guard, but you plug the TX pin of one Pico into the RX pin of the other and the RX into the TX. This is because if one transmits on the TX pin, you want to receive it on the RX pin on the other one and vice versa. So we're going to be using GP4 and connect that to GP5, like so. So RX to TX, and then we're going to connect GP5 to GP4, so RX to TX, like so. And very importantly, we're going to need to connect a ground pin of one Pico to the ground pin of another Pico. And this is going to ensure that they share a common ground. A voltage is generated with reference to ground. So this ensures that if one produces a 3.3 volt signal, it measures 3.3 volts on the other one because they share a common ground.

Now I've gone ahead and plugged both of my Picos into my computer and opened up two instances of Thonny. One here is connected to one of the Picos and the other one is connected to the other one. And this is going to allow us to program both of these at once. Now what we're going to do is we're going to control the LED of this Pico with a signal from the other one. So we will write some code for this one to send commands over UART, and then we're going to write some code on this one to receive those commands and control the LED with them.

Starting with the one that will send the message, we're going to import our library. So we're going to import pin and also UART. And then we're also going to import time because we will be needing that. Next we're going to initialize our UART with very similarly how we set up most of our pins. And in our setup options, we're going to first specify the UART peripheral we're going to be using, as well as the board rate, very important here, as well as the TX pin we're using, pin four. And we're going to specify the RX pin, which is pin five. Sweet. So next we're just going to create our while true loop, and then all I'm going to do is I'm going to send a message with UART.write, and then I'm going to write on, and then I'm going to sleep it for two seconds. And then I'm going to do exactly the same, but I'm going to write off. And that's it. That's all we need to do to send messages over UART in MicroPython. It's really simple. And if we run it, nothing's going to happen because we're sending that data over, but we're doing nothing with it. Now let's write the code to receive it.

So I'm just going to copy and paste what we had there. I'm just going to delete all that, and then we don't need time, so I'm just going to get rid of it. And I'm just going to call this one test UART2 to stop it from being confusing so we can refer to it. And very importantly, we want to ensure that it shares the same board rate. What I'm also going to do is I'm going to set up an LED with pin, and we've set up lots of LEDs before, so this should be pretty straightforward, as I'm going to set that as an output. Sweet. Now to start with, we're going to need this test UART2 dot any line. Now we're going to need this dot any line here because when the Pico sends data to the other one, that data is going to get stored in something called a buffer, which just kind of holds the data till it's ready to be processed. And what this dot any does is it just checks if there is data in the buffer. And if it is, it will return true logic. So if there is something in the buffer, we're just going to assign it to a message, and we can read it with just test UART2 dot read. Then to make it easier on us, we're just going to print message to the shell, and then we're just going to set up some logic here. So if the message is on, we are going to set the LED to on. And if it's off, we are just going to set the LED off. And I forgot to put my colons on the end of all my if statements, so we'll just whack that in there.

Now, if we run the code that sends it on the sender board and on the other one, if we run the code that receives it, we can see that we are now printing off our off and on strings, and that data is being transferred from the sender board to the receiver board. But something is wrong here. We are not getting a flashing LED on this board. We are printing our messages through the shell here, just in a weird format. This is a bit of a technical thing, but UART sends something called a byte string, which has this format with the B and the quotation marks and the actual string we're sending inside of them.This is just something that happens with UART, and it's very easy to fix. On the end of our read statement, we're just going to put dot decode. And if we stop and run that, we can see that we are now just going to receive that raw message, not in that weird format. And if we look at our LED, it is flashing on and off. Wow, that's a pretty darn cool thing. We are literally sending words from one Pico to another. But how does that work?

Well, on this Pico, when we use the dot write command to send a string, that string gets turned from words into ones and zeros using something called ASI encoding. ASI is kind of just a universal set of rules for representing a letter with something called a byte. Don't confuse a byte with a bit, though. A bit is just a one or a zero, and a byte is just eight of those bits put together. So when we use the dot write function, each letter of that on and off string gets turned into a byte, then the Pico rapidly changes the voltage on the pin to send those ones and zeros to the other Pico. And then when we dot read on the other Pico, we use the same ASI rules to turn those bytes back into strings. And that is pretty ingenious. to ones and zeros through a wire and then turned back into words on a completely different device.

Now, an important thing is that you can only send strings, no integers, no floats. So if we create a variable called X here and assign it the integer 10 and then try and send that, it's going to give us an error. What we must do is we have to turn it into a string with the string command before we send it over. So if we look at this one, we're going to be receiving 10 and off here.

Now the Pico only has two UART channels or prohiferals, as they're called, UART0 and UART1, and you can only have one device connected to a UART prohiferal at a time. But there are multiple pins that you can use to access these UART prohiferals. Here we use pins four and five, which are the TX and RX pins for UART1, but there is another way to access it. You could instead use pins eight and nine, which are also connected to UART1. But you can't make two different UART connections with these pins as they're both connected to UART1. If you wanted to make another UART connection, you would need to use the other prohiferal, UART0. And you can access UART0 through pins zero and one or 12 and 13 or pins 16 and 17. These are all kind of just different routes that you can use to access the same UART hardware. So in our setup, we need to specify what UART prohiferal we're using and what pins we're using to access it. So instead of one, four and five, we could access UART0 through pins 12 and 13, for example. You can always check a pinout diagram to see what pins can be used to access what UART prohiferal.

All right, sweet. We can make a UART connection, but what can we do with it? Well, we can now connect our Pico to something else and get them to work together. You could not only connect your Pico to another Pico, but other microcontrollers, like maybe you could connect your Pico to an Arduino. Or you could get your Pico to work together with a Raspberry Pi computer. You can make the Pi do all the hard number crunching and all the calculations because it's really powerful and get it to tell the Pico to control some motors through UART. Just be wary, though, and check what logic level they use, because the Arduino, for example, uses 5 volt logic to create its ones and zeros, not the 3.3 volt logic that our Pico uses. But this can be fixed with a really inexpensive logic level converter like this. You can also connect your Pico to UART enabled modules and sensors like this GPS here. I'm using the exact same code from the demo to receive live GPS coordinates over UART. All the processing is done on the GPS, and I just get the final result through UART. And all I've had to do is plug power into the device and connect the TX and RX pins to my Pico. Now, your experience using a UART module might not be exactly the same as this, though. You might need to install and use a library, but it shouldn't be too dissimilar.

So three key takeaways. One, UART is a communication protocol that allows two devices to talk to each other at the same time. Two, it only needs to use two pins, TX and RX, and you connect TX to RX and RX to TX. And three, we can use the.write and to send and receive strings over a UART connection. Just make sure you use.any to check if there is something to be received in the buffer first.



Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.