I'm making a note here, huge success!
I have reproduced this on Instax SQ1 using ATtiny13A. Biggest deviation was that SQ1 has Vdd always active, even when the lense is turned to off, so the code was changed a bit for more deep sleep saving - using power down sleep mode (and adjusting the interrupts to support it), setting input pull-up for all unused pins, disabling BOD fuse, reducing the clock speed to 128 kHz and I ended up using internal pull-up resistors instead of an external one.
Hardware
After programming with Arduino ISP only 4 wires are required - GND, Vdd, PB0 (purple), PB1 (white).
Connected in much the same way as in the guide.
Software
I have "ported" the code for the Arduino IDE using the MicroCore framework. Here are the setting to burn the fuses:
After setting the fuses to the above mentioned settings I have flashed this sketch with maximum power savings:
Note: Arduino ISP needs to be reprogrammed with #define SPI_CLOCK (128000/6) to account for the reduced cpu frequency after burning the fuse that reduced the CPU frequency from 9.6MHz to 128kHz.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#define BUTTON_PIN PB1
#define OUTPUT_PIN PB0
#define SIGNAL_DURATION_MS 300
#define SHORT_BUTTON_PRESS_TIME_MS 1500
#define BUTTON_PROBING_INTERVAL_MS 100
#define LONG_BUTTON_PRESS_SIGNAL_DELAY_MS 10000
void send_signal()
{
// PORTB0 is always set to 0 (output/low or input/high-z depending on DDRB)
// Drive output low (output)
DDRB |= (1 << DDB0);
_delay_ms(SIGNAL_DURATION_MS);
// Return to high-z (input)
DDRB &= ~(1 << DDB0);
}
short is_button_pressed()
{
return !(PINB & (1 << BUTTON_PIN));
}
short is_long_button_press()
{
int delay = 0;
do
{
_delay_ms(BUTTON_PROBING_INTERVAL_MS);
delay += BUTTON_PROBING_INTERVAL_MS;
} while (is_button_pressed() && delay < SHORT_BUTTON_PRESS_TIME_MS);
return delay >= SHORT_BUTTON_PRESS_TIME_MS;
}
void wait_for_button_release()
{
while (is_button_pressed())
{
_delay_ms(BUTTON_PROBING_INTERVAL_MS);
}
}
ISR(INT0_vect)
{
// Disable INT0 to avoid multiple triggers while the button is held down.
GIMSK &= ~(1 << INT0);
}
void app()
{
// Set PB0 as input (high-z) and rest as input
DDRB = 0;
// Set pull-ups on input pins except PB0 (which should stay high-z)
PORTB = (1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5);
// Disable unused peripherals for power saving.
ADCSRA &= ~(1 << ADEN); // Disable ADC.
// Keep PB1 (AIN1/INT0) digital input enabled.
DIDR0 = (1 << AIN0D) | (1 << ADC0D) | (1 << ADC1D) | (1 << ADC2D) | (1 << ADC3D);
ACSR |= (1<<ACD); // Disable analog comparator
PRR |= (1<<PRTIM0)|(1<<PRADC); // Enable power reduction Timer0/ADC
// Enable INT0 in low-level mode (required for wake from power-down).
MCUCR &= ~((1 << ISC01) | (1 << ISC00));
GIMSK |= (1 << INT0);
// Disable WDT
wdt_disable();
// Enable interrupts.
sei();
// Use deep sleep and wake via INT0.
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// Infinite loop.
while (1)
{
sleep_mode();
if (is_button_pressed())
{
if (is_long_button_press())
{
wait_for_button_release();
_delay_ms(LONG_BUTTON_PRESS_SIGNAL_DELAY_MS);
}
send_signal();
}
// Re-arm INT0 only after the button returns high.
wait_for_button_release();
GIFR |= (1 << INTF0);
GIMSK |= (1 << INT0);
}
}
extern "C" void setup() {app();}
extern "C" void loop() {}
Its a shame Instax does not do this out of the box since they have such a capable mcu on board. Anyways I'm thanking you for your guide. If I have any issues I will update them here.
I'm making a note here, huge success!
I have reproduced this on Instax SQ1 using ATtiny13A. Biggest deviation was that SQ1 has Vdd always active, even when the lense is turned to off, so the code was changed a bit for more deep sleep saving - using power down sleep mode (and adjusting the interrupts to support it), setting input pull-up for all unused pins, disabling BOD fuse, reducing the clock speed to 128 kHz and I ended up using internal pull-up resistors instead of an external one.
Hardware
After programming with Arduino ISP only 4 wires are required - GND, Vdd, PB0 (purple), PB1 (white).
Connected in much the same way as in the guide.
Software
I have "ported" the code for the Arduino IDE using the MicroCore framework. Here are the setting to burn the fuses:
After setting the fuses to the above mentioned settings I have flashed this sketch with maximum power savings:
Note: Arduino ISP needs to be reprogrammed with
#define SPI_CLOCK (128000/6)to account for the reduced cpu frequency after burning the fuse that reduced the CPU frequency from 9.6MHz to 128kHz.Its a shame Instax does not do this out of the box since they have such a capable mcu on board. Anyways I'm thanking you for your guide. If I have any issues I will update them here.