Flashlight Firmware Repository

The more I look at this, the more I realize full power PWM is not the way to go.
LEDs really crave current regulation. If only we had an LD-2 with an ATMEL MCU :slight_smile:
In the meantime I will hack an 8x7135 into two or three controllable groups of 7135s, as others have done. Only first group with PWM to get the very low modes.

For the photosensor, just connect the LED between the ‘LO’ and ‘HI’ inputs on your meter and select frequency. If the signal is large enough for the frequency counter to trigger, you will have a reading. If not, the LED signal will need to amplified and the DC offset removed.

Well, that was ridiculously easy. I should have tried this sooner!

Step 1: Connect an LED to the DMM. I used an old XM-L T6.
Step 2: Press the DMM’s “FREQ” button.
Step 3: Shine a light at the LED.

Instant and precise PWM speed measurement! :slight_smile:

I measured a few things…

  • Two production BLF-A6 units: 15.49 kHz, 13.35 kHz
  • S10-Ti w/ MELD: 488 Hz (same speed my phone mic measured)
  • Blackshadow Terminator: 187.9 Hz (same speed my phone mic measured)
  • CNQG Brass Beauty w/ brass-edc.c: 16.84 kHz
  • Stock BLF EE X6v1: 9.38 kHz
  • Stock original Convoy S3: 4.43 kHz
  • iTP A3 EOS (final model): 2.45 kHz
  • CNQG brass AA (stock): 304.2 Hz low, 1000.0 Hz med
  • SK-68: 128 Hz… then 127… then 126… decreasing with battery charge
  • And an attiny25 test host: 31.74 kHz

I was also able to measure the party strobe modes on my EDC:

  • “12Hz mode”: 12.4 Hz
  • “24Hz mode”: 23.9 Hz
  • “60Hz mode”: 64.6 Hz

It’s neat to see that I got them pretty close through guesswork.

Hi,

Could someone build the .hex for luxdrv and for STAR?

Thanks,
Jim

I’ve been able to build a .hex - just using the minidrv for now.

I’ve been messing around with the modes, and I was wondering what is the minimum value for that in the array? From the comments, it looks like minimum is 5, but is that the lowest mode I can get? If so, it still seems kind of bright, so how do they get those moonlight modes that are lower than that?

Thanks,
Jim

TK,

Apparently nickelflipper had an alpha of his NANJG ramping driver:

Should that be in your repository (you were on that thread too :laughing:?

Jim

Ah, good. It looks like you figured out the build process.

The PWM values can go from 0 to 255, but the minimum depends on your exact hardware. For moon on a 7135 chip, I normally use a value of 3/255 or sometimes even 2/255, both running with phase-correct PWM. For fast PWM, the minimum will be a bit higher. For a FET driver, the minimum will be lower.

Maybe. However, it’s only an alpha debug version and there is no source code available.

Hi TK,

For the Dr. Jones minidrv, he has:

Is that 9kHz PWM considered “fast PWM”?

If it’s not, then would “1” or “2” work? [I guess what I’m asking is if there is some minimum value at which PWM stops working?]

Also, does the number of 7135s on the NANJG (in my case, there are 12 of them) determine how low the moonlight would be?

‘Fast’ is not necessarily fast, it is just ~double the frequency of the other option, called ‘phase-correct’.

Change
TCCR0A=0b00100001
to
TCCR0A=0b00100011
to get fast mode.

Phase-correct mode runs at 1/510 the frequency of the MCU clock.
Fast mode runs at 1/256 the frequency of the MCU clock.
(Both assuming your PWM clock pre-scale is 1 as per above.)

In theory the light output corresponds to the average current.
And average current = x/255 the full current capability of the 7135s.
(where x = your PWM setting)
In practice x has to be larger than 1-6, depending on the frequency of the PWM.
At 9 kHz, the 7135s only start to turn on after ~4/255 of the PWM period has already passed. This number depends heavily on cell voltage. At 3.4 V they may not turn on at all at 4/255.

For your 12x7135 driver you can approximate average current draw as about (x-5)/255 * 350 *12 at 9kHz.
And (x-10)/255 * 350 *12 at 18 kHz.

The 5 or 10 offset is to accommodate the delay of the 7135 to turn on at each PWM pulse.

It is a compromise, do you want high frequency PWM to avoid flicker and noise, or do you want to have more precise current control?
You can always run moon at 1-2 kHz and the medium modes faster.

Wow! Thanks.

I understand. So, basically, with that many 7135s (x12), and with 380mA 7135s, and set to 6, it would be average current of (1/255) x 380 x 12, that is 17.88mA at the original 9kHz PWM?

You also have the LED to worry about. Many simply won’t light up at all on 1 PWM, no matter how much current they theoretically are getting.

Yeah… that was what I was wondering/curious/messing around about, and whether it was even possible to get a reasonable moonlight with 12 380 mA 7135s. So far, from my testing, it seems like if I set the PWM to the point that the emitter lights, it’d have to be way too bright to be called “moonlight”.

Kind of. Your calculation is right on.
But it is very non-linear when you are at the edge of switching on the 7138s.
Your batch of 7138s may have slightly different gate characteristics, the MCU output as well.
And we are so close to the edge that the cell voltage makes a difference.
Something that worked for me was to bump the level by one at 3.6 V and again at 3.4 V.
The trick is to only go up with the bumping, otherwise you get a flickering candle.

With all of these firmwares being available has anybody thought about creating a library of functions? Would there be enough benefit in creating one?

That is not really the LED.
Try it at a low enough PWM frequency (below lets say 1 kHz) and any LED that lights up at 255/255 will also light up at 1/255.

The 7135s I looked at only start to turn on after about 2 us. They are only fully on after about 6 us.
So we want PWM pulses at least 6 us long to get semi-consistent operation.

If you want to accommodate 1/255 PWM that implies a PWM period of 255 * 6 us = 1.53 ms, or 654 Hz.

Easy test.

In the code above, select on the /8 prescaler for the PWM timer.
Then try 1/255.
You might not like the flicker, but it illustrates the point.

TCCR0A=0b00100001; //phase-correct PWM
TCCR0B=0b00000010; //pre-scale 8, so PWM at 1.1 kHz
or
TCCR0B=0b00000011; //pre-scale 64, so PWM at 140 Hz (should give terrible flicker)

Hmm, I just went to try this, and I am not having success. You just connected the LED+ to DMM+ and neg to gnd? My DMM has a Hz/% button, I assume that’s frequency,

LEDs aren’t very efficient sensors, so you might need to turn up the light you’re measuring to a pretty bright level, and hold it very close to the “sensor”. Also, it depends quite a bit on the DMM you use. The DMM I tried was a really expensive one, so I’m not surprised it worked so easily.

An actual photosensor should be able to measure much dimmer lights, but I don’t have one of those… so I ran an emitter in reverse. The efficiency is terrible, but it worked well enough for my purposes.

It’s funny you mention that. A couple days ago, I started exporting common code into header files so I can share it between different projects. It’s only the most basic stuff though, the things which have been identical in pretty much every project.

Making actual libraries is a much harder task, since on an attiny every byte counts. Libraries make it a bit hard to include only the specific bits of code you want, and hard to tailor that code to each project. But at least some things can be shared to avoid repetition…

The easiest thing to share is #defines. They take no room unless actually used. So, most of my headers are just #defines for calibration values, hardware abstractions, etc.

Maybe a compendium of useful functions, rather than a true library, is the way to go. You wouldn’t include it in your project but rather cut and paste the functions you want from some central, curated, repository.

Try a small solar cell in a mostly dark room. Will produce a larger signal and their response time is suppose to be fast.