Texas Avenger "TA" Driver series - Triple channel + Bistro or Narsil + Clicky or E-switch - The Ultimate open source driver!

I know I am a bit late for a question about different MCUs and it may be stupid but - has anybody ever considered using an ESP8266 on a driver?

Its 32-pin QFN package has about the same size as a small AtTiny SOIC package but it will need external SPI Flash RAM. 32-bit/80 MHz/16 MB would be total overkill but it would solve all memory and GPIO limitations and still have an ultra low sleep mode. Programming can be done with the Arduino IDE. And last but not least, it was designed as a WiFi chip.

Interesting chip, whats the price on those + the extras needed to make it run?

Also what would the total footprint be with all the extra components?

The real advantage of the 1617 and 841 is the 3x3 footprint that is super important for the things we are doing now days.

The wifi would be very cool indeed but only if it doesn’t come at too high of a cost in money or space.

I wounder if bluetooth would be a cheaper / smaller option? I have no clue about these type of chips.

The ESP8266 usually comes with a metal EMC cover - search for a photo of an ESP201 board for a look at the two main components. The chip is 5x5 mm, about $1.2. Memory is a Winbond SOP8, $0.5 for 4 MB.

A bit more footprint than today. If the two chips do not fit on a driver board maybe one of several connection boards can be wired to the driver. They are all less than $2.

Its new brother ESP32 has Bluetooth but it is 6x6 mm and still costs too much.

The big thing about the ESP8266 is that it is very powerful yet very cheap and has sufficient documentation by now.

The chip itself is reasonable but that memory would be impossible to fit with the MCU, FET and other components on a normal flashlight driver sadly. I am surprised that the memory is so large. Honestly I don’t see us ever needing more then 256kb or 512kb at the extreme end for a flashlight. Even that would give massive amounts of extra room. Are there more compact options for smaller amounts of memory?

It seems there are smaller USON8 (2x3 mm) or WLCSP size RAM chips available.
ESP-09 has a smaller one.

The problem with the ready-made boards is that you may not have access to all GIOs. But a 10x10 mm ESP-09 for example (6 GPIOs plus programming pins) would be much easier to attach to a larger driver PCB if you want all that tiny WIFI components.

There are plenty of MCUs that would be very good choices for flashlights, but you know, many of us really couldn’t be bothered to re-design all our drivers, read the entire datasheet over again, get a whole new development platform and figuring out all limitations and how it works from the beginning.

Many of us, myself included, started with Star firmware and changing some values. We did not have to read an entire datasheet to figure out which registers to use to read voltages and stuff, all we had to do was look at the registers that Star used and look ’em up in the datasheet. Once we got to know more about them registers and stuff, shifting on to the next MCU (25/45/85) was pretty easy. Now I’ve moved on to the 841 and shifting to that one was also pretty easy, and others that have their sights on the 1617 won’t have a hard time either… Also, AVR MCUs are so widely used, just do a search on what you need to know and you will find it, or find help pretty quickly.

So it better be one heck of a MCU if someone is going to go give up all the above and start from scratch… Sure, that ESP8266 looks cool, but 5x5mm with 7 external components? What advantage are we going to get with it? WiFi connection to our lights? I looked at the overview of those smaller ones, and there are no selling points on analog to digital converters or internal temperature sensors. What advantage are we going to have with them? Sure, they might have real advantages, but just by looking at the specs they are not at all obvious (at least to me), so someone has to give them to me on a silver plate before I’d even consider going through the hassle of switching MCU brand. I sure ain’t gonna do it to save 1x1mm on my boards.

I understand that nobody wants to throw away his toolchain and start from scratch just because a new chip comes along. But I was reading about limited memory and limited pins a lot and about footprint changes for larger AtTinys to solve that recently.
I do not know if it would be worth it. I am just curious if there are technical reasons why nobody is using it today.

I came up with this idea because the ESP8266 would be a totally different level. It is not just another barebone MCU, it is much more powerful. For example it can do SPI (I²C, CANBUS, you name it) to attach dozends of sensors to a single I/O pin. Temperature, brightness, color, accelleration, motion, proximity, touch. Or displays: OLED, e-Ink…

That thing can run a BASIC interpreter in a browser window or Javascript to be a webserver. You could program the modes of your flashlight from your smartphone without an app or switch it on from continents away via internet.

It would be like playing La Marseillaise on a Formula 1 motor. Because you can.
Maybe just not on small driver boards.

Afaik most of the seven external components are only needed for the WiFi antenna.

Well, the footprints are now smaller, can get 3x3mm, with the 841 and 1617 there are enough pins. I don’t know why you would ask if there are technical reasons as to why nobody is using it, most have either not heard of it or aren’t interested in touch screens on their flashlights yet. I don’t see why I would want a dozen of sensors either, right now most aren’t connecting any even if there are spare pins. I don’t find the idea of a flashlight with a bunch of sensors hanging out of it that appealing.

I also don’ t get why I would want to program my flashlight from my phone. My flashlight has a button, and I can press sequences to program basically everything, seeing brightness adjustment on the fly. Having to have an additional unit to program it seems silly to me. Others might be more interested though, using the phone is already been discussed by using the LED as a light sensor.

All these things like SPI, canbis, basic, web servers, motion thingies and so on seems more suited to a home management system than a flashlight.

I’d like to reverse the question… Why aren’t you using it?

Have you looked at any version since 1.0? And don't look at the c file beyond the only 3 configurations in it. The rest of the defines there, as clearly marked, are not for configuration.

Anyway I can certainly help you with where to start though. You start with the TAv1-OTSM hex file and just flash it, after of course building a board with the right diode cap and divider. That's it. Then if something isn't to liking you look at the options in the config_TAv1-OTSM.h file and start seeing if there's anything you might want to change and post here to ask if needed. For that build, there's really nothing you'd change that you don't already know about, ie modegroup defines, that haven't really changed. The only other one is timing threshold defines, that are only simpler than the ones you've dealt with in the past but basically identical except they're in seconds now, not ADC units. The configs that matter are separated out much more cleanly from the ones that don't compared to the past, and most of them are pretty independent and many invalid combinations throw warnings.

There's a define to turn on Vcc reads of course (which you also won't need to touch) and that one came at your request. There's probably only about 10 new defines really, two of those being the OTSM and Vcc read. Many of the rest being e-switch related and clearly not relavent, and a couple for the new thermal control options or debugging, that also I think are pretty clearly for that. As far as compiling it, in worst case, you just double-click the including batch file and it compiles. I couldn't figure out a way to make it fewer clicks ;)

Again, you chearleeded to get OTSM and Vcc in bistro, kind of surprised you don't even try it, but ok.

@Mike C I think reducing timing mostly helped me because of the way BODS works. It requires a 16ms startup fuse, and I don't know how much power it's using durig that startup. Fortunately, it seems it's nowhere near full on power or it wouldn't come close to working at all, but I suspect it's quite a bit more than full off power, so you don't want those startup periods too often. This is one angle where a newer BODS (fuse selected or whatever) might be improved. Also the ADC, it mostly matters only because of how long it keeps the mcu awake. The mcu full power is 2 to 4mA. The ADC power is 150uA, but if your ADC acquisition time is slow, it keeps that 2 to 4mA running longer. I think you're already setting prescale at some small value though. Then it's not a big deal. The pin change may be doing worse just because of when it exactly it triggers off. That's part of why I like a divider though. I bring the on voltage down so it's not high above threshold. This improves off-detection speed.

Here's the config for the TA-OTSM version. Now to someone who knows nothing about this stuff this might look pretty daunting, but to you TA, there's only a small hand full of new defines here. To that other person, they should start with the default and then ask themselves what they're trying to do.


Now color coded, red for new defines, blue for comments added only in this post.

#ifndef config_bistro_H
#define config_bistro_H
/*
* Firmware configuration header.
*
* Bistro configuration file for TA driver 2017, (C) Flintrock (FR).
* USES voltage divider and OTC.
*
* To work with tk-bistro and other compatible software.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/


/*
* =========================================================================
* Settings to modify per driver
*/

/////////////// Choose a layout////////////////

//#define FET_7135_LAYOUT //FET+1
#define TRIPLEDOWN_LAYOUT //TA tripple
//#define NANJG105D_LAYOUT // biscotti/convoy/nanjg105D
//#define BLFA6_LAYOUT // BLFA6, FET+1, OTC and star3
//#define NANJG_LAYOUT // specify an I/O pin layout
//#define QUADRUPLEDOWN_LAYOUT // Yes, that right :)
//#define CUSTOM_LAYOUT // go define it for however you want to wire your driver.
//**** You can now easily customize layouts in fr-tk-attiny.h :

// choose the file that defines your modegruops (so we can easily keep more)
#define MODEGROUPS_H "modegroups/modegroups-TA-tripple-v1.3plus.h"
//#define MODEGROUPS_H "modegroups/modegroups-biscotti.h"
//#define MODEGROUPS_H "modegroups/modegroups-BLFA6.h"

/************************* Misc utility configs*************************************/
//#define VOLTAGE_CAL // builds a driver that just blinks ADC reading, set the VOLTAGE mode below.

//These are new but just for debugging
//#define STRIPPED // use for debugging, strips many features to make more space for debug compiler options or testing functions.
// customize it below
//#define OTSM_debug //may require STRIPPED to fit. //Will blink out number of wakes (see SLEEP_TIME_EXPONENT) on short clicks, before entering mode.

/************************************OFF-TIME CONFIGS**********************************/

#define OFFTIM3 // Use short/med/long off-time presses instead of just short/long


// #define USE_OTC // use off time cap.

// Off-time sleep mode by -FR, thanks to flashy Mike and Mike C for early feasibility test with similar methods.
#define USE_OTSM // USE OTSM. Pin must be defined in the layout too.

//#define OTSM_USES_OTC // use OTC cap for extra power on OTSM (sets it output high to charge up)
#define OTSM_powersave // Also works without OTSM to reduce moon-mode drain.
// Squeeze out a bit more off-time by saving power during
// shutoff detection (so at all times). Implements ms resolution (could be less) idle sleeps in place of delay.
// Seems to add at 0.5s of sleep at 3.1V 30uF cap, starting with only 0.75 that matters.
// But at higher voltages, it's still only 0.5s additional, not multiplicative.
// Also adds about 12 bytes that could be used for about two more mode groups instead :P


// Traditionally Cap values defined in tk-calibration
// But wake times in OTSM are not a calibration, just a configuration, so they go here.
// Times are in decimal seconds. short (med) wakes are <, not = to wake_time_short(med)

//I will probably just remove this one from view soon:
#define SLEEP_TIME_EXPONENT 4 // OTSM clicky sleep will be increments of 16ms*2^STE
// so 0 is 16, 1 is 32, 2 is 64, 3 is 128, 4 is 0.25s, 5 is 0.5s etc.
// To allow long click times use 4. For 1/8s resolution, use 3.

// (making these orange because they aren't exactly new, just better)
#define wake_time_short 0.5 // 0.5s : Short press is up to 0.5 s
#define wake_time_med 1.5 // this is limited by cap performance, but setting it high won't hurt
// Since anything beyond the cap capacity will be read as long anyway.
// It's also the long-press off-threshold for e-switch operation.

/*****************************END OTSM CONGIGS*********************************/

//#define USE_ESWITCH // pin must be defined in the layout too.
//#define USE_ESWITCH_LOCKOUT_TOGGLE

/**********************VOLTAGE CONFIG****************************************/

#define VOLTAGE_MON // Comment out to disable LVP
//You should leave one (but only one) of the next two uncommented.
#define READ_VOLTAGE_FROM_VCC // inverted "internal" Vcc voltage monitoring
// Works well for 1S lights without worrying about resistor values.
//#define READ_VOLTAGE_FROM_DIVIDER // classic voltage reading
//#define REFERENCE_DIVIDER_READS_TO_VCC // default is 1.1V, but this is needed for divider reading with OTSM on the voltage pin.
// This should normally be used with an LDO. For 1S (non-LDO or 5.0VLDO) just avoid the problem with READ_VOLTAGE_FROM_VCC.

/*** Enable battery indicator mode? */
#define USE_BATTCHECK
// Choose a battery indicator style
//#define BATTCHECK_4bars // up to 4 blinks
//#define BATTCHECK_8bars // up to 8 blinks
#define BATTCHECK_VpT // Volts + tenths

/******theremal protection: ***/
#define TEMPERATURE_MON // You can set starting temperature in the "maxtemp" setting in config options first boot options.
#define USE_TEMP_CAL // include a TEMP_CAL mode in the menu. // include a TEMP_CAL mode in the menu.
#define TEMP_STEP_DOWN //Requires TEMPERATURE_MON, Use step-down and tap-up instead of regulate/oscillate

/*******Mode features***********/

// these do nothing new, only save space for stuff you don't want, needed only for making things like biscotti builds.
#define USE_MUGGLE_MODE // compile in use of muggle mode
#define USE_REVERSE_MODES // compile in use of reverse modes
#define USE_MOON // compile in moon mode control

// Options for first bootup/default:

#define USE_FIRSTBOOT // FR notes this only costs two bytes since not using it implements alternative checks anyway.

#define INIT_MODEGROUP 11 // which mode group will be default, mode groups below start at zero, select the mode group you want and subtract one from the number to get it by defualt here
#define INIT_ENABLE_MOON 1 // Should we add moon to the set of modes?
#define INIT_REVERSE_MODES 0 // flip the mode order?
#define INIT_MEMORY 0 // mode memory, or not
#define INIT_OFFTIM3 1 // enable medium-press by default?
#define INIT_MUGGLE_MODE 0 // simple mode designed for mugglesotsm
#define INIT_LOCKSWITCH 0 // 0 => E-swtich enabled, 1 => locked.
#define INIT_MAXTEMP 88 // maximum temperature

#define BLINK_SPEED 750


// This is used to simplify the toggle function
// eliminating mode_override, using this threshold instead:
#define MINIMUM_OVERRIDE_MODE 245 // DO NOT EDIT. DO NOT DEFINE ANY STROBES HIGER OR EQUAL TO THIS.

/******* Select Which Strobes to compile in**** *********************/
////Must still be connected to a mode group or hidden mode to be used, enabled but unused modes don't get optimized out

#define BATTCHECK 244 // Convenience code for battery check mode
//mode codes for strobes, must be less than MINIMUM_OVERRIDE_MODE
#define BIKING_STROBE 243 // Single flash biking strobe mode
//#define FULL_BIKING_STROBE // Stutter bike strobe, uncomment to enable
//#define POLICE_STROBE 242 // Dual mode alternating strobe
//#define RANDOM_STROBE 241
//#define SOS 240
//#define STROBE_8HZ 239
#define STROBE_10HZ 238
#define STROBE_16HZ 237
#define STROBE_OLD_MOVIE 236
#define STROBE_CREEPY 235 // Creepy strobe mode, or really cool if you have a bunch of friends around
//#define RAMP 234 //Ramping "strobe"

//(Ok, these are new , but just for debugging, I should maybe just remove them)
#ifdef STRIPPED // define what you want to remove in stripped mode
#undef TEMPERATURE_MON
#undef VOLTAGE_MON
#define NO_STROBES // don't use strobes (not automatically stripped from modes though, probably will produce BLINK_BRIGHTNESS)
#undef USE_BATTCHECK
#endif


/**********************************************************************************
**********************END OF CONFIGURATION*****************************************
***********************************************************************************/

So if I clean out some of the debugging options, and maybe remove that confusing wake_time_exponent option, the only new things specifically relate to adding the new features, OTSM, ESWITCH, Voltage read options, and the new thermal control option. Not sure how that can be simpler, and it's I can't imagine how you can not call it more organized.

Here is the type of stuff that is no longer cluttering the configs section, because much of the include ordering requirements have been removed, and things like progmem of ramps automatically done as needed only for ramps actually defined.

uint8_t fast_presses __attribute__ ((section (".noinit")));

// total length of current mode group's array
uint8_t mode_cnt;
// number of regular non-hidden modes in current mode group
uint8_t solid_modes;
// number of hidden modes in the current mode group
// (hardcoded because both groups have the same hidden modes)
//uint8_t hidden_modes = NUM_HIDDEN; // this is never used

uint8_t modes[9 + sizeof(hiddenmodes)]; // make sure this is long enough...

// Modes (gets set when the light starts up based on saved config values)
PROGMEM const uint8_t ramp_7135[] = { RAMP_7135 };
PROGMEM const uint8_t ramp_7135s[] = { RAMP_7135s };
PROGMEM const uint8_t ramp_FET[] = { RAMP_FET };

This was cluttering the configs section before because the configs mixed programming and defines.

That's not a criticism, it's just evolved. I should really make the modegroups themselves a define too, and do the actual progmem later, becuase that still causes a little constraint like this:

#include <avr/pgmspace.h>
//#include <avr/io.h>
//#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
//#include <avr/power.h>
#include <string.h>

#define OWN_DELAY // Don't use stock delay functions.
#define USE_DELAY_S // Also use _delay_s(), not just _delay_ms()
#include "tk-delay.h"

#include "tk-voltage.h"

#ifdef RANDOM_STROBE
#include "tk-random.h"
#endif

and in the layout , all more (very hard to understand) stuff you no longer need to deal with:

#define CAP_CHANNEL 0x03 // MUX 03 corresponds with PB3 (Star 4)

#define CAP_DIDR ADC3D // Digital input disable bit corresponding with PB3

#define PWM_LVL OCR0B // OCR0B is the output compare register for PB1
#define ALT_PWM_PIN PB0 // pin 5, 1x7135 PWM
#define ALT_PWM_LVL OCR0A // OCR0A is the output compare register for PB0
#define FET_PWM_LVL OCR1B // output compare register for PB4

#define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2

#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
#define ADC_PRSCL 0x06 // clk/64

That's all moved out of the layout configuration area because the user only wants to select which pins to use.

Your modegroup defines are in a file all of their own, disentangled from other includes, in the modegroups directory, and are almost completely unchanged from before.

And new layouts no longer require reading the attiny25 manual to understand things like mux channels. That's all hidden from user configuration.

To be direct the claim that this is somehow more complicated than it used to be just isn't right and I think is related only to not trying it. The organization, and the fact that many old options are fixed in HD (at least they compile now), means many combinations of options now actually work and so many combinations are built. I suppose that flexibility could be confused with complexity.

I want to try it out but like I said, I don’t even have the hardware to try it on at the moment and don’t feel like tearing apart an existing light right now to steal a driver as most of the drivers in lights I would pull apart are soldered in place and basically there forever.

I have been using A6 drivers in the last few lights I built due to this and because I can’t afford to build new drivers. Nor do I have the funds to get the components to get the diode/cap/divider it needs.

What are the exact components it needs BTW?

I will try it when I have time but I have pretty much stopped modding flashlight the last few months except for a few leftover projects.

This was an excellent suggestion. I hooked it up, tried it out and it works very well. I’ve now implemented this in my driver design so I can finally have a driver and firmware that is fully compatible with clicky switch, e-switch and dual switch setups. Thanks!

I’ve also got pin check working by taking the voltage divider output to an additional pin, so one pin monitors voltage and the other does pin check. In order to have the voltage high enough for pin check I used two identical resistors (halves voltage) and 2.2V internal voltage reference. So I did have to make a design change for it to work but it is well worth it as Lazy-R-us suggestion is also implemented.

^ that sounds very interesting
Could you elaborate slightly about which pin you used? Knowing your design a bit I doubt you had a free unused pin around. :slight_smile:
But where (and how) did you share this added feature with? And how you did set it to low (PortB command I presume)?
Thx

I’ve switched to the ATtiny841 MU so I do have a few pins laying around :slight_smile:

I had shared a version of my 841 driver here: Mike C drivers: v8 series, ATtiny1634 based. but as that design is obsolete I un-shared it. I will update that thread and share the new design shortly.

In my new design the negative side of the divider which normally goes to ground now goes to PB0. However, I’ve just ordered that board. My confirmed tests where with wires, loose resistors and the negative side of the divider connected to PA5. To test I set PA5 as output in DDRA register, set PA5 to low with PORTA to turn the divider on, and set PA5 to high to turn it off. With PA5 low (divider on) my ADC read returns correct voltage, with PA5 high (divider off) the ADC read returned about the same as for a floating pin.

This is getting more interesting all the time! I’m looking forward to seeing your new driver design.

I tried to change some modegroups
when i build the solution in Atmel Studio 7 I get 110.3% size of a Attiny25 error

I had the same issues, this is why I now only build it in linux. It was just not worth the hassle of getting atmel to work properly.

Make sure that the optimization is turned on is the first thing I would check.

Solution is what TA said probably :slight_smile: