According to Pete - Demystifying Serial Communication


Well, we've breezed through the half-way point of September and fall is officially in the air. School is back in session, football season is in full-swing, and the first mountain snowfall is in the books. More importantly, half-way through September means another edition of "According to Pete." Today, Pete tackles some common questions about serial communication. Check it out:

Feel free to leave any questions or suggestions in the comments section below. We hope you enjoyed this edition of "According to Pete" and we'll back with more in a few short weeks. Cheers!


Comments 32 comments

  • “The gear is jacked and we need to send someone out on a horse.” I now need to clean my breakfast off my monitor! Love it! Keep up the awesome work, Pete.

    • Isn’t RS232 12 Volts? That’s why you had to translate it for the old TTL(5V)? {now down to Pete’s 3.3V ?}

      And if I remember what Gramps used to tell me they use to run the telegraph wires at least 12V-24VDC and on long runs up to 100V DC.

    • Has anyone written any sort of a “Hackers of the Old West” type graphic novel? With all the popularity of Steam Punk in the last couple of decades, it’s surprizing I’ve never run across something like that…

      • If you like magic in your “Hackers of the Old West” novels, look up the Mistborn series.

  • Why adjust stop bits (1, 1.5, 2)? Back in the day, the hardware wasn’t always fast enough to get one byte out of the way and to the next stage of processing in just one bit-time. After all, at 110 BPS, that’s less than a tenth of a second!

    Similarly for start bits. Sometimes it took more than one bit-time to get the shift register loaded.

    Now I miss the ASR-33 I had hooked up to my Commodore 64. What a friendly sound!

    • Oh, man. I remember being in 4th grade doing multiplication drills on one of those. That sound will be with me the rest of my life.

    • I can see many areas in which adjusting start/stop bits would be necessary. Let’s say I have a UART hub. In order for me to do pseudo-addressing, I would need to know which data goes where. If all UART comm was 8n1, data would go in whatever flow control I have it put in. By adjusting start/stop bits, you can do some pseudo-addressing.

      Another reason to have adjusted start/stop bits, if you suspect the Rx/Tx lines are going to be affected by noise (even then you’d want to do parity).

      These are just a couple ideas, because the hardware now is running faster and faster, and requires more of the designer’s attention to designing communications. People that use the Arduino code have it easy, because you just write a few lines and you got serial, but you don’t know what is going in the background. What if you wanted to do check for other flags that the UART can use?

    • Or to do a carriage return and/or linefeed (which has nothing to do with rental cars or fishing).

  • Nice one as usual! I’m already waiting for the I2C and CAN Bus version :)

  • Thanks lad, love your posts! Keep up the good work!

  • Thanks for the clear explanation, had to get past the odd speech style, but still learnt alot.

  • Love your vidz. Please keep it up.

  • Back in the good (bad?) old days when noise was a big problem (especially over lengthy cable runs that picked up interference), the parity bits were used to determine if the data was truly valid. One parity bit was usually sufficient and if “most” bits were a 1, then the parity bit would be high (if most bits were low then parity would be low). The problem was that if noise made the parity match what was expected (even with bad data bits) then it would be interpreted as a valid byte. The addition of the second parity bit as a check against the first helped (mostly) eliminate any false parity checks (chances were very low that noise would make both parity bits the same value). Again, this was back when shielded wiring was a luxury and a lot of serial communication took place over ribbon cable. Generally speaking, the “noisier” the line, the more parity and stop bits you used to make sure you were getting valid data.

    With that being said, since most data “back in the day” was transmitted at very low baud rates due to the high equipment costs and bad lines (75/110/300/600/1200 baud) it was expensive in terms of throughput to add all of these stop and parity bits (essentially “throwaway” bits if the data was indeed valid) since they could consume almost 1/3rd of the total bits sent. Hence the 8/N/1 (8 bits, No parity, 1 Start bit) over good quality lines since it allowed the most information to be “packed” into the smallest number of bits sent. Just a little history there.

    As Pete asked “Why would you choose Even or Odd Parity?” I actually had several occasions where the noise on the line (back in the day) would tend to spike either “Low or High” most of the time. Choosing a parity opposite of where the noise or spikes would tend to be would help eliminate a lot of bad frames - again, showing my age.

    Noise is generally not a problem now with well-shielded wiring but remember that the protocol does not determine the method of transfer. You can use the RS-232 (485, etc) protocol through IR, Radio, Optical Fiber or anything else you can think of (with its own set of “noise” so that should give some idea about the reason for all of this parity and start/stop bit discussion.

    And one last tidbit: The “while(!Serial.available())” in the arduino is just a check against a bit to indicate a full byte has been received into the buffer.

  • Good tutorial. I work on industrial automation and am having to learn the basics of serial communication, RS-232 and RS-485, and Modbus. Good info. I also like you comment about engineering falling back on the fundamentals of how things work. Yep. We are problem solvers.

  • Siiick! Psyched for I2C and SPI.

    UART: Demystified.

  • I have a software UART for AVRs using the ICP for Arduino and ATtiny4313 on http://harleyhacking.blogspot.com to talk to my Valentine 1 radar detector.

    8n1 sending Us will create a nice square wave (how I originally did the remote IR carrier on the Palm Pilot).

    Where is the discussion of the break signal?

    It isn’t 3.3v, look at the RS232-c spec - it is +/- over 3v, usually 6-9.

    You can (sometimes) share UART devices, but it requires some hardware tweaks.

    Automotive J1850 is variable pulse width serial - think open collector. ISO9141/14230 is plain UART, but typically at 10400 baud.

    I remember the ASR-33, where can I find a font with the curvey letters?

    To test crystals or resonators syncing, heat or freeze them.

    ASCII is 7 bit, EBCDIC required 8, but it included the cents \c sign and a sideways L for logical not.

    I had an Anderson-Jacobson daisy-wheel that could move fractionally both vertically and horizontally in both directions.

    I once did a video on cereal communications but it ended up too grainy, perhaps too much milk in the Alpha-Bits. Double Bufferin fixes headaches and dyspepsia. There once was a serial daemon that was set so it ate-one-nun.

  • Parity bits aren’t used much because there’s nothing to do about the error. The hardware layer isn’t that useful of a spot to catch the error. These days, errors are usually detected at a higher layer, where a resend can be requested. The UART counts the 1-bits in the message, the parity bit is then used to make the total even or odd, depending on how it’s set. It’s not particularly good at catching errors, either. Parity was just a bad idea and that’s why no one uses it any more (well, I’m sure SOMEone does).

    • The parity bit is used for checking the integrity of the data being sent/received. If the data being transmitted/received has the wrong parity, how else would you discard the data? Without the parity, you’d be getting garbage, and that could be the difference of making a robot serve a human, and not serve them for dinner.

      Yes parity isn’t used much anymore, but other serial transmission types (eg PCIe), needs the parity in order to determine clock speed, and data integrity.

      • I think most likely parity was used initially more due to hardware speed limitations. I have no concrete proof of this though, except when I started in serial coms back in 90 it was more prevelent in discussions. When computers became faster, and could use faster baud rates reliably, the PC at that point could relaibly run 115200 most of the time if needed, then wrapper checksums or error correction were added to the prototocols. This moved the error checking up several layers. Also, RS232 is general used in “quiet” environments. In more industrial settings, RS485/422 is used as it is more bullet proof on the hardware side ane more resistent to noise.

        • In the ‘70s, a VERY used printer (teletype) cost several hundred and had no processor. If parity failed, the character was printed as blank. You also had to send several NULLs so the printer could perform a carriage return. But, 110 baud was faster than I could type back then.

  • If you cover this again, you may want to consider adding information about:

    • buffering, most modern UARTS and a lot of micro’s have an on chip buffer.
    • The 8250 and 16550, as it’s simple to tell the capabilities of a device when they claim to be compatible with those chips.
    • Underrun and overrun errors. Overrun errors in particular are difficult to deal with at times. Not that you would see overrun errors @ 9600 with your code !
    • Breaks and Marks. Break can be useful for signaling, the popular lighting control, DMX uses an 80us break, followed by a 8us Mark
    • Address driver chips. Some ( all? ) micro’s have logic level UARTS and will need a driver, such as a MAX232 to comunicate with a PC, but would be fine micro to micro.
    • I’ve blown lots of driver chips over the years, especially 485, and you can occasionally take out a UART as well, but if the driver is doing it’s job, and is opto isolated, it should be OK.
    • you didn’t mention connecting RX to TX and visa versa !
    • Most of what you’re talking about is a bit beyond the scope of one short video, but yes, all good points. Except I think I did mention TX to RX, though very briefly.

      • You mentioned crossing Tx and Rx a.k.a. null modem. I still have drawer of dusty adapters for rs 232.

  • Just a note about Serial.read(), you don’t need to provide a variable. Just because a function returns a value, it doesn’t mean you have to provide a variable to store it in.

    void setup()
    {
      Serial.begin(9600);         // Setup serial at 9600 baud
    }
    
    void loop()
    {
      while(!Serial.available()); // Wait until data is received
      Serial.read();              // Remove the data
      Serial.write('K');          // Write a "K"
      delay(5);                   // Delay 5ms
    }
    
  • Wow. I never knew that UART was so simple(ly complex).

  • An engineering degree: $60k problem solving degree.

    Best way to understand USART is to understand encoding types. UART has the 8n1, but USART will have to encode more bits. From here, the master will be looking for a set of bits in a specific order, once it finds that order it knows it’s got a frame to work with at a specific rate.

    Best way to understand this is to look at PCIe and how it uses 8b/10b. It takes 8-bits of data and encodes it to 10-bits. Now, from an efficiency standpoint, 8b/10b is not very efficient, it has large overhead. So how do you remove this overhead? YOU ADD MORE BITS! In PCIe Gen3, you got a large # of bits being encoded in a specific way to get the high clocking speeds.

    Hope that helps explain USART. In all reality, stick with SPI/I2C for synchronous comms.

    • Thanks for that. Regarding the degree being $60K, work a job in electronics to help pay and educate yourself, only do 12 credits per semester, get married to somebody who’s also working, and don’t have kids until you’re done. Oh, and make sure you’re a resident of wherever you go. I eeked it out without any debt, but a lot of late nights.

  • You should allow us to download these videos. I can’t watch youtube at school :(


This Week

This Month

Heartbleed

Happy Arduino Day!