Flashlight Firmware Repository

Ooo that would save us a pin!

EDIT: Sorry, I understand now that wouldn’t work. Would still need to use pin3

The rating of the IO pins is tied to what you feed on pin 8 (Vcc).
Except for pin 1 (the reset pin), the ‘absolute maximum’ rating on any pin is Vcc + 0.5 V.
And the maximum rating for Vcc is 6 V.

(Datasheet 18.1)

But running close to a device’s absolute maximum rating is usually a bad idea.

The datasheet says this:

Could it be made so that a standard momentary firmware that only outputs one PWM channel, with a certain sequence of button presses could change the output pin and nothing else all modes stay the same but out of a different pin instead?

Yes, it’s definitely possible to make something which toggles the output channel. I’m not totally sure why, unless maybe you had two different emitters, but it can be done.

Cool, basically I like having a secondary Red emitter in my lights, sometimes useful mostly just novelty but adds something extra to it. Would be cool to have a full range of levels and pick with emitter to output from.

This is the stock 105C on the ‘wooden light’ above. It has eight 7135s and drives a mystery bin XML2.

I set up the PWM to 9.4 kHz phase-correct. (Actual frequency is 7.2 kHz, due to the un-calibrated clock we get at 4.8 MHz).
Since we are running at 7.2 kHz, each of the 255 sub-periods of the PWM signal is around 0.55 us (1/7200/255).
This is with a PWM duty cycle of 32/255:

We are zoomed in on only one ‘on’ pulse of the PWM train.
The yellow trace is the control pin on the MCU.
The cyan trace is the ‘output’ pin of the 7135s going to the LED.
Both are referenced to ground (normally cell negative terminal, although I was using a bench power supply).

The horizontal scale is 2 us per division.
The vertical scale is as indicated on the screen capture, but is not very important. Basically the 7135s are fully on when the blue trace bottoms out and fully off when at the other end. (I did trace the current as well, but the signal is much more noisy, using a 4” piece of AWG 22 as shunt does not help.)

So we see on the yellow trend that the MCU output turns on at the 2nd division from the left, struggles for 2 us, then settles as a straight line at 4 V.

The 7135s output oscillates for another 4 us (there is a control loop in each chip, and this wave is probably created by the feedback loop trying to catch up with 350 mA set-point). So our theoretical 32/255 x 2.8 A becomes more like 22/255 x 2.8 A.

This what we get at 2/255 PWM:

and 4/255:

8/255:

No surprises, we are just cutting the trend we see on the first screen capture.

Finally around 10/255 we start to get to the stable output level, just before the end of the pulse:

So basically we have a 6 us unstable transition period before the 7135s get to do what they are supposed to.

Typical circuit design strategy would limit this unstable operation to less than 10% of total operation to get acceptable stability, linearity, efficiency, repeatability, etc. That means not using pulses shorter than 60 us.
That is around 43% PWM at 7.2 kHz. And 86% PWM when using fast PWM at 13.5 kHz!
So we see we are not really playing inside the ballpark.
It also unfortunately translates to an ideal PWM frequency of 1/(60 us x 255) = 65 Hz.
Not going to happen.
So we have to live with the inconsistent PWM results or find a better way of doing it.

My compromise for the moment is to lower the PWM to 2.2 kHz.
Also lowering the self-imposed 10x criteria above to 2x limits me to using pulses longer than 12 us.
At 2.2 kHz, each 1/255 sub-period is 1.8 us. So PWM duty cycles greater than 7/255 is ‘stable’.

2.2 kHz PWM, 8/255 duty-cycle, more than half the ‘on pulse’ gives stable current:

I am working on my X6R, trying to get it to recognize when the charger is connected. I have connected a wire directly from the USB 5v+ to Pin 7 on the Attiny (normally used for LVP). Then I ran TK’s battcheck.hex. As expected, it reads out the full 255 adc value.

So now all we need is a bit of code that tells the light to turn off when it senses max voltage on Pin 3, right?
Something like:

If
adc_ticks = 255;
mode_idx = 0
else
mode_idx = last_mode_idx

Except in the proper language and for Pin3 instead of pin7.

Or even if it detects ANY voltage on Pin3, it doesn’t have to be specific.

I’m trying to get this working in the STAR momentary version I posted above.

Would this work?

I’ve put it into the firmware here
Don’t know it it will actually work and can’t try to compile it as I’m currently at work.

I don’t really follow what you did, but I’ll compile it and try it on my test rig…. just a minute….

edit: it compiled and flashed fine, but no dice. The driver didn’t react at all to input on Pin3 (or pin7)

Dam. I’ll keep looking at it hopefully ToyKeeper might be able to see any issues with what I’ve done. I’ll start from scratch tomorrow and see what I can fine. Just bare in mine that I have no coding background and have never learnt any coding, I just hack and stitch stuff together.

At a glance, it doesn’t appear that code is checking pin 3 at all. The ADC hardware can only measure one thing at a time. With VCC on one pin and the charge sensor on another, it’s necessary to reconfigure the ADC between readings and then set it up for a fresh measurement. This will mean flip-flopping the ADC between two pins, toggling the pin every time it goes through the main loop.

Also, it looks like you told the code to step down incrementally before shutting off, like what the LVP does, instead of just shutting off. And it’s sharing the same “lowbatt_cnt” counter as LVP, so I’d expect it to act more than a little bit weird. Like, if it detected the charger being connected, it’d bump up the counter. But then LVP detection would see that the battery is fine, and reset the counter to zero. And it would keep repeating that while the light stays on forever.

I’ll be doing something similar soon, but instead of LVP + charger, it’ll be measuring LVP + temperature. So maybe I’ll have an example of how it can work soon. Also, I think JonnyC already did something like this in his thermal step-down branch, but I’m not sure how close it is to finished.

I thought it would take much less code. As you said, it doesn’t need to ramp down or delay and check a few times before acting, just set pwm=0 or mode_idx=0 as soon as any positive input is sensed on Pin3.

I thought it would just be as simple as changing mode order on Star3 was/is.

Yeah, I’m not sure if the ADC is even required for this. It might be able to detect the charger based only on whether the pin is “up” or “down”.

Can’t say for sure without trying it though.

… which you could probably do by using a stock build (with the pin 3 “star” enabled) and checking if it uses a different mode order depending on whether the light is plugged in.

Ok, so I flashed it with the FW version that I posted earlier, which still has the Star3 mode order code intact. Without the lead from the charger soldered, it functions correctly. With the connection to the charger but the charger NOT powered, it toggles Star3 and switches the mode order. When power is applied to the charger, mode order switches back to the original order.

Also, the driver will run without external power supply. With only power connected to Pin3 (not pin 8 ) the driver functions normally.

Edit: Just discovered that the Attiny gets extremely hot with the 5v running directly into pin3, so we definitely need a limiter inline.

As useless as my bit of code was at least were making progress I will see if it can get a test rig built this weekend and have a play

Not sure if this works but I’ll try give it a go over the weekend.

Drat, it sounds like the easy method doesn’t work. :frowning:

I've measured some FET drivers PWM on my scope at around 17 KHz, but I've never seen one go up close to 19 KHz.

When I flash that, the driver behaves very strangely. I can’t even work out a pattern.

The driver is responding to the charger being powered, we just need to make it respond in the way that we want.
I tried this, but no dice

Plus, we need to have it check pin 3 continuously, not just when power is first applied.