Warning: this project involves high voltages that when handled incorrectly may pose a serious
health hazard.
Please make sure you know what you're doing before attempting to replicate this.
For years I eyed the really cheap microcontroller sector.
Padauk processors at ~3c ea, were too basic and difficult to flash.
Puyas were too slow and boring.
But A month or two back I heard about the ch32v003 from WCH on E-E-V-BLOG.
It was just right.
A 48 MHz RISC-V processor with 16kB of FLASH, 2kB of RAM, DMA, lots of peripherals, a single-wire
debug interface.
It can even run at 5V like an AVR!
I am a sucker for tiny parts, so I just *had* to get the QFN at $0.12.
For other packages, like the SOIC version, it can dip down below $0.10.
A dev board and programmer, under $10, shipped.
I have to admit I’m not the first maker to be captivated by this part.
Unbeknownst to me, my friend, BitLuni saw these same chips and had the same feelings
and beat me to a video.
You should totally check out his video after this one on his CH32V003 supercluster.
One of the first things I did was make my own devkit, with double rows so I could use
each pin and then also probe it for debugging.
I also had Astronautilus do the silkscreen art on this board.
I wanted to make a fully open stack for programming and debugging, the first thing I did was make
it possible to use the WCH-Link-E Programmer that comes with the kit to be used to flash
it in Windows or Linux with an open source development stack.
Then I designed and ordered an ESP32-S2 programmer that could also turn on and off the 3.3 and
5V rails.
I got 25 dev kit/programmers made, so if you’re one of my patrons, message me on patreon,
and I’ll mail you one along with one of my ESP32-S2 programmers, if you’re in the
US for free or as cheaply as I can if you’re global.
Stock permitting.
While the CH32V003’s aren’t “in stock” on LCSC, I was able to purchase them on JLCPCB,
so I could play with them and order boards without needing to hand-solder anything.
It’s a lot of fun to be able to design boards, order them and get them about 7 days later.
Now comes the point of the video, and the cause of the thumbnail!
I saw this listing on Aliexpress recently for nixie tubes and I didn't know much about
them, other than this was the cheapest I’d ever seen them and they were really pretty.
@Spirit532_ was nice enough to talk me through everything I needed to know about how to safely
drive the tubes.
For instance, to never overdrive the current, and avoid turning on multiple cathodes, and
it looks better to use full current, but PWM the nixie to dim it.
In addition a great way to drive it with relative safety on a noisy supply is to use a single
18k ohm anode resistor.
I recently noticed this itty bitty, 2.5 x 3.2 mm flyback transformer on LCSC and I was
dying to merge these two projects together!
So I spent an hour or two where I designed and ordered these boards.
They use just a 12 cent CH32V003 as a closed-loop software-controlled flyback controller that
with a 3 cent FET and this itty-bitty 30 cent transformer, one cent diode and 2 cent smoothing
capacitor to produce the 180V @ 2.5mA or so needed to power the nixie tubes all for under
50 cents in parts!
The 003 has enough I/O to do take input from a host, do the closed loop control and control
FETs on the individual segments’ cathodes, and have more cathode control for turning
on additional neon bulbs.
I started using ch32v003fun, my open source SDK as the basis of this project.
Since starting it, a lot of people have created great examples.
The idea of this SDK is instead of using complicated libraries that use lots of code space, performance,
and memory.
ch32v003fun just gives programmers an easy way of writing the code to do what they want,
without complicated modules and components.
Exposing the complexity that HALs try to cover up and letting us jettison unneeded, hidden
complexity.
Increasing the effective power of this chip by 3 or 4 fold!
All I did was import ch32v003fun as a submodule, along-side a new folder and went to town.
I started by copying code from my blink test.
To verify that my part was okay.
Then, I copied and pasted some of the examples people wrote like emeb’s (like “e” - “meb”
(like deb)’s) timer and ADC examples.
I configured my IO, started writing.
One of the first things I knew I would want is some sort of GUI, so I used rawdraw and
minichlink (the open source programmer we wrote for ch32v003fun) as a library so I could
communicate with the DATA0/1 debug registers with only that single-wire programming/debug
interface.
That way I could quickly and easily program the device and over the same wire also control
my target voltage, while monitoring the feedback voltage to make sure things don’t get too
spicy.
And just to be safe, when I first started I tried to always make sure the tube was turned
on, so the current would have somewhere to go instead of just letting the high voltage
rail go crazy.
I did test one sacrificial unit to see just how high of a voltage this supply could generate,
or if it would arc over or otherwise explode.
I had to disable both the voltage and current limiting safeties.
The voltage just went up to around 400V, twice the rated values and the transformer just
kinda cooked itself.
The flyback works like a boost converter, except that, because there is a 10:1 turns
ratio on my transformer, it gives me 10x the voltage over the boost voltage on the input,
on the output.
I turn on the main switching fet, and when I do it, the current begins to flow through
the primary side of the transformer, charging it.
The longer the FET is on, the more energy gets stored in the transformer.
Then, when I release the FET, that current flow has to go somewhere.
The primary isn’t connected to anything so the current flows through the secondary,
into this fast acting diode and charges a capacitor on the high voltage side.
I was able to use the TRGO system so I could let TIMER1, the PWM the FET was on trigger
a conversion.
If you are using a microcontroller as a switched mode power supply, you have to synchronize
the ADC to your switch because if it samples at random times, then you will not be able
to accurately control the output because all you will see is noise.
But if you sample at exactly the same time every frame, then all of that noise disappears.
Speaking of noise.
Because we are literally a flyback converter, the values from the ADC are going to be a
little noisy.
There’s neat trick to filter signals in code.
We can use an IIR–an infinite impulse response filter.
That means that it doesn’t average over a window, but it does care much more about
recent samples than older samples.
Normally it’s done with an equation that looks like this.
But, because our timing is at least approximately constant we can make this a constant.
And, furthermore we can use some bit shifting hax to make this basically 3 instructions,
and doesn’t require any multiplies or floating point.
It takes several charge/flyback cycles to get the voltage of the output capacitor up
to our operating voltage, but, we charge it up, and as we approach our target voltage
we can roll off the power, because we use a PID (Porportional, Integral, and Derivative)
control loop to control the high voltage rail.
Additionally, we can use the incoming voltage to properly tune the max time the FET is on
to prevent transformer oversaturation.
This does take a “multiply.”
It’s the only one in all of the code.
This matters because it’s an RV32EC core, so no “multiply” assembly instruction
at all.
Instead we have to do it in software.
So I was able to heavily optimize multiply for this chip to be about 30% faster than
the libgcc software multiply.
And it’s a lot of fun that you can see, on the scope the extra time the multiply takes
when the second operand increases in value.
With the flyback done, I did want to light up individual segments, but Spirit raved about
being able to dim the segments.
And so I added that.
Boy, was he right.
These tubes look so pretty when fading.
I did this trick where I split up my PWM into multiple stages, so the primary switch rate
is very high (greater than 1.5kHz) but we can get a lot of intensity resolution over
a longer period of time.
So now, I have this single-chip solution for controlling a high-voltage flyback that can
tune to any voltage I want as well as something to handle dimming the tubes.
It can talk over that single-wire debug bus, that can be communicated to with with a single-file
header that can be run on pretty much any microcontroller.
And all with a BOM price of less than two fiddy–PCB included–for the control board.
What’s next?
Well, since we aren’t weighing ourselves down with a hardware abstraction layer, this
project uses about 1/8th the amount of flash and RAM that that chip has and has a bunch
of extra CPU cycles are free, so there’s lots of room for more features.
Maybe I can make it use a UART, or if I’m lucky maybe emulate WS2812’s?
“Neonpixels” if you will.
I’m def gonna control these with an ESP32-S2 so I can control them over USB or, just be
a really pretty clock.
I’ve intensely commented my code and put it up on github, check it, ch32v003fun and
my patreon link out in the description.
I also am going to be testing out another rev of the boards.
In fact they’re already on order.
Also, I might do a deep dive on the code.
Anyway, thanks for watching.