Introduction: Slaveflash With Attiny24 Ver. 2.0

You might have noticed the Slaveflash I built with an Attiny 24, the instructable can be found here: Slaveflash-trigger-for-digital-with-Attiny24


After building the first prototype I collected all my old flashes I got over the years and had four more slaveflash-triggers to built. 
I already figured out an PCB-Layout for the SOIC-version of the attiny 24. But the biggest parts in the design are actually the hex-switch and the optocoupler, so it would make no sense to substitute only the microcontroller by a smaller one. Instead I replaced the hex-switch by a learning mode in software and also replaced the power source.

By replacing the 7805 voltage controller by a button cell with 3V, the power consumption was reduced from 2mA to below 0.5mA without the LED on. 

So here it is: Let's got started!

Step 1: Changes in the Schematics

In comparison to the former model a lot of things are deleted and the schematics is much easier.
  • The complete voltage controller section is deleted.
  • The hex-switch is replaced by nothing.
And this is what is left:
  • The reset-button
  • the flash-detector
  • the status-Led
  • and the optocoupler. 

Step 2: The Software

Also the software has changed a bit. The function to read out the hex-switch was omitted, instead two small if-statements were added in the timer overflow interrupt routine. And this is how it works:

After startup the variable "flashesneeded" is zero, that means unset. As long as this is the case the trigger waits to learn how many flashes there will be. The trigger will detect every flash and count it. After firing your real flash once you have to wait for the timer overflow (~1s). Then the if-function will recognize that there were flashes detected while the flashesneeded-variable is still zero. In this case the number of flashes detected will be written to flashesneeded and the learning mode is done. Now the variable differs from zero and no more learning occurs. To learn another number of preflashes only hit the reset button to restart the microcontroller.

It's so easy and simple!
And it saves you a lot of money!

Step 3: Making the Breadboard

I was up to print a dedicated PCB for this circuit, but when you look at how simple it is, this would be a waste of time!
I made the whole board in one hour in the evening. Just look at the two pictures to figure out what to connect. Or think on your own! ;-)

This is all set up with standard parts, no SMD and with a standard breadboard. The size of the whole circuit is about 3x4.5cm.

Step 4: Setup

Well the problem with these circuits is always: Where to store them! How to handle them and how to make it safe.

So far I chose to mount it on card-board.
I gave the cardboard a cut-out to fit the flash hot shoe in. Then I glued the cardboard to the sides of the hot shoe. Then I bend the straight part down a bit an glued the breadboard with one bigger drop of hot glue under the coin cell holder to the breadboard.
This way I can disassemble it again once I have a better solution.

Because the circuit is very light there is no problem with the weight. And also no cables are hanging around. The flash and the trigger have both different power sources which makes it very easy to change and replace the flash if you like.

Step 5: Test It!

The video shows how the slave-flash with the trigger works.

After pressing the reset button, the LED flashes two times to indicate boot-up. Then we learn the trigger three flashes and wait for the timer to overflow. The next time three flashes are detected the slave-flash fires too.

Step 6: Some Examples

Just a few pictures to show you what you could do with a slave flash trigger. I'm already looking forward to the next big family celebration to use these, but so far I only got to use them in the garden...
To understand the principles of flashlights look here:

Have fun and vote for me!


Mladens made it! (author)2015-01-11

Hello and thank you for this instructible. :)

I will try to make one but i need to use attiny85. Code would not compile in WinAVR so i started poking and prodding. Since I am total beginner it must contain mistakes but it compiles without any warnings.

I can't be sure when i will have time to test this but when i do i will confirm or edit or more likely ask for help :)

Comments and corrections are more then welcome ;)


main.c code:

* Slave-Flash with Attiny85
* Original code by: andyk75 -

* Description:
* A photo-diode registers a flash and counts an internal counter
* if the counter reaches the limit an second flash is triggered.
* Ports:
* PB4 statusled
* PB3 Reset, active low, 10k to VCC, pushbutton to GND
* PB2 Interrupt int0, active high, 1k to Pushbutton, 10k to GND Pulldown
* PB1 Clock (Xtal2), UNUSED
* PB0 fire

#ifndef F_CPU
// #warning "F_CPU not defined, is set to 1MHz"
#define F_CPU 1000000UL

#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include "slaveflash.h"

void init(void)
statusledport &= ~(1<<statusled);
statusledDDR |= (1<<statusled);

fireledport &= ~(1<<fireled);
fireledDDR |= (1<<fireled);

// Flashdetect-Interrupt
MCUCR = (1<<ISC01); // A rising Edge at Int0 generates Interrupt
GIMSK |= (1<<INT0); // aktivate interupt for int0

// reduce power consumption by switching off unneeded options
ACSR |= (1<<ACD); // Analog comparator disable
ADCSRA = 0; // ADC disable
PRR = (1<<PRTIM0) | (1<<PRUSI) | (1<<PRADC); // shut down timer1, USI, ADC for power reduce

// Timer to reset the flashcounter
TCCR1 |= (1 << CS10) | (1 << CS11) | (0 << CS12) | (1 << CS13); // timer 1 prescaler to 4096
TIMSK |= (1<<TOIE1); // Overflow interrupt enable

flashcount = 0; // clear all counted flashes
flashesneeded = 0; // initialise flashesneeded to zero

ISR(TIM1_OVF_vect) // Timer 1 Overflow
TCNT1 = 255; // preload the timer counter for about 1s.
if(flashesneeded == 0) // if still learning
flashesneeded = flashcount; // timer kicking in after learning flashes
flashcount = 0; // Reset the counted flashes
statusledport &= ~(1<<statusled); // clear the statusled

ISR(INT0_vect) // Interrupt Service routine for the int0-Pin (PB2 = interrpt)
TCNT1 = 255; // preload the timer counter for about 1s.
statusledport ^= (1<<statusled);
if (flashesneeded > 0) if (flashcount == flashesneeded) fire();

int main(void)
init(); // Set all Registers and initialise

_delay_ms(100); // Wait a 'bit'

signal(2); // signal correct startup
sei(); // enable interrupts
for(;;); // do nothing, everything important is done in the interrupt routines

return 0;

void signal(uint8_t counter)
uint8_t i;
for(i = 0; i<counter; i++)
statusledport |= (1<<statusled);
statusledport &= ~(1<<statusled);

void fire(void)
// Release the slave-flash
fireledport |= (1<<fireled);
_delay_ms(250); // enough to release the flash
fireledport &= ~(1<<fireled);
_delay_ms(100); // wait a bit before going back and reactivating the interrupt
flashcount = 0;


slaveflash.h is also modified for new pins


#define true 1
#define false 0

#define flashdetect PB2 // IN

#define statusled PB4 // OUT
#define fireled PB0 // OUT

#define flashdetectDDR DDRB
#define flashdetectport PORTB

#define statusledDDR DDRB
#define statusledport PORTB
#define fireledDDR DDRB
#define fireledport PORTB

// Function prototypes
void init(void);
int main(void);
void signal(uint8_t counter);
void fire(void);

// Variables

uint8_t flashcount, flashesneeded;


andyk75 made it! (author)andyk752015-01-12

Sorry, but I can not debug your code. Since I don't have the time and the Attiny85.

But here are some hints:

Use a LED to see where the code is going to. Does the Interrupt really occur? Did you configure the interrupt correctly? Does the photodiode work correctly? Is the timing right? Do you wait to long for the second flash? Or reset the counter too fast?

Good luck!

Adler44 made it! (author)2012-07-02

Adler44 say:
Thanks Andy, you are absolutely right. My mind was playing tricks on me; I was reading slaveflash.h file as an hex file. Sorry for your time and thanks again.

Adler44 made it! (author)2012-06-30

thanks for your circuit. I hope it works with my sony dsc w300 PS camera. One question though, in the list of include files is the slaveflash.h. It is not listed in my avrstudio4 or winavr installations. How do I get this for compiling and programming?
thanks a lot.

andyk75 made it! (author)andyk752012-07-02

You have to download the file slaveflash.h from step 2!
Just where you got the c-code!
Have fun and enjoy the slaveflash!

nixon roy made it! (author)2012-03-25

sir i copied ur c file and pasted it on avr studio and buil but its showing many error around 24 error

andyk75 made it! (author)andyk752012-03-26

You also need to include the header file (*.h)!
And make the correct settings in the avr-studio für the attiny 24. Unfortunately I'm not using avr-studio any more, so I can't help you with that. You could try a avr-forum for specific questions.

diy_bloke made it! (author)2011-12-09

Could be just me, but yr code generates many many errors in compiling. I am no expert on libraries, but is just a header file (slaveflash.h) enough for compiling?

What compiler have you used?

andyk75 made it! (author)andyk752011-12-12


this code works well with the AVR-Studio 4.something and the winAVR-gcc compiler. I had no error and not even a warning left when compiling.
I set up the workflow long ago.
AVR-studio is the editing-environment that takes care of the makefile and the includes and everything. While the winAVR provides the compiler, the libraries and the rest of what is needed. winAVR works completely in the background, I don't know if there is even a gui for it.

Hope that helped!

diy_bloke made it! (author)diy_bloke2011-12-12

Thanks Andy, I already presumed it was depending on the compiler. Guess I will get AVR

diy_bloke made it! (author)2011-10-29

Great design. The 'learning' mode is a great addition. There is another design of a 'learning' slave unit in the public domain (from Pavel Janko), based on a PIC, but this one might be easier coz the Attiny24 is probably somewhat easier to program.
No let me correct that, it is easier in my experience to build an attiny programmer than it is to build a PIC programmer.

I may build this one. I think though that the optocoupler is not really necessary as the unit is self contained. A Thyristor or even a transistor (if the sync voltage is not to0 high) will suffice.

About This Instructable




Bio: I like to explore new things and try out stuff. At the moment I'm in to electronics, BLE and LEDs.
More by andyk75:Mobile Data-Backup With Raspberry Pi 3Micro Bluetooth Low Energy (BLE) Robot (for Roborally?)Make 3D-action Videos for a Budget-price
Add instructable to: