First line goes to ToyKeeper, the original author of bistro.
"Universal Edition" (kind of a box set, 64 hex files!). Lots of new and fixed stuff.
OTSM is working in a light! Solid stable click times, configured in fractional seconds and insensitive to resistors or temperature. See manual below for build details on a 17mm TA v1.
TAv1-OTC and TAv1-OTSM both are well tested, advancing this to Beta release 1.0. Other new features are still alpha, some untested.
Here it is, include (many) hex files this time and much reorganized build and configuration system.
version 1.0 first working OTSM version, well tested
version 1.1: relatively minor changes, still tested, should be fine.
Version 1.1 Adds TA LDO OTSM firmware, and a second dual-switch build.
Version 1.3-r2 (there was no 1.2) adds new thermal control and dual switch modes:
-TURBO_TIMEOUT tap-up didn't work, probably fixed (not 100% tested).
-ESWITCH menu lockout didn't work, maybe fixed it, took a stab at it anyway, but no testing. Never was sure I liked it anyway.
-New TA v1.3 modegroups are included. I've also added 1 old mode from original and one hybrid of my own. The modegroup file for details, the extra modes are not well documented yet.
-OTSM_powersave which is not only for OTSM, is now available to save power on attiny13's too now (4mA to 2mA for on-current if similar to attiny25).
-New temperature step-down option, like BLFA6 turbo timeout and tap up, except the drop down is temperature-triggered. A minimum (not max) time in turbo is set to 10s by default.
-Both the minimum time and the level to step down to are configurable. All levels above that will get thermal protection (except strobes, in bistro way, reading temp is too slow to work with strobes).
More space savings, about 50 bytes, but this was mostly re-used by the new thermal stepdown and added modes.
-Trying to clean up cap-timing section and comments, adding clear preprocessor sections for every possible switch and timing combination.
1-switch: no_init, OTC, OTSM
2-switch: Eswitch + nothing, no_init, OTC, OTSM, or lexel mode.
-Dual switch noinit has a better chance of working correctly now (no eswitch or dual switch lights have been fully tested).
-Dual switch OTSM is discontinued for now.
-Dual switch dumbclick option/build is added. by request of Lexel, the power switch does nothing. It comes back on in the same mode it went off.
- Dual switch turboclick option/build is added. Variation of lexel request (that I like), power switch always comes on in first hidden mode (typically turbo).
-1.3-r2 adds a one-click compile script that works with Atmel-Studio 7.0 and instructions for using it.
Ideas for farther ahead:
Try shortening medium click for OTSM, may require adding finer timing resulotion for all times, or possibly just early times. (has a cap performance cost, but it's performing better than needed now).
Maybe rework dual switch stuff so every click type can be given assigned an action type in the configs. Hard to keep the programming tight, and clean, but avoids endless options.
In particular consider reverse click order for power switch, maybe separately from above plan.
Manual updated v1.3
Flintrock, 2017 (C)
Licensing philosophy (for the manual only, code is gpl 3) Modify and distribute
all you want, but presenting it as if you wrote much more of it than you did is
immoral and fraudulent. Credit to others avoids that and generally goes
appreciated too. That's it.
i. The Basics
Bistro-HD is setup to be easily configurable to produce a bistro (originally by
ToyKeeper) customized for your needs, your driver board, your attiny version,
the features modes, strobes and groups you want, with a one-click build script,
and extra work on space savings mean you can fit more features in including
several new ones. The original flaship feature is OTSM, a stable click-time
replacement for OTC. Other new feautres include e-switch support, voltage read
from Vcc pin, 4-channel support, and more, all fittin into an attiny25. Builds
for attiny13/45/85 also are made though. A large combination of builds already
exist in the hex directory including biscotti, TA, classic, and battcheck
Essentially, while there's a ton of overhaul under the hood and some new
features, it's still ToyKeeper's bistro. Short clicks advance to next mode.
Long clicks (or leaving the light off) resets unless memory is enabled, then it
returns on to the same mode it was in. If OFFTIM3 is compiled in and medium
clicks are enabled in the menu then medium clicks go back one mode or go into
hidden modes from the lowest mode. A menu toggle can enable an extra moon mode
if compiled in and turned on, and another option allows mode order to be
reversed. See bistro documentation for full details:
Many fast clicks enter the menu as described there. I will try to keep the
same menu options as listed there and below with the same numbers. When menu
options are removed from a configuration, that item is skipped in the menu
sequence. This way 5 will always be modegroup selection in all drivers, for
Presently the menu options are:
1: muggle mode
3: enable moon
4: reverse modes
6: Enable medium click
7: Temp cal
9: toggle e-switch on and off (very uncertain feature, may get removed)
The downside of this approach to fixed menu numbers is that the multi-blink
menu can't be shortened as neatly to a menu more like the modegroups menu. Menu
options beyond 10 are going to get pretty annoying (that's about 50 blinks and
10 strobes to wait through).
I NEW FEATURES (or renewed)
in order of newest to oldest
The biggest feature is maybe easy configurability and big space savings. Other
new experimental features take advantage of the extra space. The easy
configurability means the entire bistro family can be kept in one code, and the
included Makefile automatically builds all configuration for every compatible
attiny version and a battcheck build compatible with each configuration. BLFA6
even almost works with all features, but to get that lean in a small build may
not be possible without a dedicated code. (A BLFA6 emulation is included, but
the attiny13 build is too big. If you happen to like it though you could
customize it for an attiny25). The new features are:
Makefile to build every configuration on each compatible attiny, and with
battcheck builds for each, also produces preprocessed source code file in the
Preprocessor-output subdirectory for each build (with license text included,
but other comments stripped) for streamlined code review, or debugging.
Easy compiling even without Atmel Studio! See instructions below.
Separated config and modegroup files from bistro.c for clarity.
Battcheck builds for every firmware for blinking out ADC values.
Biscotti builds fits Turbo-timeout and might have enough bytes left over to
configure in another small feature.
Turbo-timeout for attiny13 (biscotti build). Just like BLFA6.
"safe presses": See option description below. Improves on ToyKeeper's noinit
method, making OTC-less click timing more reliable.
STAR3: Untested.. use star 3 to enable memory mode.
OTSM with BODS: The feature that started this, now fully functional. The idea
is that power-off time during clicks can be reliably measured by powering the
mcu in sleep mode with a large cap to measure click times. This is much more
reliable than OTC and doesn't change with every electronics change on the board
or with temperature (turbo). Using it requires different component selection.
See OTSM section below for details. This is the first OTSM using multiple power
saving techniques in order to work with relatively small capacitance.
ESWITCH: Not extensively tested. It works much like standard three-speed bistro
clicks. Short and med presses work as usual and a long press turns off the
light. Presently any press turns the light back on. The only lockout option is
a global lockout to entirely disable the switch, for example in a two-switch
light. This is kind of demonstration concept. It might need changes in UI.
4-channel: Now supports up to 4 channels of PWM in any combination. The
attiny24/45/85 only have 3 independant waveform generators, but the 4th is
achieved with clock-triggered interrupts to toggle the output. Full off is
achieved on the 4th channel inspite of the limitations of the method. This is
done simply by overriding the PWM and shutting the channel off. A PWM setting
of 0 still creates a nice moon.
VCC voltage read: Can read voltage from Vcc without use of the voltage divider
(or need for R1/R2). Can also reference voltage reads to Vcc, needed for some
Parameterized voltage calibration: Allows single measurement or small
corrections for calibrating the voltage (for LVP or BATTCHECK).
II Pre-defined builds:
Several preconfigured builds are included.
Many represent rebuilds of older versions. Most are untested, but many of the
features included in the builds are tested (a few aren't yet).
default: This has no gauranteed setup. Probably will remain a Tripple build and
may have new features come and go. It's purpose is to be THE definitive
baseline configuration file, including all the latest build options (although
some will be commented out, but still there). If starting a new configuration
from scratch or studying the options, this is the one to look at.
attiny13 compatible builds (will auto build for attiny13 and above)
battcheck-divider: flashes adc channel for voltage read from divider using 1.1V
biscotti: Original biscotti, but with TURBO timeout on attiny13 (or thermal
control on 24/45/85), SAFE_PRESSES (see configs above), and a few bytes
left to add your favorite options (moon control or firstboot might fit for
instance, or another strobe, especially if N_SAFE_PRESSES is reduced to 3)
BLFA6_EMU: This doesn't actually fit on the attiny13 but the attiny13hex is
made anyway. You could remove a strobe and it might fit. It's about 40 bytes
too big. But it should work on the attiny25.
attiny25 compatible builds:
TAv1-OTSM: The flagship build, rock solid no-fuss time-based click timing for a
1S tripple channel build with the TA modegroups, using Vcc voltage reads.
TAv1-OTSM-LDO: A version for LDO build (2S 3S etc mostly). It reads voltage
from the divider instead of Vcc, but requires more precise resistor selection,
and of course an LDO voltage regulator. See OTSM build section below.
classic: Original bistro configuration and modes.
trippledown: Original trippledown configuration and modes
TAv1-OTC: Essentially the original TA version of trippledown and its great
modes. OTC for first generation builds. Room left to add many more modes.
dual-switch-noinit-TA: There at least a couple of ways to do this, more with
some minor code changes. This one use TA modegroups, and trippledown layout
and noinit RAM decay check for timing the clicking switch (no medium presses on
the clicking switch). This requires the e-switch and OTC are on the same pins
and probably want some resitance inline with teh switch to bring the cap down
If the driver is built with OTSM the click switch will have normal
functionality. There is an issue with this configuration that high divider
resitance needed for low switch drain is contradictory to low divider resistance
needed for OTSM. For now, using the click switch when putting the light on the
shelf is the solution.
If the driver is built without OTSM the click switch will reset (long press)
based on mode memory, which can be useful too. The voltage pin senses power-off
(so clicking switch). And voltage is monitored on Vcc (for a 1S light). I will
probably make a divider monitored version soon and will add a default click
mode so the click switch can come on in a pre-set mode even with OTSM or noinit
4channel-dual-switch: Places the ESWITCH on the voltage pin, and uses OTSM for
timing the clicking switch, same issues as the three switch version. Another
option is to use safe_presses. However that combination isn't supported yet.
If a normal C2 cap is used, the clicking switch will always get read as a long
press, either resetting to the first mode, or the last used mode. More thought
needs to go into dual switch builds.
All this dual switch stuff is very in flux.
.. others emerging.
III Quickest Start
Go to the hex directory, choose one for the right version and attiny, and flash
it. See fuses chapter below.
As described above the included Makefile builds all configurations on
attiny13, 25, 45 and 85 and each with a battcheck build too. Like other builds
the battcheck hex must correspond to your driver layout and attiny chip. It
also must correspond to the voltage reading method you're using. This is why a
battcheck is made corresponding to every firmware combination.
You can compile from within atmel studio you can use the included batch files
together with either Atmel Studio 7.0 installed or WinAVR 20100110 using the
included batch files. The batch files use the included Makefile for compiler
configuration. Within Atmel Studio you can use the included Makefile , or the
normal atmel studio way. Both are described here, but using the Makefile means
you'll get the same build configuration as the default builds and should be
able to recreate exactly the same build sizes. On the other hand using the
normal Atmel Studio way allows the debugger to work. Note that hex's built
with the Makefil will end up in the hex/ directory and hex's built the AS way
and without the Makefile will end up somwhere like Release/bin/ so don't use
the wrong one.
IV.1 Using Atmel Studio, without the Makefile:
You can compile a single build in the usual way in AS. You can even use two
build configurations under Build->Configuration Manager, one for Makefile use
and one for normal single-hex compiling. For single hex compiling without the
Makefile, be sure to select the correct device in device tab of properties.
Selecting it in the code configuration alone is not sufficient when compiling
with AS. Debugging without the Makefile is fine, but to be sure get the best
compiling options, for the final build, your best bet is to use the Makefile.
The resulting hex file will normally be found in the "Release/bin" subdirectory.
IV.2 Compiling with the Makefile
IV.2.1 One-click compiling (double click really)
Advantages: uses some compiler options as release builds used. Does not require
importing files/project into Atmel Studio. You can edit code and configuration
files in any editor you want, including Atmel Studio, but you don't need to
import or create a project.
There is an included Makefile that configures what hex's to build and how to
build them. Two different bat files are included. You can install either
Atmel Studio 7.0 or WinAVR 20100110. Tested builds were made with Atmel Studio
If you installed Atmel Studio 7.0 with default directory choices, simply double
click on "buildall-AS.bat" in windows file explorere to build all standard
If you installed WinAVR 20100110 with default directory choices simply double
click on "buildall.bat" to build all standard configurations.
The hex files built this way will be left in the hex subdirectory.
If needed you can edit the buildall-WinAVR.bat file with your install path
information. Or you can edit the GCC_DIR and INCLUDES in Makefile itself if
you want to just type "make all" on the command line. Even if using Atmel
Studio for editing and debugging, WinAVR seems to compile faster, which matters
with >50 hex builds.
To configure which hex's are built see notes on editing the Makefile in next
IV.2.2 Atmel Studio with the Makefile:
To use Atmel Studio with the MAkefile, edit the Makefile and make sure the
GCC_DIR and INCLUDES matches your atmel install, but by default it should work
for AS 7.0. You want to conslut a guide on building firmware in AS if you don't
know how already. After you get the code imported into an AS project, in
Project->Properties->Build click Use External Makefile and select the file:
Makefile. Then cntrl-alt-F7 to compile as usual.
IV.2.3 Makefile tips and tricks:
After building, the output window will show the size of all build combinations
produced. This build method is particularly useful when modifying the code, to
make sure all configurations still compile, and with anticipated sizes.
Using any of the Makefile methods you can instead compile only single firmware
by uncommenting a ONE_BUILD define in the Makefile. See comments and examples
there. The configuration that is built in that case is determined by that
option, *not* by the configurationg file defined in bistro-HD.c
Have a look at the Makefile to customize which files to build. Notice that
pre-processed source code is output in the Preprocessor-out subdirectory. This
is very helpful for debugging.
Finally you can uncomment NO_BATTCHECK to disable battcheck builds (saves a
An example build summary looks like this:
text data bss dec hex filename
704 0 41 745 2e9 .\bin\battcheck-4channel-dual-switch-HD-attiny25.elf
712 0 41 753 2f1 .\bin\battcheck-4channel-dual-switch-HD-attiny45.elf
712 0 41 753 2f1 .\bin\battcheck-4channel-dual-switch-HD-attiny85.elf
352 0 25 377 179 .\bin\battcheck-biscotti-HD-attiny13.elf
372 0 29 401 191 .\bin\battcheck-biscotti-HD-attiny25.elf
376 0 29 405 195 .\bin\battcheck-biscotti-HD-attiny45.elf
376 0 29 405 195 .\bin\battcheck-biscotti-HD-attiny85.elf
542 0 35 577 241 .\bin\battcheck-classic-HD-attiny25.elf
546 0 35 581 245 .\bin\battcheck-classic-HD-attiny45.elf
546 0 35 581 245 .\bin\battcheck-classic-HD-attiny85.elf
526 0 39 565 235 .\bin\battcheck-custom-HD-attiny25.elf
530 0 39 569 239 .\bin\battcheck-custom-HD-attiny45.elf
530 0 39 569 239 .\bin\battcheck-custom-HD-attiny85.elf
526 0 39 565 235 .\bin\battcheck-default-HD-attiny25.elf
530 0 39 569 239 .\bin\battcheck-default-HD-attiny45.elf
530 0 39 569 239 .\bin\battcheck-default-HD-attiny85.elf
684 0 40 724 2d4 .\bin\battcheck-dual-switch-dumbclick-TA-HD-attiny25.elf
692 0 40 732 2dc .\bin\battcheck-dual-switch-dumbclick-TA-HD-attiny45.elf
692 0 40 732 2dc .\bin\battcheck-dual-switch-dumbclick-TA-HD-attiny85.elf
640 0 34 674 2a2 .\bin\battcheck-dual-switch-noinit-TA-HD-attiny25.elf
648 0 34 682 2aa .\bin\battcheck-dual-switch-noinit-TA-HD-attiny45.elf
648 0 34 682 2aa .\bin\battcheck-dual-switch-noinit-TA-HD-attiny85.elf
656 0 39 695 2b7 .\bin\battcheck-dual-switch-turboclick-TA-HD-attiny25.elf
664 0 39 703 2bf .\bin\battcheck-dual-switch-turboclick-TA-HD-attiny45.elf
664 0 39 703 2bf .\bin\battcheck-dual-switch-turboclick-TA-HD-attiny85.elf
508 0 38 546 222 .\bin\battcheck-TAv1-OTC-HD-attiny25.elf
512 0 38 550 226 .\bin\battcheck-TAv1-OTC-HD-attiny45.elf
512 0 38 550 226 .\bin\battcheck-TAv1-OTC-HD-attiny85.elf
584 0 39 623 26f .\bin\battcheck-TAv1-OTSM-HD-attiny25.elf
592 0 39 631 277 .\bin\battcheck-TAv1-OTSM-HD-attiny45.elf
592 0 39 631 277 .\bin\battcheck-TAv1-OTSM-HD-attiny85.elf
572 0 38 610 262 .\bin\battcheck-TAv1-OTSM-LDO-HD-attiny25.elf
580 0 38 618 26a .\bin\battcheck-TAv1-OTSM-LDO-HD-attiny45.elf
580 0 38 618 26a .\bin\battcheck-TAv1-OTSM-LDO-HD-attiny85.elf
568 0 34 602 25a .\bin\battcheck-trippledown-HD-attiny25.elf
572 0 34 606 25e .\bin\battcheck-trippledown-HD-attiny45.elf
572 0 34 606 25e .\bin\battcheck-trippledown-HD-attiny85.elf
1924 0 42 1966 7ae .\bin\bistro-4channel-dual-switch-HD-attiny25.elf
1932 0 42 1974 7b6 .\bin\bistro-4channel-dual-switch-HD-attiny45.elf
1932 0 42 1974 7b6 .\bin\bistro-4channel-dual-switch-HD-attiny85.elf
990 0 28 1018 3fa .\bin\bistro-biscotti-HD-attiny13.elf
1102 0 32 1134 46e .\bin\bistro-biscotti-HD-attiny25.elf
1106 0 32 1138 472 .\bin\bistro-biscotti-HD-attiny45.elf
1106 0 32 1138 472 .\bin\bistro-biscotti-HD-attiny85.elf
1676 0 36 1712 6b0 .\bin\bistro-classic-HD-attiny25.elf
1680 0 36 1716 6b4 .\bin\bistro-classic-HD-attiny45.elf
1680 0 36 1716 6b4 .\bin\bistro-classic-HD-attiny85.elf
1742 0 40 1782 6f6 .\bin\bistro-custom-HD-attiny25.elf
1746 0 40 1786 6fa .\bin\bistro-custom-HD-attiny45.elf
1746 0 40 1786 6fa .\bin\bistro-custom-HD-attiny85.elf
1718 0 40 1758 6de .\bin\bistro-default-HD-attiny25.elf
1722 0 40 1762 6e2 .\bin\bistro-default-HD-attiny45.elf
1722 0 40 1762 6e2 .\bin\bistro-default-HD-attiny85.elf
1904 0 40 1944 798 .\bin\bistro-dual-switch-dumbclick-TA-HD-attiny25.elf
1912 0 40 1952 7a0 .\bin\bistro-dual-switch-dumbclick-TA-HD-attiny45.elf
1912 0 40 1952 7a0 .\bin\bistro-dual-switch-dumbclick-TA-HD-attiny85.elf
1684 0 35 1719 6b7 .\bin\bistro-dual-switch-noinit-TA-HD-attiny25.elf
1692 0 35 1727 6bf .\bin\bistro-dual-switch-noinit-TA-HD-attiny45.elf
1692 0 35 1727 6bf .\bin\bistro-dual-switch-noinit-TA-HD-attiny85.elf
1876 0 40 1916 77c .\bin\bistro-dual-switch-turboclick-TA-HD-attiny25.elf
1884 0 40 1924 784 .\bin\bistro-dual-switch-turboclick-TA-HD-attiny45.elf
1884 0 40 1924 784 .\bin\bistro-dual-switch-turboclick-TA-HD-attiny85.elf
1690 0 39 1729 6c1 .\bin\bistro-TAv1-OTC-HD-attiny25.elf
1694 0 39 1733 6c5 .\bin\bistro-TAv1-OTC-HD-attiny45.elf
1694 0 39 1733 6c5 .\bin\bistro-TAv1-OTC-HD-attiny85.elf
1780 0 40 1820 71c .\bin\bistro-TAv1-OTSM-HD-attiny25.elf
1788 0 40 1828 724 .\bin\bistro-TAv1-OTSM-HD-attiny45.elf
1788 0 40 1828 724 .\bin\bistro-TAv1-OTSM-HD-attiny85.elf
1760 0 39 1799 707 .\bin\bistro-TAv1-OTSM-LDO-HD-attiny25.elf
1768 0 39 1807 70f .\bin\bistro-TAv1-OTSM-LDO-HD-attiny45.elf
1768 0 39 1807 70f .\bin\bistro-TAv1-OTSM-LDO-HD-attiny85.elf
1666 0 35 1701 6a5 .\bin\bistro-trippledown-HD-attiny25.elf
1670 0 35 1705 6a9 .\bin\bistro-trippledown-HD-attiny45.elf
1670 0 35 1705 6a9 .\bin\bistro-trippledown-HD-attiny85.elf
Start with fr-tk-attiny.h. This defines the driver board configuration or
"layout". There are many predefined layouts and you can make your own or just
use the "custom-layout" for your needs. For now you only need to identify one
you like and modify it, or create a new one. We'll select the one to actually
use later. Configuration is significantly simplified from the past but the
basic idea is the same.
The first thing to configure is the PWM channels to enable. Ideally three
things should match, the channels defined here, the channels tied to a FET,
7135, etc on your actual driver, and the channels defined by the "ramps" in the
modegroup.h. You can disable channels in modegroups.h by commenting out the
ramp, and you CAN use a layout that enables more channels than your board has.
(There's a chance this will cause issues with OTSM builds. OTSM sleep is very
sensitive to how pin states are defined, but you can try). This makes
trippledown-layout a good all-around choice for most purposes.
What you cannot do is use a layout that is missing channels that are wired on
your board. Channels not included in the layout get set to input high (for good
but boring reasons). If your FET pin gets set high, you'll get turbo all the
Other pins: You can define a CAP_PIN for OTC, an ESWITCH_PIN and VOLTAGE_PIN.
It's safe to set these even if they won't be used. They are only activated if
the features are turned on in the main configuration file. This means they can
even be defined on the same pin and in fact the ESWITH_PIN and VOLTAGE pin can
be used on the same pin!
VOTAGE_PIN: If you want to measure voltage from Vcc (see option in Customizing
Configuration) the definition of the VOLTAGE_PIN will not matter for that. For
OTSM you will still want a voltage sense pin to detect power on. For eswitch
only without OTSM, especially if your voltage pin is disconnected, you should
comment it out. The voltage PIN is left floating by the firmware if defined.
It is no longer required to match ADMUX values and such to the pins. This is
done automatically at the bottom of the file.
V.2 Customizing the Configuration:
Configurations exist in the configs directory. You can start with one similar
to what you need, rename it, and edit it.
There's already a config-custom.h and it's built by the Makefile already so
it's easiest to use that. But start by copying one you like to overwrite
config-custom.h. The config-default.h is meant to always have all the latest
config options (either commented or uncommented). Other configs were made for a
purpose and may not be updated with all newest options available.
If you want to use a different name, the naming should remain like
config_yourconfigname.h and you can add it to the compile list configuring
bistro.c directly, or if using the Makefile, add yourconfigname to one of the
FIRMWARES variables (the lowest chip it should work with, ex: FIRMWARES25).
Alternatively just add: ONE_BUILD := bistro-yourconfigname.hex to build only
that firmware and its battcheck build.
A note about config options: Many options are useful for an all purpose build
to give users options, but for custom builds, might not make any sense and
waste space. For example if you always like your modes high to low, just
reprogram your mode orders and leave off the USE_REVERSE_MODES feature, making
room for something else. Moon, and muggle are likely similar. Why have a moon
toggle if you always like moon? Just define the first ramp position
as a moon level and use it in the modegroups.
Configuration file options documentation will likely become obsolete and I
only document selected options here. See comments in the file for the rest.
Layout: Here is where you choose your layout. Uncomment an existing one or add
your own new one.
Modegroups: Select a modegroup header file. These define
the mode configurations and the files are found in the modegroups subdirectory.
Again obviously you can start with one as a template.
VOLTAGE_CAL: produces a voltage calibration-only build. Voltage read options
apply. Offtime Configs)
SAFE_PRESSES: Only useful withough OTC or OTSM. ToyKeeper famously made the
noinit method to detect click length and count clicks with no capacitor by
keeping the click count in memory and detecting memory decay. However it's
very unreliable. Using multiple bytes for the noinit variable adds redundancy
that reduces the odds of problems from maybe 1 in 20 to 1 in thousands. If you
have room and aren't using OTC or OTSM, enable this and set N_SAFE_PRESSES
according to comments.
OFFTIM3: Enables middle length clicks (not just short long) used to go
backwards and enter hidden modes. Requires OTC or OTSM, but not both. Enable
this and one of those.
OTC: Off time capacitor. Measure charge on a capacitor too see how long the
light has been off. It's great, but very sensitive to hardware design and
OTSM: Uses a large CAP to run the MCU for a couple of seconds, counting time.
Timing is more stable, but it presently doesn't seem to work well (or at all?)
OTSM_POWERSAVE: Replaces delay functions with idle sleeps, actually can be used
without OTSM to lower power use in moon mode (probably from about 4mA to about
2mA which is very significant in moon mode). Orignal purpose was to aid in
powersaving during OTSM shutdown.
SLEEP_TIME_EXPONENT: only used for OTSM and ESWITCH, set's click timing
resolution (at expense OTSM shutdown time) nomally don't edit this.
wake_time_short/med, sets timing thresholds for OTSM or ESWITCH presses. Set
in actual floating point seconds!
USE_ESWITCH:Self explanatory, the eswitch. Make sure it's defined on your
***Dual switch options***
The options under this are all for dual switch lights. None of them are tested.
USE_ESWITCH_LOCKOUT_TOGGLE: Enables menu option 9 that disables the Eswitch.
Not really sure how useful this is. Probably need a more general lockout
DUAL_SWITCH_NOINIT: The clicking switch (power switch) uses the noinit click
time. OTC and off-time caps should not be used. No medium clicks will be
recognized on the power switch.
DUMB_CLICK: The power switch does not change the mode. Just turns the light
off and on.
TURBO_CLICK: The power switch always brings the light on to the first hidden
mode (the last one defined in hiddenmodes, since we enter hiddenmodes
backwards). This is usually turbo.
***End of Dual-switch options***
READ_VOLTAGE_FROM_VCC: Reads the voltage from the Vcc pin instead of voltage
divider pin. This works well for 1S drivers with not voltage regulator (LDO)
on the mcu, and doesn't require adjustment for resistor selection.
REFERENCE_VOTLAGE_READS_TO_VCC: Still reads from the voltage divider but uses
Vcc as the reference (and max) voltage instead of the 1.1 internal voltage.
This is required for 2S or greater OTSM. See details below.
USE_TURBO_TIMEOUT: This re-implements BLFA6 style turbo timeout for attiny13
builds, especially HD-biscotti (thanks to much space savings). It needed some
changes to work in bistro, but here it is. (untested actually). If you
uncomment the whole preprocessor conditional you will get TURBO_TIMEOUT on
attiny13 builds and thermal moniotoring on attiny25/45/85 builds.
TURBO_STEPDOWN:Possibly hidden control for USE_TURBO_TIMEOUT and TEMP_STEP_DOWN
You can define this to a ramp level to step down to in your modegroups.h, but
default is RAMP_SIZE/2.
TEMPERATURE_MON: Allows temperature regulation (various options)
By default this uses classic bsitro temperature regulation, which attempts to
regulate the output at the max defined temperature. See note and end of section
TEMP_STEP_DOWN: Requires TEMPERATURE_MON is defined, uses a hybrid of TURBO
timeout and bistro temp mon. After hitting a max temp, it just jumps back to
TURBO_STEPDOWN level, and a short click bumps it back up. Note that the first
line of defense is your thumb. If the light is too hot, you turn it off. The
second, not first, line of protection is this. So if this cuts in too soon,
raise the temp threshold with the calibration mode. Then you shouldn't really
need to use the tap-up feature until after the light has cooled some. However,
if you tap up while it's still hot you'll get a default of 10s minimum in turbo
before the temp will be checked again. You can adjust this with the
USE_STAR3 uses BLFA6 star3 sensing code, you probably don't need it.
USE_MUGGLE/REVERSE/MOON: Can now disable the lights menu options for these.
USE_FIRSTBOOT enables the reset menu option.
INIT_BLAH defines the initial and reset value of BLAH (modegroup, etc..)
Uncomment the strobes you need. You don't need to worry about the numbers, so
long as they are all different and all below MINIMUM_OVERRIDE_MODE as
instructed in the comments. Generally you just need to uncomment or comment
them. These should match the modes defined in the modegroups and the
hiddenmodes group in the selected modegroup.h file.
V.3 Customizing Modegroups
Edit your chosen modegroup file (see Customizing the Configuration), found in
the modegroups subdirectory. Ramps define the setting for each PWM at ech
available level. Makes ure RAMP_SIZE matches the total number of ramp modes.
Define a RAMP for every PWM channel (see Customizing the Layout). Define your
hidden modes, and modegroups, following available examples and comments.
V.4 Selecting your Configuration
You can either add your main configuration file to the Makefile if building
that way (or if using config-custom, it's already there) or you can edit
bistro-HD.c and define the ATTINY version and config file near the top. Then
you should compile using the normal Atmel Studio compilation. See compiling
VI.1 Voltage Calibration
HD includes new voltage calibration methods. See fr-calibration.h for details.
The calibrations no longer require taking measurements at a long list of
measurements. For divider reads one measurement should be enough (I hope) and
since it can be changed with one variable, guess and check (or educated
adjustement) may also get close fairly easily. You must check your firmwares
config file to see what type of voltage read the firmware is using.
VI.2 CAP timing Adjustments
OTC timing is done the same as in bistro. Modify thresholds in calibration.h.
See bistro documentation for more details.
To flash the software you will need fuse settings. This is at your risk. The
wrong fuses can make your chip useless and unflashable.
Fuses (for attin25/45/85):
Some options for the high fuse are:
DD => BOD disabled early revision chips may not work with BOD and
OTSM. Disabling BOD might get it working, but risks corruption.
DE => BOD set to 1.8V Non V-version chips are still not specced
for this and may corrupt. late model V chips with this setting is
DF => BOD set to 2.7V Safe on all chips, but may not work well
with OTSM, without huge caps. You can try.
And for the low fuse:
C2, 0ms startup time. Probably won't work with BODS capable late
model chips, but should improve OTSM a little if not using one
D2, 4ms Testing finds this seems to work well on attiny25 BODS
capable chip, datasheet maybe implies 64 is safer (not clear and
hardware dependent), but 64 seems to eat power.
E2 64ms startup. Will consume more power during off clicks and
will probably break click timing.
Ext fuse should be: 0xff
Tested with high:DE low:D2, Ext 0xff on non-V attiny25, but it's
probably not spec compliant with that chip.
Used the same on V version 25 (where it is spec compliant).
To be written, try documentation for biscotti for now.
For more details on these settings
VIII.1a Parts and build for tested TAv1 board for 1S
OTSM is working better and better, but getting it there required a combination
of software work and the best parts. It may be possible now to use cheaper or
lesser parts since OTSM performs a little better than needed with these, but
these are tested and work.
It's required to have BODS support for the mcu (see theory below). From page 36
of the manual this requires:
• ATtiny25, revision E, and newer
• ATtiny45, revision D, and newer
• ATtiny85, revision C, and newer
The spec for OTSM also requires V version (10Mhz, low voltage version) chips.
You might get by without it, but it won't work as well and may cause
Unfortunately most ATtiny 85s reported off the shelf have been revion B, for
the past many years even. They don't work. So far Attiny25, attiny25V,
attiny45 and attiny45 v's where reports exist on this, have been of recent
enough version. Of course attiny25V is available in the smaller footprint and
fits 17mm TAv1 boards. At the time of this writing all HD features including
OTSM can fit on an attiny25.
Diode part number: RB751V40T1G
This is the MCU protection diode. It isolates voltage from the C2 cap that
powers the MCU while input power is down. It was chosen for its low leakage
even at high temperatures. Leakage below 1 or 2 uA is probably fine.
C2 cap (powers MCU during off time, quality counts here)
Cap part number: 298D476X0010P2T
This cap was chosen to get the most capacitance in an 0805 possible and because
Tantalum does not suffer from DC bias de-rating or temperature fluctuation.
Capacitance this high (47uF) in an 0805 are all low voltage. For Ceramic if
the DC offset is more than about 1/3 of the rated voltage the capacitance
starts to drop, some times a bunch. This cap does have a large tolerance
Tested with R1 of 1K and R2 of 3.3K R1 should be no more than about 1/3 of R2,
but this ratio should be ideal for OTSM performance in a 1S light (but only in
a 1S light). Lower values can improve OTSM performance, at the expense of
higher mood mode drain. If you use lower quality caps or diode, you can try to
add a bleeder of about 500ohm to gain a little advantage on off time, not much.
VIII.1b Parts and build for TAv1 board for LDO (2S, 3S etc)
See section VIII.1a for mcu, cap and diode selection.
Place the diode on the R7 resistor pad with the anode (+ side) pointing away
from C2. No OTC cap is needed. Use the following divider resistors:
2S: 1780 2210
3S: 2250 1500
4S: 2870 1100
No bleeder. That's it.
For 2S or more build, the attiny must be fed power by some form of voltage
regulation such an LDO. This means that Vcc (input voltage) cannot be used to
measure the battery voltage. The divider must be used. Furthermore because
the divider pin must stay logic high to indicate power on, the 1.1V reference
cannot be used. The REFERENCE_DIVIDER_READS_TO_VCC option must be used (It's
compiled into the LDO firmware) This reads pin voltage as a fraction of Vcc
with Vcc being the max, allowing the highest possible divider voltages.
There's some difficulty here because a low battery, 2.5V/cell is 0.6 the
voltage of a full battery: 4.2V/cell. 0.6Vcc is also the maximum trigger level
for a pin change interrupt, which indicates a click and puts the light into
sleep. In reality the trigger level should be below this, but by spec it can be
this high. So we need the divider voltage to really stay as high as possible.
Furhtermore Vcc is reduced from the LDO voltage by the diode voltage. This
fluctuates slightly with temperature and current, so we need to estimate this
max voltage as well as possible. From the diode spec sheet a maximum diode
voltage of about 0.4V at 2 to 4mA is seen, but more typical is 0.35V and this
should be correct within 0.1V even when hot.
Using a TA generation 1 (v1) LDO board, a diode must be added, the same one as
for the 1S configuration above. The diode can be added in place of the R7
0-ohm resistor. The same caps are used.
The only other difference is the correct resistor values should be chosen. We
want a total resistance R2+R1= about 4kOhms. We need the voltage on pin 7 to be
equal to the LDO voltage minus the diode voltage, ie Vcc, when the batteries
are at max voltage, Vbm.
So the divider should be R2/(R1+R2) = Vcc/Vbm.
Following the TA build specs and the diode used here, Vcc is 5.0-0.35 = 4.65V
This gives R2 = Vcc/Vbm *4kOhm.
And R1 = 4kOhm-R2
here is the calculated table for various voltage levels:
R1 R2 Vcc/Vbm ideal:
2S: 1786 2214 0.5536
3S: 2524 1476 0.3690
4s: 2892 1107 0.2768
Of course these resistors don't exist, so we need to look for something close,
with the ratio being the most important thing.
R1 R2 Divider Error %
2S: 1780 2210 0.06
3S: 2250 1500 0.36
4S: 2870 1100 0.1
These should be in 1% tolerance or better. Any inaccuracy here pushes the
measureable voltage range up against the spec limits.
VIII.2 OTSM Theory and technicalities
See "Features" for basic explanation. Mike C and Flashy Mike tested early OTSM
concepts. OTSM must power the mcu off a CAP and detect power-off so that it
can enter a low power sleep state until power returns. The first important step
is fast power-off detection. DEL recommends a 1uF C1 for stability. C1 must
discharge to some threshold voltage to trigger a poweroff detection. C2 must
remain high. This means a diode or LDO/diode combination must exist between C2
and C1 and it should have low leakage current even when hot (<1 or2 uA
preferably). This limits diode selection. If C1 takes too long to drain,
Charge on C2 will also be consumed by the mcu power. This means the reistance
from C1 to ground should not be too big. Starting with a divider voltage close
to the maxximum threshold helped minimize the C1 fall time. Bistro-HD uses
pin-change detection. The maximum threshold for logic level detection is
0.6*Vcc so the sense voltage can be reduced safely to 0.75*Vcc or a little
more, so a R2:R1 of about 3:1, not much less. The measured mcu current for an
attiny25 is about 4mA in full power, but by enabling OTC_POWERSAVE, is reduced
to about 2.1mA. This measurebly improves OTSM time.
The charge used during off-detection depends strongly on the resistors selected
and is easy to calculate. For the first bistro-HD OTSM light, 4.3k total
resistance 1uF C1 gave an RC time of 4.3ms. A more precise worst-case time to
drain to minum pin change threshold (0.3Vcc) ends up at about 4.0ms. With 2.1mA
of idle current draw (in OTSM_POWERSAVE mode), that's 8.5uAs of drain.
Assuming a 1V drop before the mcu turns off, the 47uF cap can provide 47uAs of
charge before shuttoff, so that's already about 18% of the available charge, or
about 10uF worth, or about 1s worth of off-time. If lower quality caps are
used this starts to matter. If you've only got 25uF of real capacitance, that
first 10 is important. For lower quality caps, using a bleeder resistor or a
divider in the hundreds of ohms range is a good idea, at the expense of
The next issue is the sleep power. Sleep power can be as low as about 4uA
(measured) but only if BOD (Brown out detection) is disabled. Unfortunately
brown out detection is maybe pretty important for preventing corruption when
operating at low voltages (testing by Mike C). Furthermore a low voltage BOD
with a compatible chip, ie the V version 10Mhz chip, is important. Fortunately
BOD can be disabled during sleep and enabled during running to protect
corruption. This feature is called BODS, but it's only supported on late
revision chips, see datasheet page 36 (and parts section above) for details.
All known attempts to find compatible chips in attiny85 have failed. However
recent purchases of attiny25V and attiny45 V have worked. Without BODS about
200uF of capacitance is required. With BODS 47uF is enough.
Sleep power is not the whole picture. When the mcu is asleep there is no clock
running that can simply tell the time when it wakes. Instead there is a
watchdog timer that can wake it up periodically. By counting wakes and checking
power state we know the time. But these wakes consume power. The more
frequent the wakes, the more the average current rises above 4uA. For 0.25s
wakes, the average current is about 8uA (with a good diode). In comparisson,
without BODS it's about 25 to 30uA (all give or take depending on voltage).
0.25s is very unresponsive. To solve this the mcu wakes on the timer or a pin
change interrupt. In this way turn on is immediate, but timing resolution is
limited to 0.25s, which is good enough.
Using the poweroff consumption and the average sleep current it's relatively
simple to calculate the total sleep time possible and with FET only this agrees
reasonably with observations. Some difficulties were presented with the 7135s
resulting in very low sleep times. This was never fully understood, but what
is clear is that sleep time depends strongly on pin states and currents sourced
from them. Aside from current through pins the manual states that pins left
floating at intermediate values result in high current drain. All pins except
the PWM pins and OTC (if used, possible in dual switch light) pin are set input
high, a high impedance state documented to be pretty good for this. The
voltage pin itself must be input low, low really means floating as the attiny
has no pull-down resistors, only pull-up. To get the 7135s to work though,
after detecting the power-drop, they had to be set to input low. Any other
configuration resulted in very low off-times.
It's worth pointing out that there is another way to detect powerdown. The ADC
can be used to detect pin voltage. This has the advantage of allowing more
flexibility in voltage levels used for power-off detection and probably more
precise control (logic level tolerance is large). The biggest downside is just
software complication. The adc needs to run asyncronously, and combining
temperature monitoring, this is change from the usual bistro adc methodws.
There was discussion about power use of the ADC, but this is not a serious
issue. The adc can run fine with very low prescale factors, probably 4 or 8
for the precision we need. At prescale 8 that's about 1us per ADC cycle and 13
cyles per readout, so about 13us per adc read, probably times two for the
software commands themselves, so let's say 30us. The ADC consumes about 150uA
of current but that's irrelevant for the short time it needs run. What matters
is it keeps the mcu awake and the mcu is consuming about 4mA of current for
30us so about 0.12uAs of charge. That's compared to about 0.25s * 10uA=2.5uAs
for a total sleep cycle. So the ADC adds about 5%. Why so low if the wake time
is doubling the current draw and we're at least doubling the wake time?
Probably because the time actually waking up is very significant. The chip
takes 4ms to wake up and is presumably in some intermediate power state then.
Compared to that the 30us extra probably isn't that much.
Some of the details are missing there, but the average current measurements are
the real evidence, and I have run tests with ADC reads during wakes on
bisro-HD with no significant impact on off-time. The ability to detect pin
fall faster could actually save power.
Voltage pin, resistor selection, and OTSM:
OTSM detects power-off on the voltage pin. So how can voltage be detected for
battcheck and LVP? The logic level threshold has a tolerance range between
0.3*Vcc and 0.6*Vcc. For a 1S light with no regulator or zener, this just
means we need the R2:R3 3:1 or greater to have a little safety margin. Making
this work well with voltage divider reading is tricker. This is possible with
included options but for this setup it's simpler to just read voltage off the
Vcc anyway, also an included option.
For a multi-cell (ex: 2S) light, Vcc will be powered by a regulator and cannot
be used to read battery voltage. If a 3.0V LDO is used, then the highest
shutdown trigger level on the voltage pin is 1.8V or 0.6*3.0. If we reference
voltage reads to Vcc the max we can read is is 3.0V. Conveniently 2.5V is
0.6* 4.2V so a typical battery operating range just barely fits in the
available headroom. Resistors must be selected in 1% tolerance so that max
voltage corresponds exactly to 3.0V or maybe 1 or 2 % less. The voltage should
be read from the divider and the option to reference divider-reads to Vcc
should be set, since these voltages are necessarily above the 1.1V internal
IX E-switch & Dual Switch
An eswitch works very similarly to OTSM, checking for voltage rises and falls
and timing on a pin. So it was natural to add e-switch support. The eswith
presently works exactly like the OTSM. Short clicks will advance the mode,
medium go backwards, and long turn the light off. Presently any click turns
the light back on. This might not neeed improvement. The only lockout is a
menu item that locks out the eswitch entirely (possibly useful if you have two
switches). The eswitch would normally operate on the OTC pin just as before.
In this case it's possible to have a clicky switch detected with OTSM or OTC on
the voltage pin. For OTC both a switch and cap would be wired to the OTC pin,
with a small series resitor in the switch line.
The eswitch and OTSM should also be able to work on the same pin, the voltage
pin. Flexibility to develop differentiated functionality may be reduced but
would need consideration. Presently, even then, is possible to tell difference
in which switch was pressed in some circumstances. For example for long
presses the clicky switch will create a full reset and the eswitch won't. This
is detectable by initialization values. Actually unless an OTSM cap is
included any click of the power switch will create a detectable reset.
An entersting option at the moment, is to configure the firmware for OTSM and
eswitch, but use a non-OTSM build. In this case all click presses will
result in a long click, allowing the click switch to always start in first or
last-used mode. This is interesting mostly because it takes no further
A significant problem with running OTSM on an e-switch light is that an
e-switch light would normally have a very high resistance from C1 to ground to
avoid parasitic drain. This conflicts with the OTSM need to have a fast
voltage drop on C1 after power off. The obvious but not simple solution is to
use a transistor to drain C1. The other option is to simply live with it. You
have a power-off switch, so use it. Other options are just to not use that
combination. Use OTC or noinit for the clicky. Noinit is probably not yet
supported in this combination.
It's also possible to run the e-switch on the reset pin. The reset voltage
threshold is very low (maybe 0.1V I think). So the switch would need a
resistor network such as to pull the voltage down only to about 0.5V. A
capacitor may be required in that case to prevent noise from triggering the
X Under the Hood
X.1 Space savings
Looping configs: Bistro uses several EEPROM saved variables, most of them
representing selections in the main menu, or "toggles" that get turned on and
off. Each variable was saved, loaded, and toggled with a separate command in
each case. By placing the variables in an array and using loop operations many
instructions are saved in each step. A single function is used for save and
restore, reducing function overhead. Since conditionals are smaller than loops,
the conditional paths for saver or restore are nested in the loop instead of
having a loop in each path. Some accomodations were required for things like
override-mode setting and muggle mode menu lockouts, but it works and the
overhead is such that even in small builds like biscotti it at least breaks
even, maybe better. In big builds this probably saves close to 100 bytes just
for the menu. The save, restore saves in addition.
Variable length mode groups: For complex modegroup definitions like the TA
tripple bistro, many short mode groups waste many bytes with 0's at the end.
By adding zero termination detection to countmodes, many bytes were saved with
limited overhead. Even in biscotti, this at least breaks even.
Other ount modes savings: A bunch of space was saved by optimizing the count
modes operations. Especially finding the start of the modegroup, the end and
copying the modegroup are now done in one read loop for non-reverse modes. For
reverse modes it's done in two.
In the new OTSM and eswitch code, much space was conserved (not gained) by
using naked or OS_task interrupt handlers. Details in the comments.
An always-on e-switch light could start up in some mode and sit in loop doing
basically nothing while interrupts control ADC reads and switch detection. If
an interrupt condition is met the main loop would catch a flag and do
something. Bistro works very differently. Every time the switch is clicked
the whole program restarts. Information must be saved periodically to record
what was happening when the power went off. For example if we were in a
selection pulse, and power went off, the user selected an option. Also the
click length is determined on startup by various means to determine what to do.
ADC's are read in the main process loop, not interrupts.
For OTSM we need to detect a power off condition and go to sleep. After
detecting power restart, we need to determine the click length and do
something. Since normally this is done in bistro at restart, we need to set
some variable, specifically sleep time, and restart. Falling back through the
main code loop would be very tricky. Furthermore it is very useful to be able
to cleanly tell the difference between a restart and a cold start. So we want
the variable initialized on a cold start, but remembered on restart.
Basically we need to treat main as a subroutine that we can call and we need
other things done before main. That sounds simple, just rename main right? No.
This restart processes is an unlimited loop on a device with a very limited
memory. Every function adds a return pointer tot the stack and the stack
retains the memory of the function before it. This will produce a stack
Instead what is done is an init section of the code is used. These sections
are not subroutines. They have no return. They are one-way. They simply run,
and then code execution carries on to main. This is useful only because it
prevents moving main to a normal subroutine and thus saves a few bytes
associated with that. For the overflow problem what we need is to simply reset
the stack pointer, and then jump to main. And that's what's done at the end of
PCINT0_vect, the pin change interrupt handler.
The attiny only has one interrupt handler for rising and falling pins. To keep
the size small everything is handled in the one function, very carefully. Since
we will restart the program at the end of the handler, we don't need the usual
interrupt overhead of saving and restoring all registers. This is a big
overhead especially for a complex interrupt (this one is) because there is no
way to set aside specific registers that the calling program doesn't touch,
since the interrupt can happen anywhere. Every register used must be saved
and resotred. But we're not ever going to return. We're going to blow up the
world and start over anyway. For this reason the usual overhead is avoided by
declaring the function with the OS_task attribute. However since the same
interrupt is used for the rising pin, we interrupt the interrupt on pin rise,
and THEN we do return, to the first instance of the interrupt. That seems to
pose a problem. By carefully controlling what registers are touched in the
rentry, we sneak in and out without damage. The whole process saves about 30
The interrupt triggers on the voltage pin fall. A watchdog sleep is enabled.
We wake every 1/4 s (configurable) to count wake times. We also wake on a pin
change. Every time we check if the pin is high. If it is, break out of the
loop, reset the stack, and jump to main.
Eswitch uses the same loop but adds a more complex sequence, with status bits,
cycling back to sleep even after a pin rise in some conditions (long press to
power off) and requiring another pair of pin changes to come back on.