IR camera trigger problem - can't get over the last hurdle. $?

Hello,

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.

I would like to replace this switch with input from an IR receiver module mounted right on my Arduino. I am using this: http://ca.mouser.com/ProductDetail/Vishay/TSOP1138/?qs=oNDV51lhjEM7P54c1MlVIg%3D%3D with an IR emitter that it came with.

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. :slight_smile: 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;
}

First off did the code work with the switch?

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.

Hi,

Thanks very much for taking the time to answer.

Yes, the code works perfectly with the switch.

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.

Many thanks :)

Ok I've taken a quick look through your code. It looks like you've already updated the relevant line to: if (digitalRead(SWITCH) == LOW)

So what is actually happening when you break the beam? Nothing at all?

Hello,

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.

:blush:

If I were you I'd write a very simple sketch that just outputs the status of pin 7 to the serial monitor just for testing purposes.

Hi,

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.

#include <IRremote.h>

#define PIN_DETECT 2
#define PIN_STATUS 13


void setup()
{
  pinMode(PIN_DETECT, INPUT);
  pinMode(PIN_STATUS, OUTPUT);

}

void loop() {
  digitalWrite(PIN_STATUS, !digitalRead(PIN_DETECT));
}

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);
}

Hi,

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.

This blog is where I got the info: http://www.arcfn.com/2010/03/detecting-ir-beam-break-with-arduino-ir.html

Hmmm... :~

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?

It is 38khz. I had mentioned it in an earlier answer, sorry I wasn't clear about it.

BTW, I really do appreciate your time and effort. XD

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.)

Hi,

I need the trip to respond as immediately as possible.

I'll have to do some more reading so I can ask and respond to your help in a more knowledgeable way.

Thanks

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.

Any luck?

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.

arduinokov,

Seems that you've dropped carrier, but maybe you're still looking for a solution. "Chagrin" has touched on some good points.

Looking around, many have posed similar questions. I originally wrote this for someone in another forum. Have a look here, though: http://arduino.cc/forum/index.php/topic,70585.15.html http://arduino.cc/forum/index.php/topic,75566.0.html

It's not blazingly fast and it likely could stand some tweaking, but it may suffice for your needs.