Almost any voltage with QC



You might also want to check :


Kicad 8 projects and Arduino code : QC_Fab.zip

QuickCharge using tiny412

The QuickCharge protocol lets you “negociate” voltage through USB on smart power supplies.

This page is a short documentation about my journey testing QuickCharge capabilities. I did it for myself and mainly for learning purposes.

I like things small and efficient. This is why this project is ATTiny412-based. (could actually be even smaller/simpler processor). The board was redesigned to make it very “Fab-able”.

You might also want to check the XIAO QC version, allowing the same protocol to be used through MicroPython, as a portable selectable power supply with rotary encoder.

Long story short (TL;DR;)

The code was written to be as compatible as possible :

All the “fast chargers” tested so far are compatible, even when only declared as PD (not explicitely QC) - read dedicated section to know the difference. However, some appeared to be CLASSA only (12V max) when used with QC even though they can deliver up to 20V when used in PD mode. Also, some were able to ramp up to 20V in continuous mode but not as QC2.0 standard voltage (asking for 19.9V will to the trick, for example). Strange.

QC protocol

Please refer to the dedicated documentation page if you want to learn more about the QC protocol.

The board

The schematic is pretty simple (USB only view) :

  • D+ 0.6V voltage is realized by a resistor bridge (R1 and R2) when the corresponding pin is set as an input. When set as an output, the pin imposes its own voltage that can be 0V = LOW (actually never used) or 3.3V = HIGH
  • D- 0.6V is realized by the ADC (code will automatically select available internal reference). Instead of changing the ADC value to get the 0V or 3.3V, we simply set the pin as a digital output when needed.
  • two 1k resistors protect the lines in case something goes wrong

The full schematic includes :

  • a 10k (or reasonably close, not critical) potentiometer - RV1 - to provide a selectable input readable by an analog pin
  • a resistor bridge (R6 and R7) to divide the VBUS voltage by 11 : we’ll do the more complex maths later. (see notes about ADC on the sense pin)
  • a 3.3V regulator and its capacitor : this value has been chosen to ease the output voltages values on D+/D-
  • and of course our cute and lovely little atTiny412 and its UPDI access for programming

Before you go further, I strongly recommend that you have a look at the code and know your goal as you might not want to populate the entire board depending on your usage.

I packed everything together. And I still use thick traces [min 0.64mm, usually more, especially on power lines]. Thick traces are easier to mill (with more than reasonable 0.5mm clearance), more robust and handle more current and force. So why would we wear out our bits removing more copper?

Hero video

And this is working just great!

Notes and comments

An arduino library exists but doesn’t take advantage of DAC and will be more resources/hardware/pins-consuming.

“Indication” LED

I added an “indication” led that lets me have a very rough idea of the voltage : with a 10k resistor the led will be very shy at 5V and be more visible when approaching 20V. This value might be adapted for ClassA. (3k3 or 4k7 probably are good values for ClassB, I didn’t test)

Stronger power lines

I put a quite thick solder cover on the power lines between my USB connector and output terminal block. This is because I want to make sure that my traces will handle high currents without resistance. It makes my board uglier but more reliable.

Resistor divider, ADC timing and maths

R6 = 47k and R7 = 4k7 form a resistor divider by a factor 11 : those values were chosen to ease components list (10x multiples are very common in stocks) and let VBUS reach 20V (or more) safely :

Using high impedance resistance devider will sink less current but will maybe require small ADC timing adjustments and/or parallel small capacitor (e.g. 100nF in parallel with R7) to avoid noise on the sensing pin.

This voltage sensor is used as a feedback.

Getting the value in dcV from the voltage divider requires some maths :

So we should compute a 11x33/1023 ~= 0.355 multiplication to get the actual voltage in dcV from the ADC conversion. This is achieved by approximating 0.355 by ( 1 + 1/2 - 1/16 - 1/32 + 1/64) / 4, that is “quite” easy to compute with limited computational resources. This code complexification is the (not-that-high-)price to pay for high code compatibility and versatility on a chip with limited resources.

“Universal” UPDI access

I put a “double” foot print on the board to reach the UPDI pin : you can either solder a 2 pins 2.54mm SMD header to get your GND-UPDI contacts, or solder a unique through hole pin. This last solution gives more robustness for testing purposes and will work fine if you connect your GND reference into the terminal block (or if you’re connected to a USB port with the same GND reference).

I actually solder a UPDI connector for testing purposes only. On my end board I usually simply program my code by pressing a wire on the UPDI pad and leave it unpopulated.

Drilled USB connector versions

I added a drilled USB connector version. I’m not a huge fan of using those, especially for power-related boards or testing purposes.

Updated USB connector version

The updated USB connector version allows multiple options for USB connector or cable.

You can either connect a “classical” USB-A connector (SMD pins).

You can solder a USB-C module (for example those). Check pinout before! This is my new favorite version.

You can also solder a scavenged USB cable.

Do NOT connect a through holes USB-A connector (you will have to force it AND the pinout is reversed!)

Wide power regions

I intentionally created wide power regions on the top : this allows one to solder wires instead of populating with a terminal block connector.

Conclusion

This - very - small board allows me to get - almost - any voltage using very minimalistic hardware and works on most smart power supply. Playing around with my different chargers let me know more about their real (and sometimes surprising) characteristics. When all I need is 12V, I now can get it easily on - almost? - any charger (even external batteries).

This gives me food for thought about my box of “chargers I keep just in case” I need a specific voltage…

Is it about to become old XX’s century stuffs?

Files

Kicad 8 projects and Arduino code : QC_Fab.zip