In general, a FET at PWM 1/255 tends to be like 10 lumens and, in fast PWM mode, pretty voltage-sensitive. It’s really not good at low modes. Adding a resistor basically lowers the effective voltage a bit to take advantage of that sensitivity. However, in phase-correct mode (which this uses by default), it’ll be less voltage-sensitive.

To get a second ramp for FET+1, you would need to use a bigger MCU or disable other features to make room. Memory takes the most room, so if you can live without that, it allows lots of other stuff instead.

It should compile small enough to fit on attiny13 with nothing changed. If it doesn’t, you probably have a compile setting to change somewhere. It needs, at least, “-Os -c -std=gnu99”, which tells it to optimize for size using the C99 language standard.

Okay, I tried it on two FET+1 drivers, one with tiny25 and one with tiny13. On tiny25 I set the ramp to 128 steps, which is really really smooth and there’s lots of room left over. On tiny13 I managed to fit 56 ramp steps after removing the heart beacon.

It doesn’t use the OTC at all.

To generate the ramp, you could uncomment one of the examples or generate a new one using a command line similar to what’s immediately above the example. It requires a working python interpreter though. Here is what I used to generate a 56-step ramp for a tiny13 FET+1:

../../bin/level_calc.py 2 56 7135 2 0.25 140 FET 1 10 1300

The “2 56” tells it you have 2 power channels and want 56 ramp steps.

The “7135 2 0.25 140” tells it the first power channel is a 7135 chip which lights up at 0.25 lm at PWM=2/255, with a maximum output of 140 lumens at PWM=255/255. Adjust moon mode by trying different values for the “2” here.

The “FET 1 10 1300” tells it the second power channel is a FET which lights up at 10 lm at PWM=1/255, with a maximum output of 1300 lumens at PWM=255/255. On a triple, you probably want to specify a higher maximum instead of 1300.

You can also run level_calc.py with no parameters, and it will ask you for each value it needs. This is probably an easier way to do it at first.

This might be closer to what you need:

level_calc.py 2 56 7135 3 0.25 140 FET 1 10 2000

You’ll also need to remove the heart beacon and turn off the fancier version of the biking mode, to make it fit in 1024 bytes. And you’ll need to edit tk-calibration.h to give it appropriate voltage values to make battcheck and LVP work. You might be able to use the battcheck/readings/manker-a6.volts file for that though.

battcheck.py readings/manker-a6.volts
#define ADC_44     178
#define ADC_43     174
#define ADC_42     170
#define ADC_41     166
#define ADC_40     162
#define ADC_39     158
#define ADC_38     154
#define ADC_37     150
#define ADC_36     146
#define ADC_35     142
#define ADC_34     137
#define ADC_33     133
#define ADC_32     129
#define ADC_31     125
#define ADC_30     121
#define ADC_29     117
#define ADC_28     113
#define ADC_27     109
#define ADC_26     105
#define ADC_25     101
#define ADC_24     97
#define ADC_23     93
#define ADC_22     89
#define ADC_21     85
#define ADC_20     81

Or calibrate it directly with battcheck.hex. The instructions are in battcheck/README. Either way though, it needs correct voltage values or LVP won’t work and the battcheck mode will give the wrong values.

I’m still getting weird Crescendo behavior sometimes and I’m not sure why, but most of the time it works.

Specifically, what I see, once in a while, and can’t trigger on purpose:

  • Sometimes after going to a memorized blinky, a tap goes to the next blinky instead of steady mode.
  • Sometimes a double-tap from steady mode ramps down from a higher level than it was just at.
  • Sometimes a single tap to exit turbo goes into ramp mode instead of steady mode.
  • Other random stuff.

I’m not totally sure, but it seems like the noinit vars are sometimes changing during the time it takes to do a quick tap. Like, a bit here or there ends up different than it should be. It tends to only have occasional and minor effects, but it still bugs me.

I’m tempted to make some automated tests for this, to find out if even a robot gets inconsistent results. It’s bizarre how I can do the same thing with it 20 times and get the same result only 19 times.

Anyway, it seems to be working pretty well otherwise.

I flashed to my test setup which is a 4x7135 105c driver, a battery holder, a switch and a led on a heatsink wired together with connectors to act as a flashlight and I be able to change any component easily. It worked perfect. But I not played a lot with it. So easy to use and easy to learn how it works. Great job Toykeeper! After 1 minute of use I like it more than Biscotti. It’s morning here and I’m after a night shift so I go to sleep and try it afternoon in a bleeder resistored lighted tailcap flashlight and a lighted tailcap light without bleeder to see any difference.

Thank you. I don’t need memory or any of the blinky modes except for the voltage check, so I guess the space won’t be an issue for fitting more ramping steps. Hopefully, I’ll have it ready before it gets dark. :smiley:

I think that way too.

I have one driver what worked correct speed with Biscotti and Crescendo, but all on my other drivers I got twice the speed. so the ramping is too fast. I don’t mind this with Biscotti but on the ramping FW it’s too fast to stop at correct level. I tried the recommended fuse settings, also tried change the Lfuse a lot lower and nothing changed. My driver what work good isthe oldest I have home. All others which are fast newer ones. Here is my flashing line: avrdude -p t13 -c usbasp -u -Uflash:w:crescendo.hex:a -Ulfuse:w:0×75:m -Uhfuse:w:0xFF:m
Does anybody had an idea what is wrong? I have a bleeder resistor on the driver. Maybe that is messing with me?

After messing with it for a day, I’m liking it better without memory. It goes directly into a ramp (one could even call it a *ahem* crescendo) from off, and lets me stop it where I want. This also lets me have a bigger ramp or a few blinkies, even on tiny13. And on tiny25, there’s a lot of extra space.

Also, since the random inconsistency was really bugging me, I ran some automated tests(*) on it. It looks like a robot gets more consistent results than when I test it manually… but only when I have it “tap” for 150ms or less. With a 200ms “tap”, the results are inconsistent. So, it looks like those short-presses have to be really short or it’ll sometimes do surprising things. And by surprising, I mean totally random because some SRAM bits decay before others and it can spontaneously jump to any mode or any level when this happens. Maybe I can avoid it by using an even bigger sample to detect long-vs-short presses.

* Just one quick test: click-tap to moon, measure amps, ramp up, measure, ramp down, measure, turbo, measure, exit turbo, measure, off… repeat 50 times and look for any measurements which look out of place.

… time passes …

Okay, there’s now a compile-time option to choose how careful it should be about this. It can use 8 bits, 16 bits, or 32 bits as the sample size… at the cost of 0, 8, or 28 extra bytes of ROM used. Attiny doesn’t really like integers longer than 8 bits.

… more time passes …

The 32-bit sample doesn’t seem to make things more consistent with 200ms taps. I suspect I’m seeing more variation in my test hardware than actual behavior changes in the light itself. It’s all running via shell scripts on a Beaglebone Black with an ACME Power Cape, which means timing isn’t incredibly precise. And each 50-repetition test run takes about 10 minutes. Maybe if I find just the right threshold though, like maybe 175ms, I can measure an actual difference from the larger SRAM sample method.

… more time passes …

Nope. No measurable difference between 8 and 32 bits worth of sample. On both, I get very clean behavior with 166ms taps and very random behavior with 175ms taps. I’ll take out the “XTREME_RANDOM_PREVENTION” code since it doesn’t help. Regardless, it was kind of a fun experiment, even if I didn’t find a way to fix the issues I found. At least it tells me the randomness is due to user inconsistency rather than hardware inconsistency.

No idea. I wouldn’t expect a bleeder to change the clock speed… but it could easily change the timing of the short/long presses, or even make it impossible to do a long-press.

If you’re absolutely sure the driver isn’t overclocked, you can change the speed by adjusting the BOGOMIPS value in tk-attiny.h. Higher numbers should make it run slower.

Im not sure about overclocking. The only difference I can notice that the one atmel which work normal speed has ATMEL1524 TINY13A SSU engraving and the fast one has ATMEL1350 TINY13A SSU. Both drivers single sided but the fast has stars on battery side and has 4x7135s, the other has nos stars and only 3x7135s.
I tried to compile but sadly I have no success because I use only windows on my PC and always got some error. So I only able to flash hex files. Can someony modify and make a hex file for me if it’s not a big problem? Thank you very much for help!
If not then I need to try out some USB linux and step up a level in firmware flashing and programming.

Thanks for your help. I got it to compile using that compile setting. For others who need to do this, the setting is in the Atmelstudio menu: project>project configuration, then in compile settings>miscellaneous. Or something close to this as I don’t have the program in front of me right now.

I ended up putting a gate resistor (270 ohms) between pin6 of the MCU and the FET gate to get a nice low low around 1 lumen.

None of those stars are connected to anything, are they? And not grounded? If they’re connected at all, it tends to interfere with flashing.

If you need to adjust the speed, it helps a lot to have a measurement of how much to adjust it. This can typically be done by using a blinky mode with a repetition cycle of 1 Hz, counting the number of cycles it goes through in, say, 60 realtime seconds. The heart beacon is good for this.

As an example, if BOGOMIPS is set to 950 and you measure 80 beacon cycles in 60 seconds… the new BOGOMIPS value should be 1267. (950 * 80 / 60)

You can also adjust the ramp speed directly with the RAMP_TIME definition, if you want it to be some length other than 2.5 seconds.

Thank you very much! I think they not connected to anywhere but I look it tomorrow morning. I’m at work and the flashlight is not here. :disappointed:

Ok, a few updates to my (unnamed) ramping firmware. It currently compiles at 872 bytes. Not a ton of room left, but 150 bytes still leaves a bit of space for additional features.

  • It now has a proper 64-level ramp
  • Changed around the config menu option (see below)
  • Added double-tap for turbo (from anywhere)
  • Added triple-tap for 8-bar battery check (from anywhere)
  • 3-byte redundancy for fast_presses

Config Menu:

  1. Memory toggle
  2. Stop-at-the-top toggle (without any user interaction, stops itself at turbo)
  3. Turbo Timer toggle (turbo steps down to 50%)
  4. Reset to default configuration

Also, ramping direction is always remembered (except from a cold start). When re-entering the ramp from steady state, it will ramp in the direction is was previously. Because of this, I didn’t feel like messing around trying the “X taps for up, Y taps for down” kinda stuff. After so many tap options, my simple mind starts getting confused :wink:

I haven’t tried Crescendo yet, but I tried my ramping stuff on a light with a bleeder. Seems to work just fine. Like TK said, the bleeder shouldn’t affect it.

That’s really strange. Dumb question, but are you seeing this with multiple drivers? And the same driver is (/drivers are) working just fine with Biscotti?

Thank you TK for developing ramping UI, I flashed it to good old nanjg105C (green) driver.
In ramping mode it starts from off (sometimes starts from low), ramps to max and then goes down, I did have a look at the code, thinking I would find ramping part of the code and try to tweak it to stop at the top but I only had like 20 minutes and got lost in the code :slight_smile:
I hope I will have more time this week so I could try to strip all not needed options until I am left with few things I want
BTW, battcheck is kinda strange, it has 3 sequences of blinking, 4.15V(or 4.19V) = 4-1-2 blinks and 3.99V shows as 4-1 blinks!

Also thanks for your effort gchart, I am looking forward digging thru code (hope you don’t mind) because I especially like this two quoted options everything else I do not need except maybe low battery warning and low battery cut off, does your FW includes this two features?

Once again many thanks to both of you, this is extraordinary work, 3-4 years back I would thought that changing FW on a flashlight is just a SF story :smiley:

Yeah, low voltage step down and eventual cut off is included. That aspect should be pretty similar to TK’s as the initial base is from Biscotti.

Your request is why I added stop-at-the-top. :slight_smile: Not sure if I’d use it much, but it’s an interesting idea so I included it.

I don’t mind your digging thru code at all. Rather, I encourage it. We all have a little different coding styles and I know I’ve learned a lot from others that were gracious enough to share their code.

Lastly, if you run into any issues tweaking it or compiling it, just let me know and I’ll put a hex file together.

FWIW, I tested it and added it to the firmware repository. It’s called “gchart/ramping-ui” unless you want to pick a name.

Everything seems to work as spec’d. The 5-second ramp is a bit slow for my taste, but it’s easy to change at compile time.

BTW, were you running into issues with fast_presses not behaving correctly before you added redundancy for it, or was that just because I was complaining so much? :slight_smile:

Maybe Today I try gchart version and if working double speed for me then it has 2.5 second ramp which is fine. :slight_smile: