E-switch UI Development / FSM

"ADC_nn values are 16.0 values and get converted to a 9.7 value (<<7)
the ADC reading is a 16.0 value and gets converted to a 11.5 value (<<5)"

That's not quite accurate. ADC_nn values are 8 bits, shifted left by 7 they become 15 bit values.

The ADC reading is 10 bits, shifted left 5 bits it becomes a 15 bit value -- so comparing 15 bit vs. 15 bit seems compatible to me.

You could take the reading, divide it by 4, then shift it left 7 bits -- that's the same thing except you lose the resolution of the lower 2 bits.

The included battcheck-25.hex file works on tiny85.

Thanks.

Interesting, that outputs 128 for 4.4V and 62 for 2.2V

Looks like I missed something with my math - that’s why I asked for a check.

It’s worth mentioning that it means 4.4V and 2.2V per cell. So, the actual voltage needs to be scaled up to however many cells the light uses in series.

On my BLF GT, I measured at 8.8V and 17.6V.

Ish.

My PSU doesn’t go up to 17.6V, so I measured a bit lower and then used the battcheck.py script to calculate what it should have been at 17.6V. Then I plugged the resulting values into ADC_22 and ADC_44, compiled, flashed, and now I have a pretty accurate voltage readout on my BLF GT.

Oh, that’s something I messed up. I thought it measures the total voltage and not a per-cell scaled down voltage…

Here's a great post from RMM on the voltage divider equation: https://budgetlightforum.com/t/-/27210/125

Back in the day I didn't understand much, well, I understand slightly more now.

here it is:


For starters, here is the voltage divider math you use to figure out which ADC value to tell the software:

ADC = ((V_bat - V_diode) * R2 * 255) / ((R1 + R2 ) * V_ref)

IF DIODE PRESENT

So for our typical 125 or so ramp down at about 3V at the battery, we get this:

126 (rounded) = ((3V-0.25V)*4700*255)/((19100+4700)*1.1)

OK, now take a look at a picture of your standard 105C driver or even the regular BLF17DD. You will see that the voltage divider circuit positive input runs through this sequence:

BATTERY-->SCHOTTKY DIODE-->VOLTAGE DIVIDER-->MCU

The Schottky diode drops the voltage by about 0.25V (it's forward voltage). So, we compensate and tell the software that we want to ramp at about 0.25V lower than what the divider seeing and converting into the lower voltage for the MCU to check against its 1.1v internal reference voltage.

If you take the diode out, you get this sequence:

BATTERY-->VOLTAGE DIVIDER-->MCU

There is no longer the 0.25V drop across the diode, so no compensation is needed.

With the zener mod on the normal circuit, here is what we get:

BATTERY-->RESISTOR-->ZENER DIODE (parallel)-->VOLTAGE DIVIDER-->MCU

Since the zener diode is going to be regulating at a constant 4.1V (the 2S input voltage will always be far above that) the voltage divider will only ever see 4.1V. If you bypass and just go BATTERY-->VOLTAGE DIVIDER-->MCU you don't have that problem.

Again, voltage cut off really isn't a big deal on anything except for buck drivers as long as you are monitoring the light, since you will see it getting very dim before the batteries get too low.

You can use a wide variety of divider resistors, as long as the ratio is correct for what you want. Higher value resistors are generally better. Let's do a quick example for 6V with a R1 of 30K and R2 of 4.7K:

188 = (6V*4700*255)/((30000+4700)*1.1)

The higher the value of resistor the less loss you get through the divider. You also want to end up at a higher ADC value such as 180 vs. a value like 50 for better resolution.


Important to note the constant: 255 is for 8 bit AToD's. This was back when we worked out that the voltage divider has to be before the diode, specially important for 2S or 4S battery setups.

I got to try it again. With the GT setup I get 102 (8.8V) / 201 (17.6V) which is somewhat near your values.
On the other hand, with the 2S setup, I get 13 (4.4V) / 255 (8.8V)

The only bad thing is, with those values, I get blink-codes of 1.1V and 2.2V if I apply 4.4V or 8.8V to the voltage divider…

Regarding your question of the initial post, some random ideas - I don’t know whether or not something like that already exists (also, I am terribly sorry, but my electronics knowledge is completely based on some simple Arduino projects and I assume there are many restrictions considering the space and power consumption of drivers):

  • Are there any UIs for lights with multiple e-switches around (FSM-based or not)? Like for a light with an e-side switch AND an e-tail switch? I am not sure, but it feels like the next natural step for me.
  • Are there UIs that can be vastly programmed by the user? Like clicking together a state-machine kind of thing in a UI on PC and upload it to the flashlight/flash it as a firmware or just as data. Another way I thought of could be on a smartphone and communication via light signals (flashlight + camera on the smartphone, main light + light sensor (e.g. in the switch). Or via a bluetooth module.

The basic idea is to use battcheck to measure the highest and lowest possible voltage it should be capable of seeing with the desired battery configuration. If these values are between ~5 and ~250, it should be usable after plugging the values into the target firmware. However, if battcheck reports less than 5 or greater than 250, the measurements are outside of the MCU’s sensor range and cannot be used. To fix that, change the values of the resistors in the voltage divdier.

Using a 10-bit measurement doesn’t help, because it doesn’t increase the range. It just adds extra precision which we generally don’t need.

Not yet, but I hope FSM will make that possible whenever hardware exists for it. It already supports a side e-switch with a tail clicky switch, but I haven’t done any lights yet with two e-switches.

A question though… if there’s an e-switch on the side and on the tail, would it make sense for those to have different actions, or should they act like they’re one switch? If they act as one, the user can use whichever one they want, according to which grip style is convenient. If they’re separate, the UI can potentially do fancier things but the user will have to flip the light around for different functions and remember more UI details.

Ish. Some people have done it with bluetooth or USB, paired with a phone app or a PC app, but those lights haven’t been very popular. One even does it with an optical sensor and an app, but it doesn’t really allow very deep configuration.

In practice, it has mostly just been a gimmick without much real usefulness. Remote control via bluetooth can be useful sometimes, especially for lights which can be mounted on a tripod, but that’s less about programming the light and more about just changing the brightness without touching it.

I hope future lights will be easier to reflash the firmware entirely though, and FSM provides some of the framework for letting people mix and match hardware and software. The idea there is to treat it like a computer, where people buy hardware for its hardware specs and then run whatever software they want on it. But that’s still in pretty early phases.

We have some custom drivers that have supported 1 e-switch, 1 power (usually tail) switch to a moderate extent, and maybe 2 e-switches, not sure where off hand. We really need more I/O pins, a more advanced MCU, more memory would help as well.

I’ve started porting FSM to work on attiny841. It’s going okay so far, though I have run into a few things where avr-libc doesn’t support it very well. For example, the clock_prescale_set() function isn’t defined for tiny841. And it’d really help to have some reference code to look at, since other people have done t841-based lights before, but none of that code is available so I’m slogging through the 366-page manual while I try to figure out how to translate everything.

This should also make it easier to use attiny1634 later, which has more ROM and is somewhat better supported. Circuit designers tell me they like t841 better though, since it has more flexible pin layout. And we don’t quite need the extra ROM space yet so 8KiB is still workable.

In both cases, some sort of flashing key or flashing adapter is needed. It’d be nice if those were available for purchase, since I’m not very good at making such small and precise parts myself.

Wow, that's terrific!!! In parallel though, yes - we need the flashing gizmo but also need a real OSHPark board design in a few common sizes, preferably. What are you gonna use for testing? Anyone volunteering for the board layout and design?

I'm very interested, not sure I can be of much help though, accept if you need help in testing or something. Unless there's specific things I could do some research on, etc. I see the 841 is a 14 pinner but still with 8 KB code space, which is ok, but looks like Anduril now is very close to 8 KB.

I’m happy to do the board design, it’s my favorite part of flashlights!

What’s the pinout for the Atmel and what driver design (1+n+fet I assume)?

For the flash adapters, I’m assuming two different designs may be needed. One is the 4x2 or 5x2 arrangement used by Lexel and HarleyQuin. The other is a 6x1 layout. IIRC, both use a 1.27mm or 1.3mm spacing in the wide direction, and 1.5mm between rows.

That 6x1 layout might even be available as an existing part, perhaps, but I haven’t found one with pogo pins. Anyone know if there’s one available, or would we have to make something custom? There are plenty of off-the-shelf parts at that size, but I don’t know of any with spring-loaded tips.

Ahh, the engineer here at work used the pogo pins for his adapters. I'll ask. In a 17 mm size, would this be possible, even with just a FET+1? I would think the challenge will be smaller size boards.

Can we go back to Dark Horse for just a sec?
I have 2 identical lights running it, same FW build and identical HW (except the LED its self) but one has BODLVL1 enabled and the other has no BOD enabled. At normal to full battery they behave the same but once the cell voltage drops below 3.5v [cell voltage] the one with BOD enabled starts to exhibit bad behavior… It no longer allows you to multi-click from on. So say you double click to swap from H1 to H2, the light instantly turns off on the first click of the double click you’re trying to do. It does this behavior in any level (L1 to L2, M1 to M2), not just high.

Again the only difference is fuse settings, they had the same exact .hex file flashed to them.

My first thought is to just flash the fuses on the bad one to disable BOD but I was wondering if there may be a HW solution, what if I added another cap or two in parallel with C2? Is that worth the time to try or do I just disable BOD and be done with it?

Different things - e.g. pressing the back button turns the light on in high mode, pressing the side switch in low or moonlight. I guess if they should do the same it would be sufficient to attach the buttons in parallel(?)

Dunno, never used BOD at 2.7V, ever. Every Q8 out there is using 1.8V, every GT I believe, so pretty much every Narsil light as a minimum. Why are you using BOD at 2.7V?

Also TK uses BOD at 1.8V: http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/fsm/view/head:/bin/flash-tiny85-fuses.sh

Just dunno why you would use something we don't use.

I thought it was more fitting, Idk.
[/Technical explanation of why I did anything, ever]

I remembered you saying you used 1.8 and I thought I also remembered you saying you felt it was low so I went one up from there. Perhaps that memory was just wrong. I’ll go ahead and try 1.8v before disabling it or adding any HW.

But still, even with an exceptionally poor precision R5 (Input resistor of Del circuit) and R1/R2 (voltage divider pair of DEL circuit) 2.7v should still allow enough overhead to not trigger at 3.5v actual cell voltage. And I’m using all US sourced 1% resistors on these things so I thought 2.7 seemed good.
Maybe if I was commanding an increase in brightness I could see a false brown out being triggered but I’m actually trying to go down in output when the first button press shuts it all down.

Edit:

I misunderstood a previous comment, sounds like switching to 1.8v BOD is all I need to do. Thanks!