TLDR: PCINT0_vect is the interrupt vector for all pin change interrupts on the attiny85. I had originally used PCINT1_vect, which caused it to restart and run setup again.
I'm working on an IR beam break trigger that I will eventually connect to a DSLR. One attiny85 pulses a 38kHz signal that is detected by a second attiny85 that gets a signal as a pin change interrupt from an IR receiver.
The basic logic is this:
timer1 counts up to 25ms
if it overflows, then it triggers an interrupt that starts the photo routine
The IR pulse comes in about every 21ms.
A pin change from the IR receiver resets the timer one counter so it doesn't reach 25ms.
That was behaving exactly like I wanted it to, so I started working on a way for the IR emitter end to tell the receiver end it was shutting down when the battery voltage got too low. I added an LCD to get some feedback on what was happening with variables.
When I added the LCD, though, the response time of the receiver end increased significantly and the LCD backlight would blink. After removing any attempts to enter sleep mode and making sure there were no commands to the LCD anywhere but in setup(), the behavior didn't change. I removed everything to do with the LCD and replaced the LCD initialization code with code that turns on the LED standing in for the camera for 5 seconds to see if the set up was running again.
Currently, the camera/LED signal turns on for 5 seconds every time that the IR receiver pin change interrupt gets triggered and will stay on if it continues to receive the IR pulses. It seems like the device is restarting. I made sure that the brown out detector and the watchdog timer were disabled and I added a pullup resistor to the reset pin. I think that narrows it down to a power on reset or a crash that restarts everything.
I've been trying to figure out what I did to break things, but I'm starting to wonder if it's been doing this the whole time and the setup code just didn't take a noticeable amount of time. Either way I'm not sure what's going on at this point. Schematic and code below.
Using Arduino uno as ISP and the ATTiny Core from Konde. Speed is at 1MHz.
#include <avr/io.h>
#include <avr/interrupt.h>
const int shutter = 4;
int num_photo = 4; //will later take input to set during setup
int photo_deltaT = 1000; //will later take input to set during setup
volatile int tripwire = 0;
void setup() {
//Interrupts setup
cli();
//Timer 1 40Hz (T=25ms) setup
TCCR1 = 0; // Stop Timer1
TCNT1 = 0; // Reset Timer1 count
GTCCR |= (1<<PSR1); // Reset prescaler for Timer1
//Turn on fast PWM mode and set prescaler to 128. See register description in section 12.3 of ATTiny85 datasheet
TCCR1 |= (1<<PWM1A)|(1<<CS13);
//Set TOP value of counter to 194 to get a 40Hz signal. Follow formula on p.87 of datasheet.
OCR1A = 194;
TIMSK |= (1<<OCIE1A); // Enable OCRA interrup on Timer 1
//Pin change interrupt setup
GIMSK |= (1<<PCIE); //Enable pin change interrupts
PCMSK |= (1<<PCINT1); //Enable pin change interrupt on PB1
WDTCR &= ~(1<<WDE) & ~(1<<WDIE); //disable watchdog timer
MCUCR |= (1<<BODS) | (1<<BODSE); //disable brownout detector
sei();
pinMode(shutter,OUTPUT);
//test signal to see if setup runs again
digitalWrite(shutter,HIGH); //sends a signal to the shutter release to take a picture
delay(5000); //wait 5s
digitalWrite(shutter,LOW); //turns off signal to shutter release
}
void loop() {
// put your main code here, to run repeatedly:
if (tripwire == 1){
photo();
tripwire = 0;
}
}
ISR(TIMER1_COMPA_vect){
tripwire = 1;
}
ISR(PCINT1_vect){
TCNT1 = 0;
}
void photo(){
GIMSK &= ~(_BV(PCIE));
for (int i = 0; i < num_photo; i++){ //sets a loop to repeat the number of photos taken per trigger
digitalWrite(shutter,HIGH); //sends a signal to the shutter release to take a picture
delay(50); //wait 50ms
digitalWrite(shutter,LOW); //turns off signal to shutter release
delay(photo_deltaT - 50); //sets the delay time between pictures
}
TCNT1 = 0;
GIMSK |= (1<<PCIE);
}




