I have been working on a system for recording with my Canon camera. I have been working very hard on this project but am stuck and I can't quite make it over the last hurdle. I'm a real newbie with Arduinos and could really use some help.
Right now, the SWITCH (see the code) is an external camera attachment called a Pocket Wizard hard wired into my board to pin 7 and ground. When triggered, it sends an IR burst up a lead (pin 12) to the IR sensor on my camera.
The difference is the pocket wizard as it was attached to my board was a N/O switch. The IR receiver module is constantly receiving an IR signal from an IR emitter and I want the trigger to be when that signal is disrupted (like a trip wire).
If anyone could look a my code and lend a hand, I would be very grateful. Not sure what would be reasonable $ for this. Please suggest.
/*REMOTE TRIP SKETCH*/
const int irLED = 12;
const int SWITCH = 7;
const int powerLED = 4;
boolean running = false;
int ledState = HIGH; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 200; // interval at which to blink (milliseconds)
unsigned int pulseDuration = 10; // microseconds
// The required 15 microseconds pulseDuration didn't work since digitalWrite consumes some additional time
// thats adds to pulseDuration value. 10 to 12 microseconds worked for me.
unsigned int video = 5360; // A 5360 microseconds delay between bursts starts/stops video recording.
unsigned long videoLength = 90000; // 90 seconds of video.
unsigned long whenToStopRecording = 0;
unsigned long awakeLength = 5000; // TEMP 5 sec 870000 = 14.5 minutes -- the camera falls asleep after 30 minutes of inaction.
unsigned long whenLastAction = 0; // When the camera did something last (ie was kept from sleeping).
unsigned long wakeVideoLength = 3000; // 3 seconds of video to keep the camera awake.
void setup(){
//Serial.begin(9600); // uncomment for debugging
pinMode(irLED, OUTPUT);
pinMode(SWITCH, INPUT);
pinMode(powerLED, OUTPUT);
digitalWrite(SWITCH, HIGH); // turn on internal 20 k pullup resistor so the open input state is HIGH.
digitalWrite(powerLED, HIGH);
}
void loop(){ // run again and again
unsigned long currentMillis = millis();
// Blink the power LED while recording.
if (running == true){
//Serial.print("running"); // uncomment for debugging
//Serial.println();
if (currentMillis - previousMillis > interval){
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW){
ledState = HIGH;
}
else{
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(powerLED, ledState);
}
}
// Test if the camera has been triggered to record
if (digitalRead(SWITCH) == LOW){ // read switch input
// Only start recording if we currently aren't.
if (!running){
shoot(video); // (hopefully) start video recording
running = true;
whenLastAction = currentMillis;
delay(500);
}
whenToStopRecording = currentMillis + videoLength;
}
// Make the camera take a 3 second video every 14.5 minutes so it doesn't fall asleep
if (currentMillis - whenLastAction > awakeLength){
if (!running){
shoot(video); // (hopefully) start video recording
running = true;
whenLastAction = currentMillis;
delay(500);
whenToStopRecording = currentMillis + wakeVideoLength;
}
}
// See if it's time to stop recording
if (currentMillis > whenToStopRecording){
// only bother if it was running -- after the video ends, the condition above is true,
// but we don't want to do anything.
if (running){
shoot(video); // (hopefully) stop video recording
digitalWrite(powerLED, HIGH);
running = false;
whenLastAction = currentMillis;
delay(500);
}
}
}
void shoot(unsigned int delayBetweenBursts){ // sends the IR signal
// send first 16 bursts
for(int i=0; i<16; i++) {
digitalWrite(irLED, HIGH);
delayMicroseconds(pulseDuration);
digitalWrite(irLED, LOW);
delayMicroseconds(pulseDuration);
}
delayMicroseconds(delayBetweenBursts);
// send second 16 bursts
for(int i=0; i<16; i++){
digitalWrite(irLED, HIGH);
delayMicroseconds(pulseDuration);
digitalWrite(irLED, LOW);
delayMicroseconds(pulseDuration);
}
return;
}
The IR receiver you have chosen is intended for use with IR remote control systems. For it to work the IR LED with have to be modulated at 38khz. The receiver disregards other signals as noise.
The receiver I am using came as part of a pair, an emitter and receiver modulated at 38khz. They work well outside of the Arduino.
On my breadboard, the receiver works with the transmitter, just in a way that is opposite to the way I want. When I turn on the emitter and point it at the receiver, it starts the recording immediately. I would like it to work like a trip wire where it only triggers the camera when the beam is broken.
I feel like I am close, but I just can't get that final step.
I don't get a chance to break the beam because as soon as I turn on the emitter and receiver parts of the setup, the camera is triggered to record immediately.
If I interrupt the beam, nothing changes as it is already recording.
You'll see in the code that the camera records for 90 sec. and then stops unless it is triggered again. Unfortunately with the current set up, once it is triggered by the IR receiver, it just continues recording.
I'm sorry, I'm just a beginner with Arduinos. It's so disheartening to be so close and not be able to find the answer. I really appreciate your help.
This code, with the included library, works perfectly, except in the opposite way. When the receiver is receiving the IR signal, the LED is lit, when the beam is broken, the LED goes out. I simply want the opposite to happen within my code.
At the speed the microcontroller runs you wouldn't be able to perceive what was actually being received. The LED could be flashing on and off but due to POV you can't see it. Give the standard DigitalReadSerial example a whirl (below)
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
int sensorValue = digitalRead(2);
Serial.println(sensorValue, DEC);
}
The LED is flashing in a very clear way that I can see. When I cover the emitter, it clearly stops. When I uncover the emitter, it flashes.
I need the opposite to create the "trip wire", so that my output (the IR led that is in front of the sensor on my camera) is triggered when the beam is broken, not established.
Ahhhh ok now it's clear. You hadn't said that it's a modulated signal! So when unbroken, you receive a constant stream of 5v pulses from the receiver? and when broken you get a constant 0v? This is why your code triggers immediately. You need to take sample [of the number of pulses] over a period of time that would ensure that, should the beam be unbroken, a pulse would have been received. The sample period is going to be a balance between accuracy and responsiveness. Do you know the frequency of the unbroken output?
You wouldn't see a 38khz frequency signal. That's the carrier frequency. I suspect you are seeing something else. How fast do you need to have this respond to the beam being broken? either use that as the basis of the sample of time or figure out the frequency of the output signal (perhaps report micros() over serial every time the signal goes low.)
I'd create a loop that checks the output for say 500ms and sets a flag if it sees a high value at any time. Then use this flag to trigger. Once you have it working you can tune the value down.
TSOP1138 is not really designed for "beam breaking". Read page 5 of the datasheet and you'll see that it expects the IR signal to have 10 cycle pauses every 16-70 cycles. The preferred Vishay brand module would be TSOP4038 or TSOP58038 which is described as a "presence sensor" and has no cycle-pause requirement.
There's a lot of code and wiring that you aren't showing here. The code you've shown us is only designed to send IR signals and doesn't say anything about an IR receiver.