E-switch UI Development / FSM

I worked on adding voltage Cal to Anduril. All coded, compiled, ready to test. I made it work to enter the fudge factor via clicks. 5 clicks is 0.25, 7 clicks is 0.35, etc. Max of 10 clicks.

Installed this just now on a SP36, previously had NarsilM v1.3 on it, and been testing it - the voltage fudge factor configuration seems to be working fine!

If I set it to 3 clicks, it reads 3.8V. If set to 10 clicks, it reads 4.1V. A difference of 7 clicks is about 1.75V, so this makes a lot of sense. Now if we (or I) could get this rolled in the official Anduril? Seems like a great feature. I was gonna spend the time doing it with NarsilM but it would be a lot more effort, because I also would have had to roll thermal config in.

Wooo Hooo!!

Well, crap. The Astrolux EC01 is one of my favorite torches right now. My son has one, and I have 3. Now that I’ve sent all that money their way, I find out they’re violating the GPL. I figured since they say right in the titles of their product pages that they’re using Andúril, that they would have done it right.

Another observation:
When I’m in voltage blinkout mode with the cell I have in the light now, the first result is either 2.6V or 3.6V (not sure, the light turns on and off as I do the clicking), probably 3.6V. But later it shows consistently 3.7V.
Is it that turning it on for the split second drops cell voltage by 0.1V and the first blinkout starts before the cell recovers?

Tom E,
Great feature, but it will be used once after flashing firmware and forgotten

True, hopefully, but that's the point - just like thermal config settings. I'm tired of re-flashing simply to tweak these settings, like I've been doing for years with Narsil. Also, there's been a lot of complaints in production lights on the inaccuracy of the voltage readings, so we will have a fix for that.

I've noticed this in my Anduril lights as well - usually a 0.1V variance, but not sure if it happens in Narsil as much. Well, the D4SV2 is a 1634 light, so the low pass filter is enabled in the cfg-emisar-d4sv2 file. Just reviewed it, and it's the same low pass filter I implemented in Narsil, actually first written by DEL. DEL's/Narsil's implementation is interrupt driven for the A-D conversions, and best as I can tell, so is Anduril, but the interrupt processing is deferred. Her interrupt handler is 1 line of code in fsm-wdt.

The only difference I can see between Narsil and Anduril is that Narsil throws away the first, or every other ADC voltage reading, and Narsil doesn't defer the processing.

So the cell will lag under load - I've certainly seen this, though I thought it was with more weak type cells, like 16340's, etc., but maybe even on a good cell, the lag could be seen as a small dip.

Awesome Tom E, sounds like a very worthwhile addition!

I guess that battery sag could be fixed by blinking number of volts , reading voltage again and blinking 0-1 numbers for full volts and then the decimals. Careful not to blink 4.9.
Or better: blindly do 2 blinks and then the rest.

Might be easily fixable by a delay. I recall from DEL, there was a reason to skip the first reading... This was back in the day of the Q8 development.

The low pass filter we use is still subject to 1 off glitchy readings - it's not doing averaging of any kind.

This seems beyond my skills so far though…

It’s in the datasheet. If swapping between temp readings and reading VCC, then this applies: “The first ADC conversion result after switching voltage reference source may be inaccurate, and the user is advised to discard this result.”

Another thing to consider when reading MCU VCC as battery voltage is that the voltage drop over the diode is only the same if the current draw from the MCU is always the same. Alterations in current draw from MCU do lead to alterations in voltage drop. It’s different depending on diode of coarse, but the drop over the diode is not fixed, it is current dependent. I didn’t bother about it with the good old fashioned 7135 & FET drivers but it became much more noticeable when I started powering some components (like digi-pot) directly from the MCU pins. I went back to using a voltage divider.

Ahh - ok. I'll have to check Anduril again for support of this. Is it true then using the external voltage divider would solve all the flaky problems we see in voltage readings/reports?

It's a shame because with a FET+1 driver, pin #7 is a spare but we stayed away because of the extra amp draw in e-switch lights. I've used higher values for the voltage divider resistors to reduce the parasitic drain and it seemed to work well.

For me it was a no brainer with the divider because of current draw when turning digi-pots on/off and having 4 output channels on/off made the readings pretty bad. I had moved on from the 85 when I started doing these kind of things so pins wasn’t an issue.

I’m using the 3217 now so I definitely don’t have a shortage of pins. The negative side of my voltage divider does not go to GND, it goes to another pin so I can control it’s connection to GND. When shutting down on E-switch lights I just set to high impedance input and turn on the pull-up resistor, that entirely eliminates parasitic drain from the divider.

That's a nice feature, to eliminate the parasitic drain.

I wonder what would it take to merge that into the main source tree…
What kind of maintenance would be needed? I guess only adding cfg files?

No idea - I'm totally confused with that mgt UI. I use git at work every day, not on the web, but with a master repository.

I got base mods to Anduril itself (anduril.c), fsm-adc, setup files, and of course added the project and solution files for Atmel Studio.

Also added voltage reading calibration to the UI - 4 clicks std method.

Yes, I assume so. I didn’t even know it existed.

That would be helpful.

I don’t think it’s a lack of willingness though… more a lack of understanding how free software works and what is required of people who sell it. The license is easy to satisfy, but seem hard for people to understand when they have never encountered anything like it before.

Usually when I bring it up, manufacturers are just like “Oh, that one uses Anduril, and the other one uses NarsilM. You’re welcome.” … and then I’m like “Knowing the name of the firmware doesn’t help; what is required is a file containing the exact source code used on the product, and a way for everyone to get that file.” :frowning:

It’s also hard to get info about Astrolux products in general, since it’s basically a reseller brand name which gets put onto products from other companies. Some are from Mateminco, but there are other OEMs too.

Nope. It seems like, more often than not, companies make no attempt to read or understand the license. They put “Anduril” in the marketing materials to help promote the product, and sometimes they’ll add a “Thanks, ToyKeeper!” somewhere, but I don’t remember the last time a company actually satisfied the license without me bothering them repeatedly with detailed instructions about what was needed.

Thanks aren’t needed. Source code is needed.

Yes, and it’s used on the D4v2 titanium and brass models.

But the button light and the aux LEDs run in sync with each other. They don’t have separate independent modes. The button LEDs mirror whatever the main LEDs or aux LEDs are doing, depending on which of the two is active at the time.

And then there’s the Noctigon K1 RGB button LEDs, which sort of do a hybrid of both.

The aux LED / button LED code really is a mess though, and could stand to be completely rewritten to make it cleaner and more straightforward. It kind of just built up over time as projects needed it, without being explicitly designed.

That’s pretty cool.

It supports two different voltage measurement methods though, and I’m not really sure how to user-calibrate the other one.

The VCC pin method is simple and merely adds a constant fudge factor to adjust the response curve. However, the voltage divider method draws a line between two arbitrary points, and those points are anything from 0 to 1023. So that would be harder to do user calibration for.

Also, the UI doesn’t generally know or care which method is used. It could access the #defines to find out, but it’d need to implement two different voltage calibration modes and select one at compile time.

This is a good start, but there’s still more to do in order to make voltage calibration work on all supported devices.

It’s definitely possible for the cell voltage to change between readings, especially between the first and second, especially if the memorized brightness is high.

But there’s also another way it can change… the code wasn’t doing very good noise reduction. It was getting a pretty wide variety of different values for no reason other than electrical noise and sensor jitter.

Fortunately, I fixed that. Actually spent a lot of the past couple months fixing that, testing a bunch of different solutions, and finally settling on one which is simple but effective. And the code is now in the repository, as of like an hour ago.

Any variation in measurements now is almost certainly a real change in the signal, not an illusion caused by noise.

Yeah. I was getting a variety of bugs caused by race conditions, so I made the order of execution more explicit. Also, I’m still kinda hoping to implement a PWM-DSM hybrid algorithm to adjust brightness between PWM steps… and that requires very tight interrupt timing, so I needed to move as much code as possible out of interrupt handlers.

Now the race condition bugs are fixed (as of mid-November), and it’s theoretically ready for the PWM-DSM thing, if I ever get around to doing it.

Yeah, the first measurement is junk, and the attiny manual says to ignore that first value.

About averaging, I tried a bunch of different methods and algorithms for that, in hopes of getting a more stable signal and increasing the effective resolution. What I found was that it worked great while the light was at rest, but during actual use the data was too noisy. Even with 2048X oversampling, the signal was still noisy sometimes on hardware with high-amp cells and a FET.

So I eventually gave up on getting extra resolution, and instead focused on eliminating noise as much as possible.

It now samples continuously, with everything left-adjusted so it’s 16 bits… 10 bits of signal and 6 bits of noise reduction. It’s basically 10.6 fixed-point numbers. Each time it gets a new sample, it adjusts the running average up or down by 1, meaning it takes 64 samples in a row to move the needle by 1 full 10-bit unit.

This way, if it’s measuring a value of 100, the raw values may fluctuate randomly between 90 and 110, but the lowpassed value only fluctuates between ~99.95 and ~100.05. So it’s much more stable.

Then it adds 0.25 to that value and does a floor() operation, which makes it a very very steady value of exactly 100. Any change in this number represents a true change in the signal, rather than just random noise.

The value still updates quickly, since it samples a few thousand times per second. But the data it spits out is very, very stable now.