Developing a customizable driver

Sure, but it’s not much to look at yet. Just a homemade test board.

The firmware works.
I have off-time reading for mode advance set to 0.5 seconds but the discharge curve of the off-time capacitor is consistent so I could change that to anywhere from probably 0.2 to multiple seconds if I wanted. Recharge is controlled by the micro and takes roughly 25 milliseconds from full discharge so there’s no worry about erroneously high reads or misreads from partial or automatic recharge. Only capacitor tolerance and temperature should affect the timing.

The default mode is the last-used mode. I have not implemented wear-leveling for the EEPROM, which is rated for 100k cycles, but it can be done.

It’s coded for 3 modes right now but the mode count is arbitrary and changed by altering 1 number in code. Any added mode PWM values (10-bit) need to be established in code, but the process is simple. The micro I’m using has sufficient RAM for 128 distinct brightness modes.

There’s a built-in 10mS delay between init and turning on the main regulator, which is controlled in software. This allows input capacitors and all reference voltages, including filtered PWM lines, to settle before turning on the light, to avoid erroneous bounces. I’ll probably tune this to the minimum on a per-driver basis.

Technically the regulator-enable function also allows for coded strobe modes but those are dumb and therefore not implemented.

I will wait until I have a functional prototype with a temperature sensor mounted LED-adjacent to worry about overtemp throttling. Depending what kind of control loop must be implemented, that feature may end up using as much code as all the rest combined.

The current unoptimized version (I know there’s some arbitrary code in there) compiles to 174 instructions.

Next step, PCB design.

Nice project sidehack, i have found very interesting reading your progress.
I wish i knew more about the topic to take part in the thread.

With work being so slow, both because of reduced sales and some process improvements that have greatly increased time efficiency, I’ve been in full R&D mode for most of the last two weeks. I’m sure y’all noticed a sudden quickening of the pace.

I forgot I hadn’t yet tested low-battery shutdown, but the adjustable linear regulator I was using in place of the micro’s LDO has a dropout of like 1V so definitely not suitable for continuing to power the micro at 2.5V with a battery input of 2.7V or so. I’ve now acquired the correct part and can test and program for that.

I also got in some of the analog temp sensors I want to test for LED temperature monitoring. They’ll work down to a fairly low voltage, and also operate on a max of 10uA, so I’m going to try powering them in parallel with the LED. The parasitic current should have an imperceptible difference on brightness even at low settings. This means only one additional wire to the LED’s PCB to get temperature readings.
The only problem now is the ground reference is floating. Fortunately that offset is always a known value - in fact, a value determined by the micro - so the math to compensate for it is easy. The simplest method is to simply scale the PWM value against the current-sense resistor, and account for the difference between ADC reference and Vcc (2.048V vs 2.5V, so a factor of roughly 1.25). Since all of those factors are constant the scaling factor is constant and determined at design time, therefore easy to program in as a constant in code.

I’ve got PCBs drawn up for 2A and 3A versions. Basically the only thing changing is the buck driver; the 2A version is a SOT25 package I can home-etch boards to test with but the 3A is an SC70-5 with pin pitch too fine for my Sharpie skills so, while I have some to test with, I’ve never actually lit one up. Its internal FETs have a lower on-state resistance though most other parameters are basically the same, so it should be more efficient.

What’s going to be the hangup in testing is LED PCBs. I’ll have to make do with regular 2-layer PCBs, thin and with plenty of vias for heat transfer, probably lap the soldermask off the bottom, but eventually I’ll want something proper. I’ve done a bit of looking at MCPCB threads on here but they were all a few years old. Who do y’all trust these days for small batch custom boards? I’m testing with two lights right now, one with a P60 dropin (16mm LED board) and a zoomie with a screw-in pill that takes a 17mm driver and 20mm LED, so I’m drawing up temp-sensor-integrated LED boards for both sizes.

Also because I got time, I’m working on prototype PCBs for a 1S 6V/5A buck, and the ~400mA buck/boost for a 2xAAA penlight. Got parts to play with, but no PCBs. They’ll probably be in the same order as the above test drivers. Next I’ll iron out the 6A buck, and then start hammering out the 8A boost, both of which will benefit from a FET tailswitch.

Spent basically the whole weekend doing design on this family. Today was regular work but some time spent checking and revising PCB layouts. Tomorrow I’ll have on order some test 17mm driver discs for the 2/3A buck builds and the basic LED PCBs with temp sensor pads.

Since the price of a prototype run of PCBs didn’t change if I increased the size a bit, I added test circuits for the 6A buck, the 6V/5A boost, the 6V/8A boost (using external FETs), and the penlight. Sunday and Monday were spent tracking down parts, drawing up a circuit and adding a 1S 5A buck/boost (also with external FETs) to the test board. So I’ll be able to test out all of them, wired to a pill-mounted LED with temp sensor, with the also-in-progress control system and firmware. Get some performance metrics, efficiency numbers. Hopefully everything works pretty well and I can start drawing up 17mm driver discs.

Also had a square centimeter of open space so I added a few test pads for SC70 and 0402 parts to verify my assembly equipment is up to the challenge. 0402 will be essential to fit this stuff in the final product. I’m really hoping the 6V/5A boost and the 1s 5A buck/boost work out well. Still need to add and test low-battery shutdown and temp sensor response in the firmware but otherwise controls are pretty complete.

I am eager to see your drawings :beer:

PCBs have been ordered. Probably won’t be much to talk about until they arrive in a couple weeks. I did do a quick test of the 3A driver circuit today and the buck IC wasn’t getting warm, which is good news. Probably put together a few of those in my zoomie and P60 test hosts and hand them out to my cousins for field-testing once I have the overtemp limit working.

Awesome project! Looking around for a 17mm buck 6v 4.5A for my custom external batt mod. Can’t wait for yours to be out

But I’m not making a 6V buck. All these drivers are designed for 1S, so under 4.5V input. However, I’ve flubbed up buck and boost on occasion, including in this thread. There’s a 6V boost that should have no trouble handling 6V 4.5A output from most of the discharge range of an 18650, so if that’s what you mean, then yep it’s on the way. I hope to be testing out a mockup of the circuit in a couple weeks, and testing a proper driver disc before the end of June.

The 6A buck driver is limited to 5.5V input so would not be suitable for any cell input capable of bucking to 6V.

For simplicity, I set up my temperature-sensor’d LED PCBs for the temp sensor to draw current in parallel with the LED. That was mentioned up above. Since they’re expecting to draw on the order if micro-amps it shouldn’t have an effect on light output. However, the device is only rated for 5.5V so that becomes a problem with 6V boosted LEDs. I’ll have to figure out if I want to run a fourth wire up there to power it with a regulated line, or if I should just put it under a resistor and small zener. Zener would mean shunting slightly more current off the LED, but still be a low-hassle installation. One extra wire is more manageable than two. We’re already avoiding an extra wire by using the LED ground line and, in software, compensating for ground offsets due to sense resistors by subtracting a factor of the output current setting from the sensed analong measurement. I think a two-component hardware solution is worth testing to lose another wire, since PCB space is at a premium and wire contact points are expensive.

Looks like my prototype PCB order has already shipped, earlier than expected, and should arrive on Monday. That’s good. I’ve not done panelized boards before so hopefully my outline routing was correct. Guess we’ll find out.

Reckon I’ll take some time between now and then to code in low-battery lockout and an initial temp-sensor routine, like I should have done last week.

Once the family of driver circuits are tested I should work on buck and buck-boost that’ll do 2S voltages and up. The 5A buck/boost should handle 2S input voltages with only a few changes: 16V/25V-rated input capacitors, better 2.5V LDO etc. It’s being built for about 8A at the inductor, which means technically it could operate as an 8A-output pure buck for running 6V LEDs from 2S cells. A 20mm version and up could do better, since there’d be room for lower-loss FETs and inductor. Maybe once this family is done I’ll focus on improvements to this guy.

So to sum everything up, the family of drivers under development, with a common control core, built for 17mm 1S, with a temp sensor on the LED:

3A buck
6A buck
5A boost
8A boost
5A buck-boost

Additionally,
400mA buck-boost (2xAAA penlight)

For the penlight, I’ve got some 1.6mm LEDs that spec as very efficient. I’ve also got a whole reel of CREE JB3030 LEDs (5 cents apiece, built my shop’s bay lights out of them) that are rated for the same or slightly better lm/W and I bet they’ll overdrive a little better, if the larger size will fit okay. The penlight housings I ordered 29 days ago with “not slow” shipping haven’t arrived yet so I can’t be sure.

8PM here, so I’m assuming DHL won’t be delivering today, which means it will have taken 2 days for my PCBs to get from China to the depot 100 miles away, and 5 days to get from the depot to me. They were supposed to have been delivered yesterday.

I now have low-battery lockout in the code. At 2.8V it’ll blink twice (200mS off/200mS on) and then stay steady on. At 2.7V it turns off. I haven’t started on temperature monitoring code; figured I’d wait until my LED PCBs arrive and I can look at real-time heat instead of trying to simulate signals with a pot. That way I can look at thermal capacitance as a factor for action delays in the control loop.

Went ahead and updated the code with constant definitions for all relevant constants (number of modes, battery cutoff values) and port pin definitions to make it easier to change things around in the future. Even internal addressing related to port pins in signal multiplexers and ADC sources pull from the defines so if I need to change port assignments it’s literally a one-line edit for the whole program. That’s probably pretty standard for you guys but not as straightforward when coding in assembler.

Maintenance routines for battery monitoring added significantly to the program size. Now we’re up to 270 2-byte instructions. I know there are at least 6 unnecessary instructions (defining a 4th mode), and I haven’t tested for bank bit optimization in the compiler. Splitting ADC routines off as a function will save a further 10 or so instructions, with further savings once temperature sensing is added. All in all I’m pretty pleased. Now if only those PCBs would show up…

Test boards finally arrived this afternoon. I had already prototyped the crap out of the 2A driver so I assembled it first and got it running behind an XM-L2 in a zoomie light. Haven’t done anything with temp sensing yet but now I have a solid test bed for it.

Defining port pins worked perfectly, as I had to switch buck-enable and battery-measurement pins. What I forgot to take into account is buck enable used to share with an ICSP pin that now has a voltage divider and bypass cap on it for sampling the battery. That crapped up the data and the micro wouldn’t program. I dropped the cap from 1uF to 0.01uF (it’s under a 47k capacitor; surely that’s got sufficient rolloff to take care of 1MHz switching noise), lowered the data speed to minimum and it programmed fine. I now have it set up for 3 modes, 10% 40% 100%

Tomorrow I’ll work on getting a 3A built and tested. That’s the disc on the right. I got 10 of these boards so I can make 10 of each for field-testing. If the 3A version works as well as I hope, especially once it’s temperature-protected, I probably won’t worry about the 2A build.

The rest of the board is test circuits for everything else I have in mind. Really excited about the big buck-boost, myself. The 5A booster will be fun to put behind some XHP50.2 I got to play with.

2.5 months in, finally some tangible progress. Technically the original scope of the project has been completed now, but y’all got me excited.

Orsm work sidehack. Reckon you may have a few members here excited as well. :beer:

It’s interesting seeing a new family of drivers being developed from scratch. Thanks for sharing your progress sidehack.

3A driver circuit works. Had some trouble at first with residual flux throwing off the divider ratio for the PWM output but I just needed to wash the board better. I have this guy wired up to test the temp sensor which is mounted right by the LED. The LED board is a two-layer 1oz copper 1mm PCB with about 100 vias, including 24 on the LED’s belly pad. I lapped off the underside soldermask, spread a drop of Arctic Silver white, and used a 5-minute epoxy along the top edges to hold it down in the pill.

With the three leads pictured, I can verify the drive current and the absolute and as-measured temp sensor output. I don’t have any topped-off cells so I could only briefly test at 100% output but the temp sensor only ran up to 55C for steady-state. When I kicked it back to 10% it dropped 11C in about ten seconds.

55C is pretty good, I think, for right next to the LED. I might have to wait for a more powerful driver (maybe that 5A buck-boost) before coding a temp-throttling routine. I think I’ll also put a temp sensor on the driver PCB, if I have room, instead of relying on the microcontroller’s internal temperature indicator, since to be anywhere near accurate it’d require a per-chip calibration routine that means more handling time, more computationally intensive measurements, or both. A twenty-cent SC70 pre-calibrated linear analog sensor would be awful handy.

Also since the move in November (I packed up my entire business and moved into a new shop across the state that my dad and I built last fall) I haven’t been able to find my good 18650 charger. Fortunately I’d picked up this battery tester a couple years ago and it didn’t take long to throw together a cell holder. Should be able to do better testing with full cells before long.

Got some efficiency numbers off the 3A buck driver. I didn’t have measured LED currents so I had to settle with expected. Everything looked pretty good (90+) from 10% to 80% but at 90% my input voltage had some pretty bad ringing on it and the input current jumped by roughly twice the expected step (580mA vs expected ~320mA). Gonna have to figure that part out. Could be an issue with inductor saturation but if we’re hitting 3A on a 3.5A rated inductor, and ripple should only be swinging it about 200mA where I have 1200mA of saturation headroom, I can’t see that as being the case. I’m hoping it was some kind of bad interaction with the input power supply so I’ll probably put a buffer cap on the input to get rid of lead inductance issues.

Might start messing with the penlight and buck-boost circuits soon. I’ve gotten about ten cells charged and tested too. Everything I’ve got are pulls from old laptop batteries so I categorized them by brand. I’m measuring capacity with a 7W costant-power discharge (should be about right for a 2A output buck-boost), starting with Panasonic CRG18650 cells. Some have tested out between 1500 and 2200 mAh, and some were like 100-500 so those are getting tossed. The 2147mA cell is pretty encouraging, with something like 63 minutes of runtime before hitting 2.70V and cutting out. Not bad for decade-old freebies. I’ve got a pile of Samsung- and LG-branded cells, half a dozen Sanyo and three I don’t know what they are still to be tested.

:beer:

Dropped a 1000uF can across the inputs of the driver to rule out any harmonic/inductive issues with the PSU and wires (16AWG about 12 inches with an inline toggle switch), and the line voltage was super flat even at 100% draw so I reckon that was the problem with the previous test.

For some reason I was seeing about a 59KHz ringing everywhere though, which is weird as that’s an order of magnitude lower than the switching speed anywhere inside the light and a little over twice my PWM pulserate. Might have been noise coming off the PSU?

I didn’t measure LED currents, sticking to calculated values, so my efficiency numbers are technically useless, but I’m seeing upwards of 90% peaking around 96% at 50% duty cycle and dropping to 88% at the full 3A output. Not bad for an SC70 regulator and, admittedly, not a great inductor (29mOhm DCR). Note that the output includes a 25mOhm sampling resistor, so if we include the power loss from this part the total conversion efficiency is going to be a bit lower (at 3A, the resistor eats 2% of input power). I will be replacing the 25mOhm sampling resistor with a 16mOhm so I can use the same 50mV PWM signal on 2A and 3A builds, and this will also reduce resistor power loss by about 36% (or 0.7% of input power at max draw). I may not even bother continuing the 2A design since 3A costs basically the same and is more capable, but 3A will need temperature limiting.

At 3A, by the time the temperature reached steady state, the light was too hot to hang onto for more than five to eight seconds.

Thought of a different UI I want to try out sometime also. It might require a hardware change if the microcontroller isn’t responsive enough, but I want to test out ramping. My off-time for mode switching is set to about 0.5 seconds right now. I figure if I can tap on for 0.5 seconds, off for 0.5 seconds, and then hold on, the light would ramp from 0-100% and back in 5-10 second cycles. When the button is released, the micro would lock in that intensity for next time the light is turned on. I need to test if the battery sense circuit will drain fast enough to trigger an interupt causing the micro to write levels to EEPROM fairly reliably before the 2.5V LDO and output bypass cap drain low enough to turn it off. Else it’ll require a hardware change (at minimum, a bigger output cap on the LDO; possibly a shottky to prevent stray drainage) to make this work. Datasheet says max 5mS to do a full write operation.

Oh also I need to do a bit more research but I figure I’ll make the ISP pads dimensionally compatible with HQ’s pogo key. The PIC needs a minimum of five pins and, if I’m seeing right, that one’s got a generic header so it should be able to cable to any ISP device including my PICKit3.

June’s going to be a busy month at work so I may not have a lot of flashlight time inbetween regular maintenance, manufacturing and something like three other design projects, but I want to at least get a final hardware design on the 3A driver (including driver-level temp sensor), code in a thermal-throttling routine and see about getting my buck-boost concept tested. Maybe add a single-AAA light to the project, nothing fancy, maybe 300mA peak output. Also I need to buy a good thermal-conductive adhesive.

The new ATtiny 0-1 series has something I will be looking into, and that is a VLM or voltage level monitor, it can be set for like 5% of the BOD level, and trigger an interrupt. And I am wondering if that is enough time to write to the eeprom? Or maybe that is what you meant?

I think you were using a TI part, so I would post up the ringing or other problems on their forum, and you would probably get an informed answer in 24hrs or less.

EDIT: 1. Why are you using a LDO regulator? 2. There is an 8 bit DAC available with an onboard buffer output, as opposed to PWM with extra parts?

My PIC can be set up for interrupt-on-change, either a low-high or high-low transition, and it’s quite responsive. I’ve used it for cycle-by-cycle current limiting in a PWM motor driver, figured to do the same thing here. I’m already measuring input voltage for low-volt shutdown on a pin, so during the ramp cycle I can switch that from an analog read to IOC and when it bottoms out the interrupt would trigger the EEPROM write.

I’m using an LDO to provide a constant 2.5V to my micro, and then dividing my 10-bit PWM down for current-sense comparison. That’s not an uncommon configuration. My PIC has only a 5-bit DAC and no buffer, plus I like PWM. Even with a DAC I’d still need extra parts for a comparison, either dividing the reference or multiplying the sense read.

Didn’t see the ringing when I was initially testing off a battery so I’m pretty sure it’s noise from the cheap-o bench power supply. I was also seeing some good 120Hz noise on my not-exactly-ground-referenced LED temp sensor as well, which wasn’t present before. My better one is a very clean linear supply but it’s only got an analog current meter so hard to do efficiency calculations with any accuracy, and only goes to 3A (which is plenty for now, but not for most of my other designs).

Maybe I should pull out one of my 12V SLA bricks and build a high-current fully linear supply. Calibrating the voltage and current measurements would be fun, but it could be quite useful. Be a fun weekend project.

Before you ask, I’ve no interest in switching to an ATTiny. I’m using a PIC16F18313 and I’ve been programming with that family (313-344) for probably five years so I know it inside and out, which is good because I’m also writing in assembler.