I would like to use a light barrier to trigger a camera.
It should trigger the camera as long as the light beam is broken (HIGH-signal) and it should be possible to shot additional images after the last trigger signal from the light barrier.
The whole system needs to sleep if nothing happes and I'm using the LowPower.h-library.
#define TRIGGER_A_PIN 1 // PA10, 15 an IC
volatile boolean trigger_a_int = false;
//My idea was to do in setup()
void setup()
{
Serial.begin(9600);
pinMode(TRIGGER_A_PIN, INPUT); //pulled low by resistor
attachInterrupt(TRIGGER_A_PIN, trigger_a_int_func, HIGH);
}
void loop() {
trigger_funct(); //calls the function to later be able to shoot additional images
}
//interrupt routine:
void trigger_a_int_func() {
detachInterrupt(TRIGGER_A_PIN);
trigger_a_int = true;
trigger_funct(); // call the camera function immediatly for taking a picture
}
//trigger the camera:
void trigger_funct() {
if (trigger_a_int) {
//Trigger the camera program
Serial.println("Trigger");
trigger_a_int = false;
attachInterrupt(TRIGGER_A_PIN, trigger_a_int_func, HIGH);
}
}
Why isn't this working? It fires the interrupt only once
HI,
why is it unnecessarily? When not detaching it fires constantly and didnt execute the rest.
Yes there volatile.
It wasn't supposed to be code snippes. I just stripped everything als in my current test program to figure out how to deal with attaching and re-attaching the interrupt.
How would you solve that if you says that's unnecessarily to detach the ISR?
timtailors:
I just stripped everything als in my current test program to figure out how to deal with attaching and re-attaching the interrupt.
For most effect help, always post a complete program that actually compiles, not just snippets where you think the problem is. After all, if you really knew what the problem was, you wouldn't need to post a question. You'd just fix it.
When not detaching it fires constantly and didnt execute the rest.
I suspect that the interrupt is doing exactly what you are telling it to do. It's firing as long as the pin is HIGH. Perhaps you want to consider using RISING, FALLING, or CHANGE.
You haven't posted any code that includes use of the LowPower.h library.
Now that you mention it, I think I recall that edge triggering requires certain clock(s) to be enabled. You can set them to be enabled during sleep. See the SMAD21 datasheet.
Post full code of your attempts (BOTH edge and level triggering) that include the LowPower.h library.
Ok but will the power consumption increase when enabling additional clocks?
If so then it would be maybe better so solve the first attemp with HIGH and getting the interrupt attached again?
RISING:
#include "LowPower.h"
#define TRIGGER_A_PIN 1 // PA10, 15 an IC
volatile boolean trigger_a_int = false;
void setup()
{
Serial.begin(9600);
pinMode(TRIGGER_A_PIN, INPUT); //pulled low by resistor
attachInterrupt(TRIGGER_A_PIN, trigger_a_int_func, RISING);
}
void loop() {
trigger_funct();
}
void trigger_a_int_func() {
trigger_a_int = true;
trigger_funct();
}
//trigger the camera:
void trigger_funct() {
if (trigger_a_int) {
//Trigger the camera program
Serial.println("Trigger");
trigger_a_int = false;
LowPower.standby();
}
}
HIGH:
#include "LowPower.h"
#define TRIGGER_A_PIN 1 // PA10, 15 an IC
volatile boolean trigger_a_int = false;
void setup()
{
Serial.begin(9600);
pinMode(TRIGGER_A_PIN, INPUT); //pulled low by resistor
attachInterrupt(TRIGGER_A_PIN, trigger_a_int_func, HIGH);
}
void loop() {
trigger_funct();
}
void trigger_a_int_func() {
trigger_a_int = true;
trigger_funct();
}
//trigger the camera:
void trigger_funct() {
if (trigger_a_int) {
//Trigger the camera program
Serial.println("Trigger");
trigger_a_int = false;
LowPower.standby();
}
}
There seems to be multiple Low Power libraries out there, all conveniently using the header file "LowPower.h". Which one are you using? BTW, This One is specifically for SAMD boards.
So, I couldn't come up with a bullet-proof way of combining level-sensitive interrupts and sleep mode. I needed to disable the interrupt in the ISR to prevent the processor from being slammed as the input continued to cause continuous interrupts. But, then re-enabling the interrupt before sleeping is tricky because an interrupt right before sleeping would disable further ones again and the processor would never wake up.
So, I went with edge-triggered interrupts and the ArduinoLowPower library. Check out the ExternalWakeup example that comes with that library as a good starting point. I ended up modifying that example because contact bounce was causing spurious interrupts and incrementing of the 'repetitions' variable.. Code below was tested on an Adafruit Feather M0 -- the only SAMD21 board I have.
If you're going to use sleep, you MUST use a level-sensitive interrupt to wake up. Once awake, you can then switch to edge-sensitive interrupts to do whatever it is you need to do when awake. When you then go back to sleep, switch back to level-sensitive interrupts. Edge-sensing REQUIRES a clock which WILL increase power consumption.
The ArduinoLowPower library in fact enables the clock necessary to allow edge-triggered interrupts during sleep. It uses the 32KHz clock for this purpose. You'd need that clock active anyway if you want to do a wake-on-RTC type sleep. So, yes it will increase power dissipation. But, I think the 32KHz clock is fairly low power.
In the end it's an engineering tradeoff. You can use other techniques, but to assert that you "MUST" use level-triggered interrupts is a fallacy.