There are many different ways to trigger an event, but sometimes you need to have an exact point in time to trigger your project. There are many different solutions out there, but most are quite cost-prohibitive. This project will show you how to build a simple and cost-efficient laser tripwire.
BUILD TIME: 45 minutes
DIFFICULTY RATING: basic
The first was from a friend of DIYODE who was preparing for national titles in horse barrel racing. It was during a discussion about her training when we realised she had no accurate measure for establishing whether or not her training runs were successful. In a sport where 0.1 of a second is the difference between being the national champion or not, this is important! The next situation involved another individual who wanted to find a way of triggering a camera so they could take pictures of mountain bikers crossing a trail. While having accurate timing is not essential in this case, it is crucial that the triggering of the camera be consistent with each passing rider. The key to both these problems was developing a simple yet accurate way to trigger an event.
THE BROAD OVERVIEW
Our primary objective here is to create a highly accurate trigger mechanism that will be consistent with each event. The event itself is then used to trigger our respective projects’ outputs.
In the case of today’s project, we will build the laser trigger first. This may be all you need, but you can also look at how we implement it beyond this, when we create a simple trigger with an optoisolator to activate a camera.
HOW IT WORKS
We have several key components that we’ll use in this build; however, the key to it all being successful and inexpensive is based around the light dependent resistor (LDR) and the laser diode.
THE LDR
The light dependent resistor, also known as a “photoresistor”, is a component that has a (variable) resistance that changes with the light intensity that falls upon it. This allows it to be used in light sensing circuits. The most common type of LDR has a resistance that falls with an increase in the light intensity falling upon the device.
The resistance of an LDR may typically have the following resistances: Daylight = 5000Ω, Dark= 20000000Ω. However, in the case of using it with an Arduino, we can simply connect it to an analogue input and measure the value with a resolution of 0 to 1023.
You can, therefore, see that there is a significant variation between these figures. If you plotted this variation on a graph, you would get something similar to that shown in the diagram shown above.
THE LASER
LASERs are things of space guns and science fiction, or at least they used to be. These days, LASERs have become incredibly inexpensive and accessible to everyday individuals. At its purest, a LASER is a beam of light that is focused in such a way that it does not disperse like a normal torchlight. A correctly focused LASER source is visible for much greater distances than any conventional light source for the same power rating. Provided it has a solid base for it to be placed upon, this focused beam can go for kilometres, making it ideal for our project!
The word “LASER” is actually an acronym for “light amplification by stimulated emission of radiation”. A LASER is created when the electrons in atoms in special glasses, crystals, or gases absorb energy from an electrical current or another laser and become “excited.” The excited electrons move from a lower energy orbit to a higher energy orbit around the atom’s nucleus. When they return to their normal or “ground” state, the electrons emit light particles called “photons”. These photons are all at the same wavelength and are coherent, meaning the crests and troughs of the light waves are all in lockstep. In contrast, ordinary visible light comprises multiple wavelengths and is not coherent.
The light generated by lasers is different from normal, visible white light. The light it produces contains only one wavelength, which is only one specific colour. Secondly, LASER light is directional. Whereas a LASER generates a very tight beam, a flashlight produces light that is diffused. Because LASER light is coherent, it stays focused for vast distances, even to the moon and back. It also means we can use it to create a very precise “line in the sand” to use in our project.
So our LDR in combination with the microcontroller will give us a numeric value based on the light hitting its face, and with the LASER being a focused and concentrated beam we can accurately “shoot” this beam across a given distance and “hit” the LDR. If the beam is on target, the LDR will register close to full value. When the LASER beam is tripped or blocked, the value of the LDR will drop significantly thus allowing us to register that an event has occurred. The one issue that negates this being a “perfect” solution is if the LDR is placed in very bright direct sunlight, as the amount of variation may be too small to reliably measure.
To balance the issue with the ambient light, we have put a potentiometer in the circuit. This will allow calibration of any light that may be present. If you intend for this project to operate in an environment where the light does not change, you could easily measure the ambient light with the sketch, and then set the value manually, thus negating the need for the potentiometer.
OPTOISOLATOR
For this build, we need to trigger a camera. Most modern cameras have a simple electrical shutter release. Put simply, they need a switch to bridge a small voltage across contacts, which in turn tells the camera to fire. This does, however, present us with a problem when we are wanting to trigger it using Arduino, as we cannot simply hook it up to one of the GPIO pins and drive it high. Instead, we need to create the equivalent of a mechanical switch, so as to allow the camera to be triggered on its independent circuit. One way to achieve this is to use a relay, but this is bulky and requires a decent amount of power to activate; not to mention that the mechanical action is usually quite slow. Being that we do not need to switch any current, we can use an optoisolator to do this job.
The BUILD
Our circuit starts by connecting the ground and 5V rails of the Arduino Uno compatible board to your bread or vero board. Be mindful of how you place the LDR on the board as it needs to be in a position where the laser can make contact with the surface.
Connect one side of the LDR to A0 in the UNO and the other to a 100Ω resistor before connecting the other side of the resistor to Ground. Next connect the outer pins of the potentiometer, one to Ground the other to 5V. The middle pin of the wiper connects to A1. For all intensive purposes, this is the basic part of the circuit you need to calibrate and detect the laser.
Next, before connecting the resistor to ground, connect the green LED to Pin 3, anode to the Uno, and cathode to a 220Ω resistor. Then, connect Pin 6 to the positive side of a Piezo buzzer, before connecting the negative to a 100Ω resistor. This is then ready to connect to Ground.
For the last part of the build, we’ll connect our optoisolator to act as our camera trigger. To do this, connect a red LED to Pin 7 with a 220Ω resistor on the other side. This resistor then connects to Pin 1 of the optoisolator. Pin 2 connects to ground. Pin 3 is not used, and neither is Pin 6. Pin 4 and 5 are used as our camera trigger. However, it could be used with anything; a relay, for example. In this case, we will be using a 2.5mm stereo jack as used by Fuji and some Canon cameras.
Pin 4 is connected to the ground or back section and Pin 5 is connected to the tip. The middle connector is used by the camera for autofocus, but we have not used it in this case. If you wanted to, you would need to add a second optoisolator and add code to focus the lens before triggering the shutter.
Basic Build:
Parts Required: | Jaycar | Altronics |
---|---|---|
1 x Arduino Uno or compatible board | XC4410 | Z6240 |
1 x LDR (Big One) | RD3485 | Z1619 |
1 x 10k Resistor | RR0596 | R7582 |
1 x Green LED | ZD0170 | Z0801 |
1 x 220Ω Resistor | RR0556 | R7542 |
1 x 10k Linear Pot | RP3510 | R2204 |
1 x Laser Diode (Arduino Module) | XC4490 | Z6370 |
1 x Buzzer | AB3459 | S6108 |
1 x 100Ω Resistor | RR0548 | R0534 |
Camera Trigger:
Parts Required: | Jaycar | Altronics |
---|---|---|
1 x Opto 4n25 5210 | ZD1928 | Z1645 |
1 x Red LED | ZD0150 | Z0800 |
1 x 220Ω Resistor | RR0556 | R7542 |
1 x Stereo 2.5mm Jack | PP0103 | P0022 |
THE CODE
This code is written for the 328p chips such as the Arduino Uno, Nano and Mega. However, it does not use any libraries or non-standard functions and should, therefore, compile across almost any of the Arduino family.
The code for this project is quite compact, and because of this, we have the space to go through all of it. We start by naming our input and output pins. You do not have to do this, however, it is best practise as searching through your code at a later date will prove cumbersome. By naming our inputs and outputs, we only have to change the pin assignment in one place if we change our hardware.
For this project, we are using two analogue inputs and three digital outputs. A0 is assigned to the tripPin, this input is used to measure the value of the light from the light dependent resistor. The adjPin is used for the potentiometer to set up the calibration, if required, to allow for any variation in the ambient light. The grnLed is the pin assigned to the green LED. This is used primarily to signal that the beam has been broken and used in the calibration process. The camPin is for our output trigger and the piezoPin links to our Piezo buzzer.
int tripPin = A0;
int adjPin = A1;
int grnLED = 3;
int camPin = 7;
int piezoPin = 6;
Next, here are the settings that you will need to change.
The system has two distinct modes: the first is a default mode called “interval mode”. This mode allows us to control exactly what happens after the beam is broken. The first setting is the camDelay integer, and refers to the number of milliseconds that the system will delay before taking the first shot. This is useful if you are unable to place the beam exactly at the point you need the camera to trigger. The next setting is the camDwell integer. Again this is a setting that is in milliseconds, and it represents the number of seconds between shots. The final setting in interval mode is the camShots, which tells the system the number of shots you want to be triggered by the unit. Please note that the system here is simply triggering the camera, and makes no dispensation for the settings on your camera. This is key when setting your shutter speed. So, if your shutter speed is set to 1/100 of a second then a dwell time of 200 is fine; but if your shutter is set to 1/2 second then the resulting shutter time will be 500ms, and the result would mean that the system will fire twice while the shutter is still open, which would mean you’d only get two of your five requested shots. Make sure that if you are using more than a single shot, that your camDwell is set to be longer than your shutter speed.
int camDelay = 0;
int camDwell = 200;
int camShots = 5;
The second mode is “burst mode”, which is simply set to “on” or “off”. This is the digital equivalent of holding your finger on the shutter button. In this case, you need to make sure your camera is set to “continuous” or similar mode. This setting determines the time in milliseconds, that you want the shutter button held down. Note that the camDelay setting still does get actioned in burst mode.
//burst mode
int burstMode = 0; //0=Off 1=On
int burstTime = 3000; //time in milli seconds
Our setup code comes next.
This simply sets up and starts our serial output, before initiating the three output pins.
void setup() {
Serial.begin(9600);
pinMode(grnLED, OUTPUT);
pinMode(camPin, OUTPUT);
pinMode(piezoPin, OUTPUT);
}
Next, we have our function “shutter”. While not crucial, it is best practise to put a function in the code before it is called. This does not affect all languages, but it is not uncommon to experience bizarre behaviour with no discernible error from this.
In the case of this code, the “shutter” function could be anything that you want done, once the beam is broken. The main loop calls this, and it’s where we action our event.
The first line here determines the delay, as specified in the camDelay variable that we set beforehand. We then move to see if burst mode is on or off. If it’s on we send the camPin high and then set a delay for the period of time in the burstTime variable. We then bring the pin low to stop the shutter. If burst mode is off, then we go into a loop for the interval timer, which loops the number of times set out in the camShots variable.
In this loop we start by sending the camPin high, and then we have a slight delay of 10 milliseconds. This may need to be tweaked, depending on your camera. This delay makes sure that we get a proper square wave sent to the camera, and enough of a pulse between pulling the pin low.
After this, we then set another delay for the period in which we have set the camDwell variable.
void shutter() {
delay(camDelay);
if (burstMode == 1) {
digitalWrite(camPin, HIGH);
delay(burstTime);
digitalWrite(camPin, LOW);
} else {
for (int i = 0; i <= camShots; i++) {
digitalWrite(camPin, HIGH);
delay(10);
digitalWrite(camPin, LOW);
delay(camDwell);
}
}
digitalWrite(piezoPin, LOW);
}
Finally, we have our main loop.
The first two lines are used to read and output our two analogue inputs. The first is the value of the tripPin and the second is the adjPin. These are to aid in setup only, and can be commented out or deleted as required.
In the next three lines, we read the value of the adjPin, our potentiometer, and use the value to define our trip point. As discussed earlier we need to know at what point the laser beam suddenly stops hitting the surface of the LDR. Our test bench ambient light reads a value of about 450 from the analogue channel. With the laser hitting the LDR it was 950.
Using the potentiometer, we adjusted this threshold to 900. This meant that ambient light could fluctuate and not bother the system, but when the laser was suddenly cut, then we have a trip active. Once this is detected, then the shutter function is called.
This is the type of project that can easily be customised or modified to suit your needs. The tripwire itself should be considered modular, and you can easily add your code but where do we add it. This is where the shutter function comes into effect.
Because our trigger calls the "shutter" function, you can simply hijack the shutter function to perform whatever actions you would like to perform when the LASER trip wire is triggered. Perhaps you want to trigger a siren, some flashing lights, alert yourself via Twitter, and more. Whatever you would like to do, simply put it inside the shutter function and you don't need to modify any other parts of the code.
void loop() {
Serial.println(analogRead(tripPin));
Serial.println(analogRead(adjPin));
int val = analogRead(adjPin);
val = map(val, 0, 1023, 0, 2046);
Serial.println(val);
if (analogRead(tripPin) < val) {
Serial.println("trip");
digitalWrite(grnLED, HIGH);
digitalWrite(piezoPin, HIGH);
shutter();
} else {
digitalWrite(grnLED, LOW);
}
delay(100);
}
CALIBRATION
We have included the potentiometer to allow us to calibrate the device. This is because of the changes that will happen with ambient light. If we were using the device in an environment where the light does not change, you could ignore the potentiometer altogether and just substitute the right value for the threshold point.
To calibrate the unit, attach the laser to power and shine it on the LDR. The green LED should be off. Turn the potentiometer until the light turns on, and the system is triggered. Once this is active move the potentiometer back slightly and the system is ready to go.
If you look back at our code, you can see that we remap the potentiometer value from the standard 1023 to 2046. This means that the middle point of the potentiometer will be used for the calibration, rather than all the way to one end.
WHERE TO FROM HERE?
We have used the LDR and a laser to create a highly accurate yet low-cost tripwire. The system could easily be expanded to produce timing loops for racing or slot cars, or other fun things. It could also be modified to have several different LDRs over a target area, to create a virtual shooting range.
WARNING: Lasers, while cool, are not toys. Directing the beam towards your own or another person’s eyes can be serious and even cause harm. We recommend the use of safety glasses during any exposure to laser-emitting diodes.