Software Half Duplex UART for AVRs

One Wire Serial

If you have worked with very low cost microcontroller in the past, such as the ATtiny series from AVR, you’ve probably been stuck without a UART peripheral. The usual answer to this problem is to implement the UART in software. It’s not fast, but it works.

Lets say you’re even more limited on resources, and only have a single pin for UART. [Ralph] created a software library and a small circuit that enables half duplex UART using only one pin. With the above circuit, and a 62 byte Arduino compatible library, you can add UART to the tiniest of ATtinys.

In this circuit, the Tx/Rx pin is on the AVR, and the Tx and Rx pins are another device. The circuit relies on the idle state of UART being a logic high signal. When the Tx pin is idle, the transistor stays on. This allows the Tx/Rx pin to pull Rx low when the AVR sends a 0. When the Tx pin sends a 0, the Tx/Rx pin gets pulled low through the diode.

It’s a clever hack, and could definitely help add communication to your next tiny project.


  1. gajiop says:

    You could use it as a fancy toilet door status indicator.

  2. says:

    Aww, that nice. But when we throw away crazy AVR crippled with Arduino we can use better controller like 8051 from Silabs –
    5V tolerant IO,
    low price,
    on-chip debug with real IDE,
    flexible pinout – runtime swapable – RX/TX trick, accurate integrated xtal…


  3. says:

    But still a nice hack, love this.

  4. rj says:

    Possibly needs any overvoltage protection: right now, if connected to a ±12V RS232 line, it’ll use the overvoltage clamps of the microcontroller.

    Regardless, needs current limiting in case of collisions.

    • tekkieneet says:

      The description doesn’t say if the other side is for EIA232 signal level
      or logic level. It doesn’t seem to invert logic level, so I am incline
      to assume this is for chip to chip.

      The old MC68HC908 uses a half duplex software UART for bootstrapping. I
      used a 2 stages of inverters connected in series. I use a 1K series
      resistor on the uC side to protect again logic contention. It is
      connected to the middle of the inverter chain so that it can read the
      EIA232 Rx signal. When the pin is set to output, it override the signal
      level and drives the 2nd stage to “EIA232″ (5V) level.

    • tekkieneet says:

      For a TTL to TTL level half duplex solution, all you need is a 1K
      connected between the Tx and Rx. Your uC is connected directly to the Rx
      pin. When the uC set its pin to output, it overrides the signal level
      coming from the 1K.

      • Ralph says:

        The problem with that the Tx transmissions loop back to the Rx, and so will corrupt communications unless you change the software on the other side to ignore the loopback echo. My solution will work with unmodified bootloader downloads, etc.

  5. theLyonsMane says:

    This is pretty neat.
    If I remember correctly, a lot of the ATTinys have a USI peripheral that can be modified to act as a half-duplex UART, so you do have a hardware solution.
    (I found a forum thread on the matter:

    • Ralph says:

      I wrote a UART using USI as well, but it used more code. The USI transmits the high bit first, so bit reversal code is needed. The only way I could get the code size within a few bytes of my bitbang serial was with 71N communication instead of 81N.

  6. Bogdan says:

    The thing about this is that it is not worth in a real application. You are better off upgrading to a better micro and. Even if you don’t have enough pins it is better to implement it some other way in software, like 1 wire or even something simpler.

    • kennedybushnell says:

      I disagree Bogdan. I use ATTiny’s all the time when I only need a couple of IO pins. Having a UART is wildly useful during the development process (at least I love it). I can’t wait to try this on my next project. :D

    • Torque says:

      Good job at berating something inspired by the hacker mentality.
      You’re on the wrong website.

      • Bogdan says:

        1. I challenge you to achieve the same functionality with only one resistor (that’s 3X less components for the additional functionality)
        2. If this were a commercial application, it will probably cost you more to add the three components than to upgrade the micro.
        3. If it is a hobby thing and space if of no concern, there is no justification for buying a 1 $/EUR tiny micro instead of one @2-3 much better and spending time worrying about all the pins and resources you don’t have and how to get around that.

        • Per says:

          Spoiled brat ;)

        • camerin says:

          1: implement in software, use as debug only, 1 test point is added, cheaper then 1 a resistor
          2: it would be able to be on a commercial product, allowing for debug, and concealing it for security.
          3: using a small micro, and exposing 1 test pad makes your device smaller. Maybe i want my package to be <1 square cm and have a bunch of sensors. I could use the single wire in the test fixture, and still have most of the pins open for sensors.

        • tekkieneet says:

          #1, see my previous post.
          #2. Not always true. Parts volume can skew the result a bit. If there
          are other projects that uses jellbean components or that particular
          smaller uC, they would lower the price a lot. There are a lot of
          incensitives to use the common components. Also you buy BJT, diodes,
          resistors in Tape & Rells of 5K vs much lower volumes for uC.

        • voxnulla says:

          You can make bullet points all you like, unless you come up with something that negates the fact that you have indeed berated something inspired by the hacker mentality, as Torque so eloquently put it, you will remain the odd one out.
          I’m fairly sure that a good hack does not require to be cheaper or easier than any commercial alternative.

          • matt says:

            Hacks arent always a good thing. And just because it was inspired by the hacker mentality doesnt make it good either.

          • voxnulla says:

            That is also true, but in this case I haven’t seen a solid argument as to why this would not be a proper hack.

        • TacticalNinja says:

          Also, It does not necessarily mean that those three components need to be on each micro (if it were to be mass produced as a commercial product), since those components can be attached in-line with the UART cable/reader/whatever.

        • Ralph says:

          SMD resistors in production quantity (10K+) sell for ~1/10th of 1c ea. SOT-23 transistors <.5c, and the diode about .5c, so just over a penny for the parts.

  7. George says:

    Very nice. Looking forward to a little attiny25 project.
    Thanks for sharing.

  8. cpldcpu says:

    Actually you can also simply tie TX and RX together. In that case all data will be echoed, but that can easily be handled in software on the PC side.

  9. Myndale says:

    Love it! Just outta curiosity what would be the benefits of using this over, say, a single 8-pin AVR running off its internal oscillator? More convenient trace routing is an obvious one, and I’m guessing power consumption might be another (yes? no?)…any others? Either way, great hack!

    • Juno says:

      Internal oscillators are known to limit the data rate of anything that relies on accurate timing, such as serial comms. It’s OK for hobby projects, if you’re lucky you’ll get 38400 bd; if you’re unlucky you’ll have problems above 2400 bd.

      • Ralph says:

        Actually I did all my testing on ATtiny85’s running on the internal oscillator. I got stable communications up to 460800 with the t85 running at 16Mhz. And that’s without any OSCCAL tuning.

        • Ralph says:

          And if you want to use 460800 @16Mhz, the timing error would be too high using a hardware UART.

          • juno says:

            Hi. Could you provide some background on your testing? The problems I’ve encountered is that a change in temperature (e.g. after running for a while in an enclosure) changes your error %. So I always end up reducing the rate to get back in the safe zone.

            Very handy site you posted!

          • Ralph says:

            When running off the internal RC oscillator you will get some frequency changes with temperature (for the ATTiny85 see Figure 22-41 in the datasheet) I put comments in the code regarding the timing accuracy:
            “2%/1% Tx/Rx timing error for 230.4kbps@8Mhz”
            Any timing outside of 5% is likely to cause a framing error (by 10 bits you’re off 1/2 a bit), so the sum of the RC oscillator variation and timing error should never get near 5% if you want to avoid errors.
            The code using 19.2kbps@8Mhz has 0.3% timing on transmit and 0.2% timing on receive, so that will give you the best results when running on the RC oscillator.

      • Ralph says:

        You can maintain the internal RC oscillator accuracy within 1% over a wide temperature range by reading the internal temperature sensor ADC channel and then adjust OSCCAL.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 96,615 other followers