Category Archives: XC8

PIC talks UART on RF – 434 MHz


PIC talks RF – 434MHz Modules

Photo Sep 01, 12 52 05 PM


Occasionally you’ll run into a project that requires a remote control. Our last article on IR might suit the bill, but what if you don’t have direct line of sight, or you’re like me and wished all remote controls worked like your PS3 and were RF-based?! No more pointing a remote! Don’t let me get your hopes up though. The 434 MHz modules (or often called 433 MHz) are more like garage door openers than a PS3 remote control. Their short range and poor bandwidth limit their ability to simple controls. No “Hello World!” this time around although it’s definitely possible, this just isn’t the application. Francesco was determined to shut me down on my decision on dropping the “Hello World” to the LCD and declared there was absolutely no problem in using the Mikroelektronika code in previous articles to send our standard “Hello World” to the LCD; this is what I love about Francesco. These RF modules can be found on eBay for a couple bucks as well as the normal places such as SparkFun, etc.

So lets get down to it; is this product right for your application?


Drop-In module for UART applications
Easy interface
No licensing

In some applications you can have a small amount of unpaired communication that will out perform bluetooth because of the lower frequency.


Limited distance, 500 ft direct line of sight
Questionable legality in the US (see below for more details)
Low data bandwidth


The communication

The 434MHz modules work by shifting the output level of their carrier frequency based on a digital input. If the input to the transmitter is a binary level “0”, the RF output is reduced if the input is a level “1” the RF output is increased. This is called Amplitude Shift Keying. While we are using the modules with a carrier frequency of 434MHz (433.92 MHz) you can also find these in 315MHz and 915MHz flavors. Further discussion about how the data is transmitted and received within the module is beyond the scope of this article.

Modulation Techniques


Lets discuss legality: It should be known Francesco lives in ITU Region 1 and Charles lives in ITU Region 2. The ITU region is a boundary created by treaty that dictates the RF band plan. The band plan is a guide outlining what segments of the RF spectrum are used for what purposes. For instance: Aircraft radio-navigation follows directly after the FM broadcast bands in the US. Google is your friend if you want to learn more. In ITU region 1 these 434 MHz modules fall into an ISM (industrial, scientific, and medical) band which is basically a free-for-all zone for all sorts of wireless devices despite it’s named intention. It’s an under-regulated, noisy cesspool of small electronic devices that can transmit license free. In ITU region 2 these 434MHz modules sit in a 70cm amateur radio band. What does this mean for legality? Well in the US you have the FCC and Part 15 rules. I did some reading on the TI Application Report SWRA048–May 2005. According to this document if you keep your transmissions under -49.2 dBm you should be safe, however if you read further in this document it suggests in a control application you can radiate at about -25dBm EIRP and even sneak some more power if account for your duty cycle. That’s up to interpretation of the document and I would probably strongly recommend actually reading 47 CFR Part 15. Regardless of your output power you still can not cause interference with the band user! That means you can not interfere with any amateur radio uses. I have a ham license so in my test I’ll use my license because I do not know my EIRP and good luck finding it in the specs (even with no external antenna connected). Will you get in trouble if you live in the Americas using these modules? Probably not. I wouldn’t produce a product to be sold outside ITU Region 1 with these modules though.


The circuit



In the first version of the 16F1509 application PORTB.7 was connected through directly to the “Data” pin of the transmitter; the Vcc is connected to a 5VDC power supply and ground to the negative side of the supply. Through testing I found that if I transmitted the data inverted I had better data reliability.

In the XC8 compiler that is accomplished by setting the SCKP bit in the BAUDCON register.

    BAUDCONbits.SCKP = 1;   //inverted TX

Because of the noise I tested this application strictly from microcontroller to PC to start with. I did this to evaluate the amount of noise. I found that these modules shouldn’t be your first choice for sending RS-232 data in a reliable manor. You can do this but I wouldn’t expect high data rates and it should be considered for control applications where handshaking and data integrity is confirmed and can be requested to be resent. A robust protocol would be needed. As shown below this is the output of the data being sent from the microcontroller to the transmitter, through the receiver and then because my terminal client didn’t have an inverted data option I added a 74LS04 inverter before the TTL to RS232 level converter.

The Code

The 16F1509 Transmitting PIC code: uart_xmit_w_parity.c

After successfully exploring the transmission side of the project I decided it wouldn’t be much fun if we didn’t give the readers a building block of a control system. Using a PIC 18F26K22 demo board that came with an LED (ease of troubleshooting) I quickly wrote a program that would first check for framing errors, then UART overruns, then finally confirm parity.

            if (RCSTA1bits.FERR) {  // Frame Error, next read will reset
                uart_data = NULL;

            if (RCSTA1bits.OERR) {  // Overrun Error
                RCSTA1bits.CREN=0;       // receive disabled
                RCSTA1bits.CREN=1;       // receive enabled
                uart_data = NULL;

            parity = calculateparity(uart_data);
            if (parity_rx == parity) {

The specification declare a framing error will be cleared automatically on the next UART read; you can ignore this but I set the received data to NULL so that I’m certain I won’t do anything else with it below if the parity happens to be correct. The overrun flag on the other hand will not be cleared unless you actually turn off the UART receiver and then it back on by clearing and setting RCSTA1bits.CREN. Finally I calculate the parity of received data and compare it with the received parity bit. If I get a match I consider the data good enough to compare it for a valid command. In the code below I am simply looking for the “a” in my call sign and set the output to the on-board LED for 1 millisecond but this could just as easily be an output to a relay (via transistor driver).. or whatever control you need. To port the code between the 16F and 18F series depends on the actual device you’re using. In these cases the 16F series I drop the “1” out of the TX/RC registries (RCSTAbits versus RCSTA1bits).. other modifications will likely be needed based on the individual product you select. Common changes are the configuration settings, oscillator settings, and BAUD control (SPBRG).

The PIC 18F26K22 Receiving Code: uart_rx_w_parity.c


The Results

In the following screenshots you’ll notice a fair amount of noise. It was worse in my initial testing of these modules. This was somewhat remedied by modifying my UART transmit code to 9-bit and using a parity generator to include an EVEN parity bit. I had high success with determining when data was bad due to noise. Either there was a framing error and/or a parity error. Both of these can be easily handled in a microcontroller. In my testing I had the best luck with 1,200 baud and 2,400 baud. I found I missed many more bits with 4,800 baud and at 300 baud I become more susceptible to noise; that surprised me more than anything.

Note the actual characters being transmitter are "__ ac0gd - test. "

Note the actual characters being transmitter are “__ ac0gd – test. “

The output on the logic analyzer on the receiving PIC showed my output when I had a valid “command” compared to the serial stream. Note in the second screen shot I occasionally miss a command because of noise. Any commands you send should be sent in multiples for your best chance of proper communication.

rx_valid rx_invalid

Spectrum Analyzer

Neither of us has a ‘scope that has the bandwidth to show you the ASK in the time domain as shown in the modulation diagram previously in the article. We can however show you this device is fairly narrowband in the frequency domain using a spectrum analyzer. The device is advertised as 433.92Mhz; I trust my SA’s accuracy over the little transmitter in a can.



Look at those harmonics!

Look at those harmonics!

These modules have a bit of harmonics; the 2nd harmonic is at about -30db of the original signal and that is not surprising given the size and cost of the device.


Logic analyser

There wasn’t much surprise on the logic analyzer. It goes in looking like regular UART and comes out with some slight timing wiggle but within specification enough for the LA protocol analyzer and terminal emulation client to receive the data. 
tx vs rx LA

Try to push the speed on the module and you just end up with data-mush!


Final thoughts

We had a great time playing with these little RF modules. They’re a very affordable way to start getting your PICs to play together when apart and are a great launching point to a lot of fun projects.

When finished with the project we had to do some range testing! I found that in a home environment I got about 100 ft (30m) of range out of this device and it still have the ability to send mostly correct information; 1 out of 4 transmissions. My preambled began to fall off first, and eventually the whole sentence was gone. At about 40ft (12m) I had about 30-50% correct transmissions. My antenna was a 6″ piece of wire on both transmitter and receiver, yes I know not even quarter wavelength.

I’ll wrap this article up with a list of considerations I wrote while writing the code for this article and testing this project…  they follow:

Uses: Remote Control, Wireless Home Automation, Telemetry.

Multiple Devices: Typically I’ve found these transmitters working in a one-to-one or multiple(tx)-to-one(rx) topology.

In one to one situations your overhead is pretty low unless you’re trying to make the transmitting/receiving device pair unique.
There are a number of projects found on the internet where a number remote sensors/transmitters broadcast some bit of telemetry to a receiver; the telemetry data would include a transmitter or sensor number with it’s packet of data.
If you’re considering a multi-to-multi or a mesh network I recommend finding an alternative product such as XBEE.

Simplex vs Half/Full Duplex: If it’s not completely obvious we’ve presented a project that information only flows in one direction (Simplex).

If you wished to have bi-directional data you would want to have a transmitter and receiver at both microcontrollers.

You could get away with using the same style transmitters and receivers if your goal was simple simplex operation. Example: walkie-talkie where one person talks while the other listens. (Unless you have a rude friend)

If you were looking for a full duplex operation you might consider buying a set of 315MHz modules for one path and then 434Mhz modules for the other path. If you attempted to use the same frequency transmitters for bi-directional transmission your receivers would get confused over actual signal and receiver garbage. Separating the frequencies to such a degree will help prevent the receiver getting mixed communication. It’s still possible that the power from one transmitter will overload the front end of the receiver installed near it. I recommend physically separating the transmitter and receiver at each microcontroller as far as reasonably possible.

Security: In uses you’ll note we didn’t mention Security applications. I don’t recommend using these simple modules for some secure application such as unlocking your front door.

If you pair this with some other technology such as Microchip’s KeeLoq or other hardware cipher offerings you can achieve reasonable secure communication.

Voltage Input: Battery Applications

The PIC you use can dictate what voltage you might desire for your system. One additional thing to consider is the voltage supplied to your transmitter. Many of these transmitters can accept up to 9VDC. You will see improved transmission range if you have the ability to run your transmitters on a higher voltage. The make and model of your modules will dictate what you can use.

External Antenna

Determining the legality of your antenna system is also another item that’s beyond the scope of this article. That being said if you are going to use an antenna attempt to make it something such as a half wavelength dipole or 5/8 or full wavelength vertical antenna with ground counterpoise. Having the correct wavelength antenna will minimize your SWR loss and improve your transmitter range.

315MHz vs 434MHz: (I’d use 315 in the US)

This is opinion, I have no articles to reference for proof, take this bit of advice with a grain of salt. If you’re in the US you’re likely better off to receive less interference by using the 315MHz modules. You’re also likely to get better range at these lower frequencies outside. Because of the lower frequency your antenna system will have to look electrically longer for best performance. The 434 modules are well within amateur radio spectrum and you’re likely to get intermittent interference if you live near a city. If this is to be used indoors you’re probably going to see better performance from the 434MHz modules.


I personally wouldn’t use a heavy protocol on these devices, but you could make your own lightweight TCP-like stack if you have nothing but time and hardware budget was tight.

Regardless you should consider at least sending an address with your data transmissions even in a one to one situation for possible future use. A transmission might look like $$$$$T01,W,203,3.0#.  The $$$$$ is a made up preamble. I’ve noticed more than any other time my first one or two bytes of information are the most noisy. If you have a couple bytes you can throw away in the front your packet the receiver microcontroller can safely ditch any preamble bad bits. I nicely formatted string will also help you determine validity of the reception. I would also recommend you consider using a stop bit (in this case I arbitrarily used “#” ).

PIC talks UART on RS-485

PIC talks UART on RS-485


RS-485 is a differential serial communications link. The link is not open-ended and doesn’t use the local hardware’s ground. The specification is defined by hardware; not the actual communications protocol. I’ve personally ran into dozens of different protocols using RS-485 that including MODbus, BACnet MS/TP, Johnson Controls N2Open, etc. Officially “RS-485″ is now TIA-485-A but you’ll find it called RS-485 or EIA-485 more times than not, I’ll switch to referencing this standard as “TIA-485″ or just 485 for the remainder of the article. TIA-485 was designed to be a multi-drop bus for multiple devices and multiple “masters” on one communications trunk. Most commonly you’ll find TIA-485 on a 2, 3 or 4 wire circuit with 24-18 gauge wire. The specification boasts of long distance communication relative to its old cousin RS-232, up to 4000ft. TIA-485 is still heavily in use with power control, automation, and monitoring systems. Nearly all commercial and industrial controls systems use TIA-485 to date. You can read more in TSB-89-A.pdf including some of the definitions I’ve used.


The communication

It is important to remember TIA-485 is an electrical specification, not a software protocol nor are their recommended physical interfaces. There are other specifications which sit on top of the TIA-485 specifications, BACnet MS/TP and MODbus being two popular choice in industry but likely not your best choice as a hobbyist. The specification was embraced by industry when it was released by the EIA in 1983 so it makes a great option for wired communications for microcontrollers. I’ve personally seen many 6502-variant systems with robust proprietary protocols on top of the bus so you should be able to develop your own protocol with out too much overhead on many of the PIC mid-range devices.

Typical speeds are 9,600 to 115k baud. In my experiences I’ve seen 9,600, 38,400 and 76,800 baud used most commonly. Typically longer segments use slower speeds for reliability, however if you have short runs you can run your bus into the multiple Mbps range.
Multiple devices? Yes, In practice the specification defines up to 32 “loads” on one bus. There have been some clever devices developed to operate as a “1/2 load” allowing for 64 devices on one segment.

Some of the actual specifications:

  • Balanced interface
  • 120 Ohm typical impedance
  • -7 to +12V common mode range
  • 200mV differential voltage between twisted pair
  • 100Kbps @ 4000ft (much faster the shorter you limit the bus)
  • full duplex (4-wire) or half duplex (2-3 wires)
  • 32 nodes

In my example I use a USB to RS-232 adapter to my PC followed by a RS-232 to TIA-485 adapter from B&B Electronics model number: 485SD9TB ($75).


The circuit

For this circuit I pulled some small 20-pin PIC development boards I had created for some experimentation with TIA-485. I hadn’t gotten to use these yet and as these were the second PCB I had ever developed in Eagle CAD I found I had made a few mistakes so I will not publish the circuit as it would be a disservice to you. You’ll note a little dead-bug wiring with the /RESET pull-up resistor. I also placed some of my jumpers in a manor I had wished I configured differently. Perhaps I’ll re-manufacture these for the more expanded board in a future article. Below I have provided a “sample” circuit which is the RS485 click board if you’re using a MikroElektronika development board. I used the Analog Devices ADM485 for my circuit although I’ve been testing some polarity agnostic devices from other manufactures. The ADM485 is a low power transceiver; You can review its specification sheet in this PDF. I used a simple test configuration as shown in this diagram:



In your circuit you will want to connect your UART TX pin to the transceiver DI pin. A digital output pin to DE to enable/disable the driver. Your UART RX pin will be wired to the ADM485 RO pin and another digital output connected to the RE pin to enable/disable the receiver. The other connections on the transceiver include the power and the A and B bus pins that you connect to other transceiver chips as shown below. I used a common two wire bus configuration.



This is photo was pulled from the TI RS-485 Reference Design Guide

Typical daisy-chain bus structure

Typical daisy-chain bus structure.


EIA-485 home-brew development board

EIA-485 home-brew development board

Francesco scolded me for trying to pass off this mostly-hardware article without at least a hint of a schematic; what was I thinking? :) Below is the schematic of the RS485 click from MikroElecktronika. This is a good starting point. You’ll notice some options to drop in termination resistors (jumpers 32, 33, and 34 depending on how you want to reference your signal, talking about ground loops and ground potential difference is beyond the scope of this article but that is the purpose for the jumper configurations). This board was set up for half-duplex as was mine. This is the most common configuration of the 485 bus.

A sample schematic for a UART to 485 interface. Note the ADM485 is pin compatible with the SN75176. The schematic shown is the actual schematic of the RS485 click board from MikroElektronika.

A sample schematic for a UART to 485 interface. Note the ADM485 is pin compatible with the SN75176. The schematic shown is the actual schematic of the RS485 click board from MikroElektronika.

The Code

The code is no different from using the standard UART on the PIC. You can read more about that on our UART article or use any UART code you desire. To use multiple devices you will may have to develop your own protocol for addressing and sending/receiving/replying to data. I’ve place this on my “PROJECTS TO-DO” list and will link that project in once I get to it.

For my testing I re-used my code on the PIC talks UART article, but in this case I had previously made a TIA-485+20 pin PIC development board so I decided to port my code to the PIC18F14K22. Instead of ‘Hello world’ I opted for the program to simply repeat a character for easy testing.

You may recognize this simple XC8 UART transmit function:

void uart_xmit(unsigned int mydata_byte) {   //this function sends 1 character to the UART transmit buffer
while(!TXSTAbits.TRMT);   // make sure buffer full bit is high before transmitting
TXREG = mydata_byte;   // transmit data by loading variable into the TXREG register

void write_uart(const char *txt){
    while(*txt != 0) uart_xmit(*txt++);     //this send a string to the TX buffer through my 'uart_xmit' function
                                            //one character at a time

And then the actual code to send the repeating characters:

while (1) {
 write_uart("Hello, world!");   //send Hello, world! to UART
 uart_xmit(0x0A);   //send an ASCII character for line feed
 __delay_ms(149);   //delay 149 milliseconds
 write_uart("From");   //send From
 uart_xmit(0x0A);   //send an ASCII character for line feed
 __delay_ms(149);   //delay 149 milliseconds
 } //... wash, rinse, repeat

I have plans to develop a light-weight protocol for use in some projects. My goal is a single master with multiple “slaves”. The slaves will be “polled” so they will listen and only respond when commanded to respond. I will likely include some form of change-in-state poll on a quick poll and follow-up with actual polling of data as needed. I will also include some form of addressing and ability to “time-out” on devices no longer on the bus or powered down.


The Results



For ease of visibility I picked on one letter to show you what the signal between the 485 A and B bus terminals looks like on the oscilloscope. You can clearly see the Z character (binary ‘1011010’). As before the data is transmitted LSB first with a start and stop bit 0101101, note that this signal is inverted from the signal recorded below on the logic analyzer. I made this measurement at the A/B output of the transceiver chip.

The EIA-485 signal reading ASCII character "Z" on an oscilloscope.

The TIA-485 signal reading ASCII character “Z” on an oscilloscope.

Logic analyzer

The output of the logic analyzer…  this shows the capture of the UART output as it goes to the transceiver chip on a single character (for comparison with the above TIA-485 output):

Using the logic analyzer to look at the ASCII character "Z" being send by the UART to the ADM485 transceiver.

Using the logic analyzer to look at the ASCII character “Z” being sent by the UART to the ADM485 transceiver.

As before here is the whole string in the test program being captured:

Hello.. on Logic Analyzer

Terminal program

For my test I decided a quick connection to my PC through its RS-232 port and converted over to TIA-485 by the B&B converter showed my circuit was working correctly and the UART on the PIC was sending proper information to my PC.

Sending Hello World! from PIC UART through TIA-485 bus and converted to RS-232 to be captured by a terminal program.

Sending Hello World! from PIC UART through TIA-485 bus and converted to RS-232 to be captured by a terminal program.


Connecting to the UART on the PC via TIA-485

Connecting to the UART on the PC via TIA-485

Physical Measurements

Enabling and Disabling the transceiver shouldn’t be left to the wayside if you’re only using the circuits for point-to-point communications. I noted that my circuit consumed 5mA with the transceiver disabled, 61mA enabled with no termination resistors and 83mA with a 100 Ohm termination resistor at the output of the transmitter. A considerable amount of power if you’re operating on batteries.

Final thoughts


As usual you can find more information on Wikipedia and a number of other sites including Analog Devices, TI and Maxium who make interface chips for the communications link. I look forward to developing a light-weight 485 protocol for the PIC and perhaps it’s something we can build on with our readers input.

Why? What use is TIA-485 to you and me? Well if you haven’t figured it out by now I have always favored TIA-485 in two applications:
1. hardwired communications lines that run more than a couple feet, and
2. When I want multiple addressed micro devices to communicate on the same trunk to a master and perhaps with each other.


PIC talks UART


PIC talks UART

16F887 UART Breadboard Hello World


This article is about connecting two PICs via their UART. If you need to know about UARTs just Google that up, if you want to see them up close … read on!

Serial communication is something that has been around for quite some time and it is still very present today in many shapes and forms. When working with embedded systems knowing how to use the UART is of the utmost importance. The UART can be used for micros to talk to each other, for a micro to I/O to a terminal running on a PC, to interface to devices like a GPS module or a Zigbee or an infrared module.

For this article we will be using two PIC16F887 40 pin PDIP and compile the code with MikroC and Microchip XC8. We will be using two Mikroelektronika’s EasyPICs boards for the preparation of the material but we will also provide instructions on how to achieve the same results on a breadboard.

The two EasyPICs board connected via UART

The two EasyPICs board connected via UART

 The communication

At the wires level the two PICs will interface using PINs 25 and 26. These are the PINs reserved as TX and RX.


PIC16F887 pinout

They are respectively RC6 and RC7 of port C in the block diagram below.


PIC16F887 block diagram


RC6/7 modes and functions

The signal generated should look like the one below. Bear in mind that our PICs will use simplex asynchronous communication. Wikipedia’s Universal asynchronous receiver/transmitter has additional information.


UART signal

The line is kept high until the transmission starts bringing the line to low and logic 0, then 8 or 9 bits are transmitted. The packet is terminated with a stop bit which is always 1. In this way the signal is brought back to high. Further details on the inner workings of the UART module can be found in the Serial Communication Modules of Mikroelektronika e-book and in Microchip PIC Mid-Range USART.

 The circuit

Our circuit will be as follows, we are connecting the PICs so that the TX on PIC1 is connected on the RX on PIC2 and vice versa the TX on PIC2 to the RX on PIC1. This configuration is also known as NULL-Modem.

Circuit setup

Just to make things easier in order to replicate the circuit on a breadboard, we have provided a BOM and a description of the breadboard set-up in another article … 40-pin (6F887) DIY Protoboard

Once the breadboards are ready and connected, they should look like this


Breadboards connected


Breadboards connected from another angle. The LCD hooks up neatly on top of the microcontroller

The Code

The aim of the program on PIC1 is to send a “Hello, world!” message to PIC2 so that the program running on it can display the message on its LCD.

The TX side will first of all set the baud rate, in this case to 9600 bps, then enter an endless loop in which it will write “Hello, world!” and “From” to its UART at 1 seconds intervals. Between each message a character 10, representing a linefeed, is also sent as a terminator.

UART1_Init(9600);               // Initialize UART module at 9600 bps
  Delay_ms(100);                  // Wait for UART module to stabilize

  while (1) {                     // Endless loop
        UART1_Write_Text("Hello, world!");   // 0x48 0x65 0x6C 0x6C 0x6F 0x2C 0x20 0x77 0x6F 0x72 0x6C 0x64 0x21
        UART1_Write(10);                     // 0x0A
        delay_ms(1000);                      // Wait a bit
        UART1_Write_Text("From");   // 0x46 0x72 0x6F 0x6D 0x20 0x30 0x78 0x45 0x45 0x2E 0x6E 0x65 0x74
        UART1_Write(10);                     // 0x0A
        delay_ms(1000);                      // Wait a bit

The RX side will setup the baud rate to match the one from the TX PIC and then simply stay in an endless loop waiting for data to be ready. If some data is received. Each byte representing a character gets stored in an array of characters until a \n or linefeeld is received at which point the array is considered complete and ready to be displayed on the LCD via the next line.

UART1_Init(9600);               // Initialize UART module at 9600 bps
  Delay_ms(100);                  // Wait for UART module to stabilize

  while (1) {                                     // Endless loop
    if (UART1_Data_Ready()) {                     // If data is received,
       UART1_Read_Text(received,"\n",255);        // Store in received everything before a linefeed
      Lcd_Out(1,1,received);                      // Display received on the LCD

In the XC8 version of the program as shown in the snippet below the bulk of the work for receiving is done in the interrupt service.

void interrupt ISR() {

    if (PIR1bits.RCIF)          // see if interrupt caused by incoming data
        char temp;
        temp = RCREG;     // read the incoming data
        PIR1bits.RCIF = 0;      // clear interrupt flag

        if(temp=='\n')      //if EOL
            index = 0;
            new_rx = 1;             //"ding"
        else if(temp!=1)           //in middle of string
            rxtxt[index] = temp;         //load it up
            index++;                    //increment index
            if(index > 19)              //that's more than enough data
                index = 0;              //reset index
                new_rx = 1;             //"ding"


Here you can fin the full TX code and the RX code for MikroC and the TX code and RX code for Microchip XC8.

 The Results

We thought it would be a good idea to give a bottom up approach to analysing what happens during the communication. Much like the ISO/OSI model will look at the different layers from the wires and the voltages up through to the message that gets displayed on the LCD.


The oscilloscope is a useful tool to look at voltage levels in the time domain. The scope displays the level from the input from the left to the right. Shown in the screen-shot is the ASCII letters “Hello”. We used a single sequence trigger to capture this sequence of the message. If you use a free-running rising-edge trigger it is difficult to determine what part of the message you are looking at. Note that there are very low levels of noise on the line. If there is noise on your UART communication lines you would find it with an oscilloscope as the oscilloscope is displaying actual voltage levels. In this case each major division horizontal  grid marking represents 2.0V with the middle horizontal marking set up as the 0V reference;  The vertical grid lines indicate time.

Hello at 9600 Baud

“Hello” at 9600 Baud

Logic analyser

One step above the voltage levels measured by the oscilloscope we can position the logic analyser which will interpret the changes of the voltage as logic levels. Depending on the type of signals and the electronics involved, the values will be interpreted as high and low or logic 1 and 0.


“Hello, world!” as logic states

Protocol decoding

In order to better understand the results from the protocol decoders of both the logic analyser and the bus pirate, we can refer to the following ASCII table. The values displayed by both tools are both in hexadecimal.



Logic analyser decoding

A part from looking a bit more squeezed, the picture below is the same as the one obtained using the logic analyser,

Hello, world as timing

“Hello, world!” as timing

it is only by inspecting it with a packet decoder that the next level of abstraction will be unveiled.


“Hello, world!” as UART Packets at 9600 kb/s

By using the hex column of ASCII table above we can already make sense of the packets by matching the numbers with the characters. It is with no surprise that the sequence above reads “Hello, world!” plus a line feed character at the end.

If you are so bold/mad as to look at the logic levels from the wave above, you will notice that the sequence for the “H” character has to be read from left to right to make sense. The “H” character is 0x48 in hexadecimal which in binary translates to 0b01001000. This should be made more evident by looking at the following picture which breaks down the packet sent into its 10 bits.


UART packet dissection

Note the duration of each byte sent. At 9.600 kb/s we are sending 9600 b/s. The adjustment made by the baud rate generator produced an effective baud rate of 9.615 kb/s.

9.615 kb/s = 9615 b/s = 9.615 b/ms = 0.009615 b/us
The packet is composed of 10 bits and it takes 1.039 ms to send according to the logic analyser. This means that 1 bit takes 0.1039 ms or 103.9 us. The rate calculated from this yields 0.009624 b/us or 9.624 kb/s which is, rather obviously, very close to the baud rate set by the micro. Hurray!


“H” character transmit duration. The duration should read 1.039 ms and not 980 us

Bus Pirate

Much like with the previous tool, when using the bus pirate in UART mode we can decode the message sent by either reading each byte sent


Bus Pirate input decode


Note that the sequence captured on the left is inverted as “From” comes before “Hello, world!”

while (1) {                     // Endless loop
        UART1_Write_Text("Hello, world!");   // 0x48 0x65 0x6C 0x6C 0x6F 0x2C 0x20 0x77 0x6F 0x72 0x6C 0x64 0x21
        UART1_Write(10);                     // 0x0A
        delay_ms(1000);                      // Wait a bit
        UART1_Write_Text("From");   // 0x46 0x72 0x6F 0x6D 0x20 0x30 0x78 0x45 0x45 0x2E 0x6E 0x65 0x74
        UART1_Write(10);                     // 0x0A
        delay_ms(1000);                      // Wait a bit










or by reading the raw UART input


Bus Pirate raw input

Note the linefeed that we have inserted at the end of each message.

Follow the link should you want to know more about sniffing UART packets with the Bus Pirate.

LCD output

Finally our message gets displayed on the LCD connected to PIC2 gets displayed!

"Hello, world!" on the LCD

“Hello, world!” on the LCD

Final thoughts

At the end of this article you should be able to have two PICs talking to each other via their UART whether you are using MikroC or Microchip XC8. With some basic understanding of the protocol we can now move onto connecting to other devices or using different media to achieve the same communication. We will add a number of spin-off of this article as soon as we manage to put them together. Stay tuned!

We hope you add fun and in doing so also learned something new. Please get in touch through the forums, we’ll do our best to answer your questions, cherish your advices and, why not, learn something more.