This is the sort of thing a nicer MCU would really help with. However, given the attiny25 as a target platform, getting it to work is ⦠unpleasant.
The standard method is PID, which is far fancier than what bistro does. Kalman filters might be an even better method, or a complementary method. I doubt thereās enough room to do either of those properly though, so I was thinking of upgrading to 10-bit sampling and doing something with the first or maybe even second derivative of the temperature readings. That way, it could react based on whether the temperature is rising or falling, or even if itās accelerating, instead of just whether itās currently too hot or not.
A first derivative would be pretty simple (even on attiny)⦠just subtract the previous measurement from the current measurement. Then add, say, two or four times that to the current temperature to predict where it might go in the near future. If the prediction is too hot, ramp down. If the prediction is too cold, ramp back up. Both adjustments can be proportional to how much the value deviates from the target.
This method would amplify any noise in the measurements though, so depending on how noisy the measurements are, a lowpass filter might be required.
TK, I'm not sure you need second derivative. You have the benefit of knowing that at least if the mode hasn't changed recently, heat tends to move exponentially toward an asymptotic limit, with a fixed relationship between first and second derivative. That means the end point is related to the sum of the preent value and something times the slope. The second derivative helps if there have been recent mode changes and there may be an overshoot hump coming, you could detect that. Yeah, that could help avoid oscillations, as you point out though, if you have the resolution for this kind of correction and the computing power. Notice if you do this well, predictively, you probably never reach turbo.
Oh, also the thermal delays can be large enough that you may already have two unavoidable humps queued up in the heat profile. Hard to predict that. But if you're doing things well from the start, maybe you don't ever have any humps, which is why I think first derivative might get close enough. I think the hard part is knowing the delay well. If you're reading recent changes and assuming you need to adjust but those changes are related to what happened 20 seconds ago, your adjustments are wrong and you're creating oscillations.
The hardest thing about all this is the timescales for the delay are similar to the time scale for the full range change. That spells trouble. Of course we know the reason, the sensor is in the wrong place.
Make sure āmodesā array is defined large enough. And youāll need to mess around with the count_modes function. Reconfigure these lines:
That ā<<3ā will need to become ā<<4ā and then youād have to make yourselfā modegroups 16 bytes long instead of 8. This is a bitwise shift, not terribly obvious.
⦠Or you might take a look at Flintrockās BistroHDās count_modes. I think it handles variable-length modegroup sets.
All of the mode groups must be 16 values long with the exception of the last one. And I think your modes array needs to be bigger. Give those changes a try and let us know. And update your pastebin when you make changes. Good luck!
Oh ok.
When you said āmake yourselfā modegroups 16 bytes long instead of 8ā I thought itās like this
for(solid_modes=0; (solid_modes < 8) āāchange toā-> for(solid_modes=0; (solid_modes < 16) thatās why I changed the 8 to 16 :person_facepalming:
Ok Iāll try your last suggestion. Thanks.
Any of you guys have āHello Worldā equivalent code for flashlights, like simplest code there is!
Something with just one āregularā mode maybe one blinky mode (so I could see how loops work) and thatās it.
I am really trying to understand ramping firmware by TK but I am just not making any progress with my modifications
One of the smallest is DrJonesā MiniDrv. From the looks of it, it is on-time memory, no blinky modes so no loops.
There are also several STAR variants that might be a good place for an intro to looping, etc. Hereās one from JohnnyC. TK also has some STARs worth checking out.
Itās probably missing a define somewhere, or has an old version of tk-delay.h. The _delay_4ms() thing was added fairly recently to save space and make room for extra safety checks. IIRC I still havenāt merged it into trunk yet because I changed some stuff which would require changes in other projects. Maybe now would be a good time to do that.
It needs this in the .c file: #define USE_DELAY_4MS
⦠and it needs the version of tk-delay.h which includes the 4ms stuff. Itās currently in the sandbox branch and the convoy branch, but not yet in trunk.
Thanks TK, first for making all this nice firmwares and then for helping us implement them
So, in Crescendo, after double-tap it will ramp down to poweroff() and then ramp up again,
I thought it would be interesting to stop it after it ramps down but at some minimal output (5) not at powered off led, so you would know that the switch is in on position.
I commented out this (line 684)
this coused it to power off after ramp down (didnt go up again).
Then I tried adding this:
so, if ramping direction is ā1 (we are ramping down) then proceed with ramping until mode_idx is higher than 8, when mode_idx is equal to 8 then it should stop ramping down and jump to set_output (5), (also tried set_mode(mode_idx); because mode_idx should at that point be 8 which is output level 5)⦠bit it alway goes all the way to 0 output (if it were to stop at 5 then you could do short tap to start ramping up again).
I also had one iteration where it went all the way to 0 output and then activated set_output(5) stopping it at level 5 which is kinda ok but I wanted it to stop before it hits 0, that would be correct way.