While doing the programming for the V2.0 revision I decided that I really wanted to try my hand at making an interrupter all on my own, without relying on someone else's code as a basis. While it sounds like an easy task it really is difficult because of the hardware limitations inherent with the ATTiny and ATMega chips. Primarily, they overflow variables at 2^15, which means if you're doing math in microseconds you can do frequencies below about 32Hz. You can of course do math in milliseconds, but you can only do integers, not floats, so timing accuracy and variability suffer. The way around this is to cleverly use both uS and mS to achieve your desired goal.
I wanted to make improvements upon the previous version of the software, and while I have done that in some regards, in other ways V2.0 is superior to V3.0. Particularly, I found there is a hardware glitch present between 34Hz and 54Hz where the internal timer subsystems don't trigger the GPIO pin states correctly despite having the correct values in the variables. I thought about writing to the hardware registers directly and avoiding delay() calls but it really didn't seem work it. So, I simply set a fixed duty cycle for this 20Hz wide range and decided to live with it. If you want no interruption in duty cycle variability, use V2.0 instead. However, V3.0 does have some nice features; no limit on maximum duty cycle. I've tested it up to 95%, though the current default implementation only allows for 50% maximum as I couldn't really find a use for >50% duty during field testing. I have a version of this software available upon request if you would like it, just tell me you want "rev 3.0, not rev 3.1". 3.1 is the internal name for this 3.0 release because if I labeled it 3.1 everyone would ask me "you went from 2.0 to 3.1?". It's a lot easier to modify the minimum and maximum frequencies now as well with clearly labeled variables for these two parameters. Minimum duty cycle is set at 2.5%, and going so low involves some clever use of nested conditionals to avoid pitfalls that occur when you aren't able to use floats in some places and are limited to 2^15 in other places. V2.0 avoids this by limiting maximum duty cycle to 10%, V3.0(internal) avoids this by limiting minimum duty cycle to 10%. So in this release we actually have 2.5%-50% duty cycle output.
Like with V2.0 there's reduced GPIO and Hardware requirements, and as such CW mode can be accessed by turning the frequency dial to maximum. I've ported the code to Arduino for ease of use as well. I've learned to loathe the ATTiny85 chip over the years simply because of its increased limitations and lack of an integral USB interface or bootloader.
Here's the files and diagram for the Arduino UNO version:
Here's the files and diagram for the ATTiny85 version: