I recently ran into an interesting issue developing my dawn simulator lamp (full project details coming soon): the HC-05 module I was going to use really didn’t play nice with the hardware UART peripheral on the Arduino Nano.

Why not use software serial like the countless other tutorials on the HC-05 on the Internet suggest, you may ask. Well, its because this project uses WS2812B LEDs, which are a real pain when you have to do multiple things that require precise timing (both RS232 and the WS2812B’s communication protocol are asynchronous) on something like an Arduino Nano, which isn’t particularly fast, has limited peripherals, doesn’t have a DMA… you get the idea. In order to ensure reliable communication when the microcontroller is tied up updating the LEDs, the hardware UART was the best choice.

Which meant that the HC-05 would have to share the same 2 pins as the onboard USB to Serial converter. But, I also had to ensure that neither device would interfere with each other, as I wanted to be able to upload sketches to the board without having to disconnect the HC-05 module every time.

Using resistors to “OR” both signals together

My first thought was to use a resistor to act sort of like an OR gate. That idea quickly went up in flames, as it seems like the CH340 chip used on my cheap Chinese Arduino Nano clone just does can’t pull its TX line down hard enough when the additional pullup of the HC-05 is in parallel with it, even with a series 220Ω resistor. Annoyingly, increasing that resistor further hindered the HC-05’s ability to drive the line past the logic low threshold level of the Arduino Nano (the ATMEGA328P has a guaranteed logic low threshold of 0.3VCC, which is 1.5V for a typical 5V Arduino Nano).

Probing the RXD pin of the Arduino, with a series 220Ω resistor and sending in an ASCII “1”:

HC05 RX waveform with 220R resistor

The HC-05 just doesn’t even manage to get under 1.5V, the Arduino still picks up the data however. (Don’t mind all that stuff after the “1”, my Bluetooth serial monitor app sends a carriage return and line feed automatically).

CH340 RX waveform with 220R resistor

The CH340 is just a goner at this point.

Increasing the resistor to 1KΩ caused issues of its own:

HC05 RX waveform with 1K resistor

The Arduino no longer registers what is being sent by the HC-05.

CH340 RX waveform with 1K resistor

The CH340 gets a pass on this, but I still wouldn’t trust it to be reliable at all.

The solution: Diode OR-ing

Using a jellybean 1N4148, I was able to get both the HC-05 and the onboard CH340 to talk to the micro properly.

Diode OR gate schematic

Probing the same RXD pin on the Arduino, but this time with the diode in place:

HC05 RX waveform with Diode OR

HC-05 with the Diode OR.

CH340 RX waveform with Diode OR

CH340 with the Diode OR.

Both are now able to communicate properly with the Arduino. It seems like the ATMEGA328P does have some wiggle room when it comes to its logic-low threshold. Even with what is essentially nothing else connected to the Arduino, the CH340 just manages to squeeze below the 1.5V logic low threshold.

And yes, I am able to upload sketches to the Arduino without any issues, including all the verification steps that. The HC-05 seems (unsurprisingly) unfazed by the uploading process, just spewing out a ton of garbage when the Arduino program reads back the memory of the microcontroller.