Wednesday, June 21, 2017

How To: STM32F103C8T6 As An USB Device (Virtual Serial Port / CDC)


Cheap STM32F103C8T6 development board 

Blue STM32F103C8T6 development boards, also known as "BluePill", are cheap way to get started with 32bit ARM microcontrollers. The STM32 development board can sometimes be bought for less than $2 and ST-LinkV2 compatible programmer and debugger doesn't cost much more than that either.
The STM32F103C8T6 has nice amount of flash and RAM, runs at 72MHz and best of all: It has built-in USB. It is possible to program these STM32 boards to act as an USB devices, without "FTDI chip". In this post and in the embedded video I will teach step by step how to use the STM32F103C8T6 as an USB device, in particular a virtual serial port.

Sunday, December 11, 2016

Bitbanging the Quick Charge 2.0 - Without any ICs!

Qualcomm's Quick Charge 2.0 sounds like a cool technology: USB power supply can output 9V or 12V, if QC2.0 compatible device requests so. I have one power supply with QC 2.0 compatible port, but what I don't have is a QC 2.0 compatible device that could take the advantage of that port.
Initially I started researching the QC 2.0 technology, hoping that I could find an IC with simple interface that could be used to request the power supply to output selected voltage. Then I found out that doing those requests is easier than I thought and it could be done without any "QC 2.0 compatible magic ICs".


Information below worked in my case, but I cannot promise it will work in other cases. If it works, the USB-port starts outputting 9V or 12V, which may break devices connected to that port. If it doesn't work, voltages applied to D+ and D- lines may break something in the power supply. I don't recommend doing following things based on information I've shared, but if you are still going to do it, you are doing it at your own risk.

Quick Charge 2.0 Handshake

Handshaking between the power supply and the device is required before the power supply can take requests from the device.
Both the handshake and requests to change the output voltage happen by changing the voltages on D+ and D- lines. Handshaking has two simple steps:
  1. Device applies 0.325V-2V to D+ -line. During this time PSU may keep D+ and D- shorted.
  2. After D+'s voltage has stayed on above range for 1.25s, power supply discharges voltage on D- through a pull-down resistor. Device should allow the voltage on D- -line to drop below 0.325V, for example by keeping D- disconnected.

Requests to change the voltage

After the hanshake has been done, device can request other output voltages by applying following voltages to D+ and D- lines:

D+ voltage D- voltage Output
0.325-2V 0.325-2V 12V
>2V 0.325-2V 9V
0.325-2V GND 5V

If the voltage on  D+ drops below 0.325V, the power supply will consider device as disconnected and go back to default mode of outputting 5V. Handshake is required in order to change the output voltage again.


I made simple test circuit out of 3.3V regulator, few resistors and three jumpers. Two resistors form a voltage divider that outputs 1.1V and first jumper connects that to D-.
Another two resistors form  another similar voltage divider and second jumper connects the output to D+. Third jumper increases the output of the voltage divider that can be connected to D+ to above 2V.
I don't have a way to connect D- to ground, but disconnecting the D+ is another way to go back to 5V output.

Sources of information

The simplest description of using QC2.0 including above table was found in pages 6 and 7 of this Texas Instruments' PDF:
That PDF references this datasheet, which contains same information in more technical form:

Wednesday, November 16, 2016

Dimming with regular power switch - DIY 3-step dimming / DoRS


Light bulbs that are dimmable with regular light switch have many names depending on a manufacturer: DoRS (Dim on Regular Switch), 3-step dim, Free dimming, 4-step dim... They all have the same main concept: Switch lamp on and turn it off and quickly on again to switch the dimming level.
This same concept is used in flashlights which have multiple modes, usually couple different brightness levels and some kind of blinking mode.


To use power switch as an input for a microcontroller is easier than some might think. Connecting a resistor (lets say 100k) between GPIO pin and positive side of capacitor (maybe 47uF?) and connecting negative side of the capacitor to ground is all the hardware that is needed.

So, how it works?

Above is digram of voltages over time. Red line is VCC of the microcontroller, which is first turned ON and then briefly OFF and ON again. Blue line is voltage of the capacitor connected to one of the GPIO pins through a resistor. When microcontroller is powered on (points A and C) it reads state of the pin where the capacitor is connected. At A it reads as LOW and microcontroller knows it was powered off for a while. GPIO pin will be changed to output HIGH, which makes the capacitor start charging until it reaches the VCC voltage. That is the normal state, where nothing else will happen automatically.

After switching off the VCC, capacitor will discharge through the resistor and the clamping diode inside the microcontroller internal input circuit. If VCC is switched on before capacitor's voltage reaches lower limit where microcontroller reads input as high, microcontroller will read the state of the pin at start up (at C on the diagram) and it will be HIGH. That tells the microcontroller that power was switched off only for a short duration and it will change into secondary state (dimmed LED).

But that's just two steps, not three!

One GPIO pin with resistor and capacitor gives two step dimming: One after switching the power on and second after cycling the power off and on again. Adding third (and then fourth, fifth...) step can be done in couple of ways. I chose to add another resistor and capacitor to second GPIO. I start to charge the capacitor only after the first power cycle has been detected. Another way would be to store current state in EEPROM, read it back after switching the power on and changing to next state if the GPIO reads as  HIGH.


Here is my demonstration video. I used single LED, but it could be replaced with mosfet and multiple LEDs to create lamp that is more usable in real life.


Below is the code used in the demonstration. It's something I put together on a minute or so, but it doest the job!
If the code doesn't show up, here is the link to the PasteBin:

Sunday, August 16, 2015

How to control LM2596 buck-converter with microcontroller

Every now and then someone asks on different forums if there is an way to control cheap LM2596 modules with an Arduino or another microcontroller. I decided to demonstrate one solution that might be basic electronics for some, but still many don’t know about.

Those buck converters will change the output voltage to make the feedback pin, connected to the output via a voltage divider, become 1.25V or so. If feedback is higher, output gets lower and vice versa. If one changes the ratio of resistors in voltage divider, output voltage will change. This is usually done by turning a trimmer resistor with a screwdriver. That is good enough for many applications where voltage will be set only once, but sometimes there is a need to adjust the output voltage more frequently.

External voltage can pull the feedback pin’s voltage higher or lower when applied to it through a resistor. That would make a summer circuit where output voltage of buck converter and external voltage are inputs and output is junction which connects to the feedback pin connects. That external voltage can be generated with just about any microcontroller. Microcontroller generates PWM signal, which is smoothed with RC low pass filter and then buffered with an operational amplifier configured as a voltage follower. Thanks to Hackaday’s Al Williams for pointing this out: I didn’t remember to mention this clearly enough in the video: Circuit shown in this demonstration needs to have really stable power supply for the microcontroller, as the PWM signal’s amplitude depends on the power supply. So any changes on power supply’s voltage will affect the amplitude of the generated voltage and therefore the buck-converter’s output voltage.

In my demonstration the PWM-signal’s maximum voltage and therefore maximum signal generated is 5V. When buck converter’s maximum output is set high enough (lets say 12->V) adjustable resistor’s (which is one between output and feedback) resistance will be relative high compared to the resistance of buck converter module’s fixed resistor (which is 330ohm in this case). Therefore when trying to adjust converter’s output to zero or as low as possible with microcontroller, the output voltage’s effect to voltage on feedback pin will be marginal. Therefore we just need to figure out resistor for voltage divider that divides 5V to 1.25V, where lower resistor is 330 ohm. That is simple task: R = (5V * 330ohm - 1.25V * 330ohm)/1.25V = 990ohm

When everything is connected, maximum output of the buck converter can be set by generating 0V with microcontroller and then adjusting the trimmer on the buck converter board to achieve the desired maximum output voltage.

Before using this in any real application, ripple and noise performance as well as stability should be tested further.

Thursday, June 11, 2015

How to hack into computer’s I2C bus

Few weeks ago I added GPIOs to ESP8266 module by soldering few wires. This time I’m “adding” an I2C bus to my laptop by just soldering some wires!

Back in 2006 I saw an wiki-page on lm-sensors -website (This one!) describing that one could tap into the PC’s I2C bus via the memory module. Back then I hadn’t soldered any SMD stuff and I decided using a parallel port was better way to interface with I2C devices.

Years later parallel ports kinda disappeared and I2C devices didn’t. Interfacing I2C devices though USB-port needs a USB to I2C adapter or a microcontroller that acts like one. But that costs a dollar or maybe even few dollars and uses one USB-port! There must be cheaper way to do it. I remembered the old wiki-page and decided to try it out with more modern memory module. I had plenty of DDR2 SO-DIMM modules, so I decided to try with one of those. The specific module had 24c021 EEPROM/Supervisor chip. It’s like 24c02 with some extra features (which aren’t relevant to this hack). Pinout was available in the datasheet and I was ready to go.

I had LM75 -temperature sensor on my table, so I tested the hack with that one. I soldered few wires, installed software to test the hack (i2c-tools and lm-sensors) and it was time to test if I could access the temperature sensor. I was able to read data from the sensor and lm-sensors detected it. Just to make sure the detected lm75 was actually the one I added, I run lm-sensors every second and touched the sensor to see that the temperature reading started to go up. It works!

I’ve seen some hacks where people have added USB-enabled microcontrollers inside laptops to add something like LEDs or sensors, but those hacks will use an USB-port. This hack doesn’t disable any featuress, but just adds new ones.