UART between 5V and 3.3V

I'm working on connecting to an AC unit over UART using an ESP32 with Arduino libraries. The AC uses 5V and its TX is open-drain. I'll have about 10 feet (3 meters) of four 18AWG wires from the AC to the ESP32. UART is at 2400 or 9600 baud. I'll build 4 boxes, each with 1 ESP32 and controlling 1 or 2 AC units.

I don't have the luxury of testing, as the house is still being built. I need to build a solution beforehand and when the house is ready, hopefully I'll have AC right away. If that fails, I'll redesign and can test more at that time. I'm asking for your advice to increase my chances of success on the first go!

SwiCago/HeatPump

I'll use the SwiCago/HeatPump library for the UART communication. There's a lot of discussion there, but not about using an ESP32 or a 10' cable. I will stick with the ESP32 (a wESP32 actually) because my ESP32 will also be doing other things and I want ethernet and PoE.

The demo circuit works for an ESP8766 because it has 5V tolerant GPIOs. There are claims the ESP32 is 5V tolerant but I would rather stick to the datasheet and 3.3V. This post seems useful, but I'm inexperienced and it's important my circuit works.

I've been reading for days and there's lots of ways to solve this, depending on all sorts of things.

Level shifters

First I looked at level shifters. This requires connecting the AC and ESP32 grounds. That should be OK, but possibly not. I can't test at this time to be sure. Also I'm not sure if the grounds test OK that they will always be OK. Should we assume the grounds can be connected without issue, or should we look for an isolated solution?

Back to level shifters, I can build my own but my experience and confidence are low so I looked at ICs. The TXB0102 is bidirectional which isn't necessary for UART but could still work. However, being bidirectional makes it sensitive to capacitance and it may not like my 10' cable. The TXS0102 appears to be a better solution, as it mentions UART in the datasheet. Still, I think both are intended to be used on-board. Is the TXS0102 likely to work with my 10' cable?

I know my 10' cable isn't a great idea, but I'm hoping it will work. I looked at a proper transmission line setup using RS-485, but then I'd need electronics at both ends. I could do that if ultimately necessarily, but if the 10' cable can work, that is much simpler. Remember, I have 6 AC units.

Also, do I really need an IC for my situation? I'm happy to use an IC if it provides more reliability or other benefits, but I don't want to make things unnecessarily complex.

Sending 5V

After connecting grounds, I could connect my ESP32 TX directly to the AC RX. The AC expects 5V, but the 3.3V should still be high enough for 5V logic high. Would it be better to send 5V over the 10' cable? If so, maybe I don't want to use this solution.

If I understand correctly, the ESP32 TX is driven actively by default. The ESP32 supports open drain output via pinMode(pin, OUTPUT_OPEN_DRAIN). Is it possible to use that with the Arduino Serial class? If so, I could pull the ESP32 output up to 5V so I have 5V over the 10' cable. I think I would need a diode to protect the ESP32. This is getting over my head, but I'm happy to learn. Is a Schottky diode the right choice?

Receiving 3.3V

This seems easy: since the AC TX is open drain, I can just pull it up to 3.3V with a 10K resistor (diagram). Again this means I'm using 3.3V over the 10' cable and I don't know how much more susceptible to noise that is than 5V.

Optocouplers

I read optocouplers can be used to isolate UART, sometimes, but I don't know what parts would be acceptable for 9600 baud. I have some LTV-846S (datasheet) on hand, would that work? How does this look?

I like the optocoupler solution because it's simple, there's no chance of a ground loop, and I have 5V over the 10' cable.

Sorry this got long!

The solution is relative simple, they make transceivers for this. You can use (CAN very reliable), RS484, RS232, and others. These devices can be used without regard to the voltage of the processor on the other end as they have their own specified communication voltage which the transceivers use. Since you have some time consider the MPC2515 CAN modules, you can add to the network any time you like and they are under $5 in the US. Be careful with the modules when using 3V3 not all support it but you can change the transceiver chip. The nice thing about this is you can add modules any time without changing any existing modules unless those modules have to communicate with the new module (software). I use Cory J. Fowler's library at: "GitHub - coryjfowler/MCP_CAN_lib: MCP_CAN Library", it worked the first try. Run CAN-H, CAN-L, and Ground, ground helps with debugging.

You state: "I don't have the luxury of testing, as the house is still being built." That is what this recommendation is intended to do allow you to build it, test it then install it later and operate with the least amount of problems. Level translators etc do work but! 10' cable will work for sure if you are in a faraday cage. Without knowing your environment electrical and thermal I will say no it will not be reliable. You state: " if it can work with a 10' cable without a transceiver on the AC side, that'd be ideal." A 10' antenna can couple a lot of junk into your logic.

As I understand, this would require electronics at both the AC and ESP32. I have 4 ESP32s and don't mind doing whatever electronics needed on that end. I have 6 ACs, so I'd need 6 more PCBs and I guess an MCU for each one? I can do that if really necessary, but if it can work with a 10' cable without a transceiver on the AC side, that'd be ideal.

I keep saying 10' since that is the worst case, but it's 3' and 6' for some ACs.

Here is the official solution from Mitsubishi:


I can't find it specified anywhere, but that looks like at least 3' of cable. Apparently they are successfully using ~3' commercially for many thousands of customers. Some of my runs are 3', so I'm OK for those. A transmission line with RS-485 or similar would be ideal for a longer run, but might also work fine without.

I'd like to try without a transceiver and add it only if needed. Given that, does my optocoupler circuit look correct? Or is there a better solution without adding electronics on the AC side?

I hooked up an LTV-846 (EDIT: see next post, this schematic is no bueno):

Results at 2400 baud:

D0 and A0 are taken just before the resistor. D1 and A1 are on the other side of the optocoupler. It doesn't look great. D1 did recognize the signal correctly, though the dots aren't nicely centered like they are in D0.

It has errors at 9600 baud, which I'd like to support reliably, if possible:

Looks like it's taking 481us for the LED to turn on strongly enough and/or the photoresistor to reduce resistance significantly.

That seems a crazy long time, no? Datasheet says 18us rise/fall time (using other parameters):


The 3.3V and 90.9ohm resistor with a 1.2V drop for the LED should give 23mA.

Am I doing something wrong? Or is it that this optocoupler isn't suitable for UART?

Alright, it works much better like this:

Here's 9600 baud:

The same but 470ohm pull up:

1K pull up looks pretty OK too. I've also tried decreasing the current through the LED, replacing 90.9 even with 1K still looks OK. That should be ~2.1mA. Maybe 470 is a better choice, 4.47mA.

Here's 9600 baud, 1K pull up, 470ohm for the LED (I think this is the one!):

The same at 19200 baud (I'll never go about 9600):

Fails at 38400:

I think this is the way to go, pending any new feedback from ya'll! I do wonder a bit how differently my ACs might interpret the UART, they might not be as flexible as the logic analyzer. I don't know what a "good enough" UART square wave looks like.

Why not build a QBF and test the length of the cable at 9600 BAUD? My guess is the UART in the AC will be as-good-as the Arduino? So, just to a loopback and see if you get what you are sending.

The QBF - "The Quick Brown Fox..." For Serial Diags - Community / Exhibition / Gallery - Arduino Forum

PS: these work well ... and cheap.
SparkFun Logic Level Converter - Bi-Directional - BOB-12009 - SparkFun Electronics

That's a good idea, thanks! I have an extra MCU, I can run an 18AWG cable across the room, maybe past the microwave, and see how it works.

I use cheap Cat5 or Cat6 scraps from old runs. The S/R pairs are already twisted and you have 100% redundancy :laughing:

My 18AWG cables aren't TP. Is there any advantage when I'm not doing differential signaling?

I did tons more testing, but I'll spare you guys the screenshot adventure. :smiley: I found that 470R for both LED and pull up resistors worked best. Higher or lower on either one worsened the square wave in various ways. She looks like this at 9600 baud:

The only downside is LOW is ~380mV while the original signal is ~85mV. Rule of thumb seems to be a safe transition voltage threshold is ~30%, so I should be OK at 0.38/3.3=12%.

I tested it all the way up to 256000, where it failed, but it works at 128000 baud! That's a pretty great result I think, since I'll use 9600. The wave looks bad at such high speeds and LOW is ~537mV, but it does work:

I had researched optocouplers specifically for logic output, like the 6N136, but now I'm confident my LTV-846 will work fine at 9600 baud. FWIW, I came across this post of optocoupler tips that was interesting.

Finally, I ran the serial data at 128000 baud through a reel of 250' of 18AWG wire to a second MCU and it received just fine. I unspooled about 20' draped around a computer under load and a bunch of mains plugs, still fine. This is 3.3V, not 5V, and isn't the same environment the AC units will be in, but I think it has a pretty decent chance of working fine.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.