Many new mobile devices now feature an USB-C connector. In order to connect these devices to USB devices or chargers with a USB-A or Micro-USB connector, you need an adapter or cable with USB-C plug on the one side and USB-A/Micro-USB connector on the other.
As first discovered by Google engineer Benson Leung, many of these USB-C to USB-A/Micro-USB cables or adapters do not conform with the USB standard allowing USB-C devices to draw excessive power, which might damage the host or charger permanently.
Recently, I bought a Nexus 5x featuring a USB-C connector and now faced the problem of figuring out whether my USB-C to USB-A cable is conforming with the standard. So I bought a USB-C connector (actually, not so easy to get as I thought) and tested my cable with a multimeter. Of course, this works fine, and fortunately, my cable was OK. Then I thought: Why not build a little device to quickly check cables without multimeter? Just plug in the cable and see whether it is OK or not.
That’s exactly what I present here: an Arduino-based device to check USB-C to USB-A/Micro-USB cables and adapters for standard conformity. Two images of the board are shown below. It’s not very complex at all as you will see, and I don’t claim this to be rocket science. It’s just a little practical tool. Everything is completely open source, the code as well as the hardware design (printed circuit board), and you can download both from my Github repository.
I don’t want to repeat everything that has already been said elsewhere. However, to keep this page self-contained, I quickly describe the problem in plain words so you can easily understand the solution.
USB-C allows the USB host or charger (called downstream-facing port, DFP) to signal to the powered USB-C device (called upstream-facing port, UFP) how much current it can provide. This is implemented by a defined current flowing from DFP to UFP over the CC (Channel Configuration) line of the USB-C connector. 80 µA +- 20 % signal “Default USB power” (900 mA for “Super Speed” devices), whereas 180 µA +-8 % signal 1.5 A, and 330 µA signal 3.0 A.
So far, so good. A USB-C host or charger will know how much power it can provide and signal the correct value by sending the corresponding current over the CC line. The problem starts with “legacy” devices with USB-A or Micro-USB connector. These connectors don’t have a CC pin, thus, the host or charger cannot signal to the USB-C device how much current they can provide. In this case, the current on the CC line is “generated” by the cable or adapter using a simple resistor RP connecting the 5 V line to the CC line of the UFP. You might remember: R = V/I. So by selecting the right resistor in the cable/adapter, a certain current ICC is flowing through the CC line. Actually, the UFP connects CC through another 5.1k resistor (RD) to ground, so you have to consider the series resistance of RP and RD when calculating ICC. RP = 56k corresponds to about 80 µA (corresponding to “Default USB-Power”), RP = 22k to 180 µA (corresponding to 1.5 A), and RP = 10k to 300 µA (corresponding to 3.0 A).
Note that now the adapter cable rather than the upstream USB host or USB charger is defining the maximum current the downstream USB-C device can pull! However, the cable cannot know to which host or charger it will be connected and how much current this host or charger can actually provide. So the only safe choice for RP is a value resulting in 80 µA on the CC line corresponding to “Default USB Power”, i.e., a 56k resistor. Unfortunately, some cable and adapter manufacturers don’t use 56k resistors but lower values like 10k resistors. If your host can just provide the required “Default USB Power”, it might get grilled.
Now that we know what to check, we can build our USB-C-Adapter-Tester shown on the images above. This tester consists of a microcontroller (Atmega 328p; same chip as used by the Arduino UNO) featuring an Analog-to-Digital Converter (ADC). The ADC measures the voltage drop along a 5.1k resistor (actually, two separate 5.1k resistors on different channels of the ADC since USB-C features two CC so you can plug-in the USB-C cable either way). Knowing the resistance and the voltage drop measured by the ADC, the microcontroller calculates ICC. If ICC is within the specified range (80 µA +- 20 %), an LED signaling a “good” cable is turned on from an GPIO pin. If it is outside the range, another LED signaling a “bad” cable is turned on.
The cable to be checked is also powering the microcontroller from the USB host or charger. The good old Atmega 328p can be powered from 5V, which is the voltage of USB-A and Micro-USB.
Since the internal voltage reference of the Atmega might not be very precise, I used an external 2.5 V voltage reference diode to provide a reference voltage to the ADC. If you trust the internal 1.1 V voltage reference of the Atmega, you can save this part.
As said, the USB-C connector was a little hard to get, but I finally found one at an E-Bay shop.
For the implementation of the code, I used the Arduino platform. The device is programmed through a standard 6 pin in-system programmer port.
As soon as you plug in the cable under test, the microcontroller starts measuring the voltage drop, translates it to current, compares it to the specified range, and switches on the corresponding LED signaling a good or bad cable.
If you want to etch the PCB yourself, I provide the Eagle files in the Git repository. Of course, you can also simply use a standard Arduino UNO instead of the shown PCB.
Several cables and adapters were tested with this device. The Micro-USB/USB-C adapter that came with the Nexus 5x phone was OK as well as my axxbiz USB-A/USB-C cable. Some Micro-USB/USB-C adapters were not OK (using 10k resistor instead of 51k resistors). Benson Leung tested many more cables if you are interested in what to buy.
I hope your USB cable is OK 🙂