Attiny25/45/85 FW Development Thread

Very nice, I will have to give it a try if I build anymore e-switch lights.

Thanks All! But ... Found a couple of minor issues with the v1.3 posted. I updated the source and resulting files. It's all updated now. The changes, as noted in the source code header are:

  • bug fix: error in modeSetCnts for Mode #8: would not have worked
  • reduced timeout from OFF to standby/sleep from 10+ secs to 5 secs
  • change default of twoDigLedOnly from enabled to disabled (Batt/Temp/Vers Ind. LED Only)

I posted a ZIP file of the HEX only, but it has limited use because there are so many compile time settings.

Updated in the same location as linked to before: My Google Drive Share for NarsilTriple. Please note the ZIP files are todays date, time of 5:45 PM (not sure how that works across time zones).

Tom, I am very appreciative of your efforts! This is an exciting firmware and will be implemented right away. You’ve thought through so many things and it allows someone like me to have something to keep my mind engaged. My mind needs to learn complicated things yet I am unable to learn as I once could learn which means I need these complicated to be easy complicated things. :wink: Sounds like it doesn’t make sense but to me it is a big deal.

So a big thank you to all you guys involved in helping me interact with these exciting and mind stretching projects!!!

Looks like some great work. I haven't really looked much into narsil honestly, but I can appreciate the work anyway.

I played a little with a genaralized function to interpolate sparse tables. A straight forward implementation added about 180 bytes vs the full lookup table, and that was after probably saving about 30 in the table itself. Some hacking up a division algorithm brought that down by 30 bytes, but also added more constraints (no gaps greater than 31 in ADC channel, with 8 step intergap resolution). You'd need really several tables before this wins.

There are probably better ways to just make a single simple straight line (or more tailored implementations of the same way possibly). These machines can multiply, they just can't divide, but 8 bits makes everything tricky (you can't multiply anything bigger than 15*16 without going to 16 bit).

So these things are heavy I'm afraid, as gchart also found.

I'm polishing off a few little adc stability things that Vcc and some OTSM related powersaving caused. Then I'll probably put this out for others to test.

Speaking of narsil though, I just realized that this bistro OTSM code, possibly with as little as one preprocessor define to change the pin ID, would turn bistro into an e-switch firmware (if that doesn't already exist somewhere, not sure). OTSM is essentially just an eswitch anyway, just that it measures how long the switch was pressed. It would just need a check to prevent the counter overflow, and at the same time probably switch over to longer watchdog times after a couple or few seconds of wakes. Why wouldn't that all work?

...

Oh, yeah.. just remembered, the e-switches are momentary? Just a push to make switch? So it would need a little extra for the toggle. How do these e-switch softwares work, long press for off? Short press/medium for controls then?

I was wondering bout that. I might not fully understand what OTSM is exactly and how it works, but think'n it just might convert a power switch into an e-switch. Bistro certainly is not designed that way. Power switching and e-switching are two different architects. e-switch firmware requires somewhat precise measurement of button press's. The common implementation is the 16 msec timer being used to poll for button presses and releases, with simple debounce logic. Having the capabilities of Bistro and adding e-switch support would normally add a considerable amount of code. Big reason why I went to the 85.

In Narsil, the critical stuff is done in the watchdog timer because it's so sensitive in acting on switch state transitions, mode based. The main loop acts on events detected by the timer. You can easily get caught up in trying to do everything in the timer, but that's a mistake - the timer should simply schedule things for the main loop to execute, such as controlling the LED output, doing the low batt signals, acting on over temp conditions, blinking out statuses, etc. If you keep to the rules, generally things will work fine. I mostly get into trouble when I break those rules, and then get into conflicts/time sync issues between the timer and the main loop.

For Bistro, it's actually much simpler, single threaded, one main loop. More like a straight sequential programming model.

Yeah, I've been struggling with exactly those model differences. I was almost going toward having the main loop process interrupts, and adding a global timer, and having adc multiplexing in background between thermal, Vcc and whatver. But in the end I did things differently. There's an interrupt that senses the switch go down, and puts it into a watchdog loop, counting times on wakes. A final pin high interrupt wakes it the last time where the real trick happens (I'll get there). For eswtich instead could just use a faster watchdog at first, and slow it down later, but I need a slow(1/4s) watchdog to save power for OTSM so the extra pin wake makes it respond faster. This is all a very nested/re-entrant web of interrupts that's very non-recommended, but works great anyway, and all to avoid the recommended way of setting a flag and handling the interrupt in the main loop. As you say bistro just isn't designed for that. I went through seeing what that would take, and it's possible of course, not even terrible probably, but definitely more work, less incremental, and more chance to create more problems.

Anyway at the wake, have to back up, the trick is that the main loop is not main() anymore. main() just sets some default values for cold starts, and calls a function that is the main loop, run(). At the wake up I reset the stack pointer to RAMEND (very uncivilized but effective) and call run(), restarting the program but bypassing initialization of main() thus keeping the wake counter and anything else I want. So I've created a goto out of the interrupt back to the beginning.

So I guess the light shouldn't go off during short clicks on e-switch. Ok, so just replace sleep with delay until the few second threshold I described. I think it could work.

Ahh, ok. The change of frequency would be a complication I suppose, can be handled though. Also wondering bout the switches. True e-switches are generally made for that. The mechanical rev and fwd clickies are generally not designed for frequent use. I'm pretty fussy bout the feel of the switches on e-switch lights. I much prefer an easier engaged switch, which they seem to be going away from. Mechanical switches to use as an e-switch? Dunno, I'd have to check a few and see.

By the way, the watchdog isn't the only useful timer. I've also setup a TCNT0 timer that I'm using for idle-mode delay loops. The rate in this case is constrained constrained by pwm configuration to 8 overflows per ms, but you I could see faster if I looked at the clock itself instead of overflows, and a 16bit overflow counter can still go out pretty long too if needed. It seems more flexible to me than a watchdog for power-on use, but then you don't always need 1ms resolution. I needed it to sneak idle sleeps into the strobe delays.

No, no.. I'm fine with bistro on clickies. No negativity meant but I'm not sure I'd love the ramping of stuff of Narsil. I'll try it once I have an eswitch light and who knows, may love it. But I was just thinking of this for true e-switch lights, like having bistro for the Q8.

OH.. just got your point about frequency.. in the wake. Yeah, no big deal. I need a timeout after n seconds of wakes to do a couple of things for sure. It's not required to change the frequency, just would help with drain some, but with BODS working, I'm already getting great drain at 1/4s, from an e-switch perspective.

Yea, in NarsilTriple I'm using the ADC complete interrupt for 1.1V ref LVP and temperature reading. DEL developed this code and I integrated it into NarsilTriple. What I like bout his LVP is it's algorithm based, no lookup table, and seems pretty accurate. Plan is to drop it into standard Narsil (2 channel) as well so we can have temp monitoring and lower standby drain in the BLF Q8.

For the Q8, we are already committed to the 2 channel driver design, so too late to convert. DEL has his own 2 channel SRK driver design as well, which I like the look of, but again, all too late for the Q8 project.

Wish I could combine the 2 Narsil source branches into one master - might look into that. Compile switching may get a bit crazy...

The algorithm definitely sounds nice. For Vcc reading though, I just don't believe it will work for accurate battery checks (anything will work for just LVP, you just need to calculate one value and the compiler can do the calculation unless it's UI configurable). Anyway, the Vcc ADC results end up very curved, mostly because of how it must be read.

Yea, under normal circumstances, I've found over a wide range it seems pretty accurate - pulled the cell and tested on a DMM. I'm think'n where it goes astray is under heat, or under load, or both, not sure. The other day thought I saw a reading of 2.n V when the cell actually was 3.2V when pulled.

A table won't do any better as far as those things. If anything you could correct for heat with an algorithm, but that's going a bit overboard in my opinion. It's jut this Vcc curve that's pretty hard to calculate with a machine that can't really do math. In excel I calculated it real accurately, real easily. On attiny85 it could still be done though. It just takes a bunch of bytes. Math takes steps. It's either built into the machine, or it needs instructions, and the attiny25 is stuck either way.

ADC Power

Been testing some power things to get a feel for some details like pin state settings.

While I was at it I tested the ADC in the sleep loop again, now with very different software than before and a little more carefully. With a 64x adc prescale (standard in bistro) and 1/4 s sleeps it adds 5uA to the average current drain during a loop (where most of the time is speant sleeping) That's turning the ADC off before entering sleep. It's not actually the ADC power causing that increase though. The ADC power is small compared to the CPU power. It's the time that the ADC keeps the loop awake that adds that power. With a 4x adc prescale, still more than fine for detecting wake, it makes no measurable difference at all to the sleep loop (should be about 16 times less, so about 0.3uA).

That 5uA would go up to 10 for a 1/8s sleep loop (because the relative amount of time on is twice as much) which would matter even without BODS, but just lowering the prescale fixes it. I'm not using the ADC in bistro anyway, but I'm not ruling it out as a valid option, and it could be used to reduce voltage constraints the divider. The open question is still if impacts shutoff detection speed, but I don't see it being the case. The adc can run pretty fast and these fall times with present hardware are at least 250us.

The more important thing I learned is that I don't need to worry about leaving the adc on during normal on time, because the power draw compared to the cpu or even compared to idle clock power isn't much. That will help with stabilizing ADC reads. I have things within 0.2V already. I think (well the manual says so) that switching to the 1.1 Vref as the voltage to measure (what is done with Vcc), requires a few ms of stabilization. That may be trickier than it seems with the present main loop and thermal measurements with strobes, but I'm sure it's not too bad, just haven't tried to fix it yet. Actually I probably broke in the first place.

Flintrock, considering your testings do you concider it possible hardware wise, to create a blf four channel driver in the near future. Application mainly RGBW controlling.

+1 I want it too! :smiley:

You mean will I write one? Probably not. Is it possible? I'm not sure. I'm not at all sure 4 channel PWM is possible, but I just don't know.

Of course there's the issue of what pin to put it on. In an eswitch light or a >1-S light, you'd have to get both switches and the voltage measurements crammed on the same pin (or maybe piggyback the switch and reset pins, hmm..). That would require using the ADC for the switch detection. That's possible, but it's not what I have now and it's very significant change, because it requires the adc running full time on interrupt control, switching between channels essentiallly in the background, instead of polling it as bistro is setup for, so a pretty big change.

Going to an ADC based system would provide more options, but not sure if I'll do it.

That switch on the reset pin might be simpler than the adc route, but it requires a little hardware, diode or resistors, to keep the switch voltage above the reset voltage.

Come to think of it, all that only applies if you need the tail switch and e-switch to behave independently, and it's not a big issue for non-eswitch 2S lights (just mis-spoke), just lose one place to add more capacitance.

If it's good enough to have the tail switch and e-switch behave the same, they can double up on the divider pin as things are now, with no change.

4 channel PWM is certainly possible. We're doin 3 channels now, and I believe the ATtiny 25/45/85 can do 4 channels with PWM max. But these Atmel's are I/O pin limited, so not the best choice, or could use an external mux. An EE design engineer I work with designed a driver for mux'ing 3 or 4 output channels for a marine application - cockpit lighting, but before he even got to the prototype phase, a pretty much exact matched product came out on the market for a decent price, negating the purpose of producing it. There's been an SRK driver developed using the ATtiny84 a while back, mentioned here, but never open sourced. The 84 has 12 general purpose I/O pins instead of our limited 5 I/O pins, so you got a whole lot more of versatility. It's a 14 pin package though, not 8, so takes more real estate, more complex driver design.