Flashlight Firmware Repository

Measurements trump theory, and Crux was nice enough to measure a lot of code for power use. :slight_smile:

I still need to fit as much of that as possible into various firmwares. Like, the blf-a6 code only has two bytes left so I should probably use that to shut off the single biggest remaining power drain after LVP.

So my flasher arrived today. I ordered these items:
http://www.dx.com/p/343981
http://www.dx.com/p/268210
http://www.dx.com/p/80207

And it works but … if you look at the clip it got tighter pins than normal female cable pins. Arrgh, but I managed to cut the plastic on the clip around 10mm and bend the pins and then it bloody worked to fit the ribbon cable. :slight_smile: Otherwise the clip seems to be of decent quality. So I managed to get my code in order too, used the one byte reads as suggested by ToyKeeper and got it to work. Got a compiler warning when using a line from blf-a6 but managed to fix it with this:
eep = eeprom_read_byte((const uint8_t *)(uint16_t)eepos);

Don’t ask me exactly why it should be like that, I found the fix on the net somewhere. :slight_smile: Finally there is a simple firmware too, code here:

Bugfixes most welcome. :slight_smile:

The compiler doesn’t fully understand the memory model on the attiny, or that the eeprom address space only has 64 slots, so it expects a 16-bit memory pointer and you’re passing it an 8-bit integer. This is totally fine, but the compiler is confused. You can turn off the warning by putting this somewhere in the code:

#pragma GCC diagnostic ignored “-Wint-to-pointer-cast”

My fix works without increasing size so if compiler is happy I’m happy already. Oh yeah forgot to say, as it turns out eeprom_read_block is just a wrapper for eeprom_read_byte so it’s basically the same thing.

Edit: Damn fast pwm is nice! No more friggin buzzing pwm modes. A big thanks to all who started this driver flasher thing. :slight_smile:

Ok, I have investigated this now. If you enter sleep mode power down all pwm output is shut off. However, full output (255) is not shut off. I found a solution to that and if you make all your pins input (0 bits) all output is shut off. So to properly shut off as much power drain as possible you should first shut off WDT and ADC and then you set pins to input. After that you can enter power down mode. Too bad there is not a power off mode that takes care of everything already.

Sounds like it could also be a race condition… if the PWM wave is high, it stays on; if the PWM wave is low, it stays off? So if PWM is set to 128 it might have a 50% chance of shutting off?

Just a guess.

Frankly i don’t care. With that said, gaaah, I hate it when you’re right. But I guess that’s why you’re the sheriff in town. 8) Yes it seems to be a race. I only tested before with 10% and then it shut off a few times. But if you test 50% sometimes it shuts off and sometimes it goes to full output. It doesn’t matter though as you just set all pins to input and be done with it.

I’m pretty happy with my first driver so I wrote another one. I’m a c noob so I basically just make things up along the way. :slight_smile: And I managed to get just about everything to work except one thing, I couldn’t for my life get the right mode count of an array I pass as a parameter to a function. In the end I found out that it’s not possible and you have to pass the size as its own parameter. grrr. Anyway, it got run time group settings so it’s pretty cool. A seasoned c coder probably can save a few bytes here and there and squeeze a bit more modes into it so happy hacking.

Thank you so much for this!!

I appreciate all your time and effort in enhancing our community as you have.

Toy Keeper, I’ve got your cypreus2 in my EagleEye XA-6 triple build, so far I’m liking it, the blinky modes are fun in the rain. Is there an easy way to make the first hidden mode High instead of Max Turbo? Hitting max turbo on this light is painful in daylight.

Joat, to change the hidden modes, just change the definition of HIDDENMODES so it says “100” or so instead of “TURBO”. You might also want to change the last “PHASE” to “FAST” on the next line. And if you want a short tap to go to max turbo instead of moon (off to moon, med top to high, short tap to either moon or max turbo), you should also change the ‘0’ on the HIDDENMODES_ALT line to the number of the mode you want next (probably SOLID_MODES-1).

So, it’s a little weird… but that’s because I wasn’t planning on putting any regular operation modes in the hidden loop.

Also, one reason max turbo is so easy to get to from off is because it serves as “impress mode”, for when muggles ask about a light. They don’t usually care that it has a nice moon mode, but they’re sure impressed by max turbo.

And thank you back. :slight_smile: I found this site when I was looking for pwm-less drivers to get away from the buzzing. I had zero knowledge about that you could write your own firmware with fast-pwm before. I’ve been seriously impressed with fast-pwm so far. All I can say to all of you is that if you don’t want to flash your driver yourself you should buy one from mtn that already got fast-pwm. I thought ToyKeeper was just talking bull when she said that fast-pwm is almost as good as no pwm but not even the SLOW shower trick seems to work with fast-pwm so I’m happy. :slight_smile:

Speaking of shower tricks, a 24 Hz strobe with 0.3ms duty cycle is lots of fun with running water.

(also, showers are terrible at showing PWM unless it’s really slow… water droplets change shape as they fall so they generate their own light pulses even on constant-output lights… try waving a note card quickly through the beam instead)

Yes the shower must be slow, edited post above. Will test the card trick later but must first go out with the dog in the night and test a few new firmware features i just added. Multi group firmwares are pretty useful after all I must say. It’s amazing how much you can squeeze into 1024 bytes. :slight_smile:

Yes, in C arrays are passed as a pointer to the beginning of the array. If you want to know how big that chunk of memory is, you need to pass the size too.

Also, this means that the symbols for arrays and pointers can be used pretty much interchangeably. The syntax of “array[3]” is basically identical to “*(array + 3)”. Take the pointer, add three of whatever its size unit is, then get whatever is at that location in memory.

Lets just say that I found that out the hard way. Usually I just go by the “if it works don’t try to fix it” philosophy but when you only got 1024 bytes you must code as efficient as possible too.

It works but I’m not really sure I got it completely right though. The rest of the multi group code I got to work directly (didn’t think that would happen). Not sure it’s the most efficient way though but so far so good. Also, I can’t really see the point with battery monitoring (if you run out of juice just pop in another one :laughing:. I only kept the power down stuff and got rid of the low mode. Turbo timer I can see that it can be useful with high power DD drivers though so I also added that.

One effective way to deal with array issues in C is to use the Pascal approach… make it one word bigger than necessary, and use the first item in the array to store its length. Another way is to make it one word longer and put a null at the end, but that means you can’t store any other nulls in it.

Or if it’s hardcoded at compile time, use ‘sizeof(myarray)’ to get its length. But that only works for hardcoded arrays and only when the original symbol is referenced.

Yeah I managed to fix the problem with sizeof as my arrays are hardcoded compile time. But I did read up on the things you talk about too. Stackoverflow has tons of answers on just about any possible coding problem. :slight_smile: But now I ran into another problem, _delay_ms() only takes compile time constants as value! What da heck is up with that? I was thinking about making it possible to set strobe frequency at run time but now I don’t know if that is even possible to do with just a few bytes.

That's the nature of standard _delay_ms(). I replaced it with my own approximate delay function, which fixes that problem and also saves a couple of bytes. See TheStar.c in the repo.

Thanks man! Saved 4 bytes too. :slight_smile:

Edit: Your function seems a bit unstable, it doesn’t work properly.

Edit2: Could it be that it must have 16 bit integers as value because those seem to work properly? 8 bit doesn’t work?

Edit3: Forget what I wrote above, found a simple bug, will report back soon.