Laser Setup and Detection
Posted on Wednesday, 21 November 2012
|
3 Comments
Laser Setup
TESTING LASER SWITCHES ON
Firstly, the laser needed to be tested to see if it would work. On the TTL laser, there is a polarized 4-pin connector with the following connections:
- Red wire:5-12 V DC input
- Black wire: GND
- Green wire: 10k pull-down (aka GND)
- White wire: active low TTL input (3.3 V or 5 V logic)
The laser was tested by firstly just turning the laser ON and leaving it on. This was done by connecting the red wire to a power source, the black wire to GND, the white wire to GND and leaving the green wire unconnected. This successfully turned the laser on.
TESTING LASER WORKS WITH ARDUINO
Arduino Laser Connections |
The Arduino was given power and the basic sketch "Blink" was downloaded to the board. Once downloaded, the laser successfully started blinking in accordance with the sketch. This shows that the laser can easily work with the Arduino.
Laser Detection
LDR
To detect a laser, a light dependent resistor (LDR) is needed. An LDR is a device which has a resistance that varies according to the amount of light falling on its surface. A typical LDR can be seen pictured below, along with its circuit diagram symbol.
LDR and circuit symbol |
The LDR that was chosen to go with the TTL Laser Module was the Mini Photocell, as this was suggested from the manufacturer. The photocell can be seen below.
Mini Photocell |
DETECTION CIRCUIT
An LDR can be set up in two ways:
- The LDR is activated by darkness
- The LDR is activated by light
LDR circuit |
When light hits the LDR, the LED will light up. The variable resistor is used to fine tune the amount of light needed to activate the LDR.
A similar circuit to the one pictured above (resistor values were different) was built on a breadboard and the variable resistor was used to tune the LDR so that only the high intensity laser beam activated the LED and not the background light from the room. The circuit was powered by connecting it to an Arduino, along with a laser. A video of this circuit working can be seen below.
As can be seen, when the laser moves over and hits the LDR, it switches the transistor and turns the LED on.
ARDUINO CODE
SIMPLE LASER DETECTION
Now that the laser and detection circuit has been tested to see that both work, the next stage is to get the Arduino involved. The Arduino should be able to turn the laser on and off. Firstly, the pin that the laser is connected to can be given a name, for example, laser. This pin can then be set as an output, which will tell the laser to go either high or low depending on which command the Arduino writes to it. For this first simple set up of code, the laser is set to be low. The pin that the LDR is connected to is set up in the same way. It is given a name (LDR) and is assigned a pin mode (this time it is set to input, as data will be received from the LDR). For this circuit, the laser is connected to pin 8 and the LDR is connected to pin 7, but any pin could have been chosen. The code can be seen below.
INSERT PIC
Once everything is set up, the Arduino was kept connected to the computer and a Serial monitor was opened. When the laser hit the LDR, on the Serial monitor "HIT" was printed. The Arduino successfully works with the laser detection circuit.
/* int LDR = 7; //LDR attached to pin 7 int laser = 8; //Laser attached to pin 8 // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // make the LDR's pin an input: pinMode(LDR, INPUT); //make the laser's pin an output: pinMode(laser, OUTPUT); digitalWrite(laser, LOW);//turn laser on }Now that the pins have been set up, code can be written to interact with the detector circuit that has been built. When the LDR is hit with the laser, the output changes from high to low. This change can be picked up by the Arduino by doing a digital read of the pin. A digital read reads the value from a specified digital pin, either HIGH or LOW. If the value read is LOW, the Arduino can state that it has been hit, else if it is HIGH it won't do anything, as can be seen in the following code.
// the loop routine runs over and over again forever: void loop() { // read the input pin: int hitState = digitalRead(LDR); //LDR goes low when it has been hit if (hitState == 0) { Serial.println("HIT"); delay(2000); // delay in between reads for stability }This code can now be put together and uploaded onto the Arduino. The Arduino and detector circuit should be set up as follows.
INSERT PIC
Once everything is set up, the Arduino was kept connected to the computer and a Serial monitor was opened. When the laser hit the LDR, on the Serial monitor "HIT" was printed. The Arduino successfully works with the laser detection circuit.
USING INTERRUPTS
If the robot was only detecting whether or not it had been hit, the code shown above would be fine. However, the robot is going to be processing lots of other code (controlling servos, motors, lasers etc) and so the above code is not sufficient, as it only checks if it has been hit once every turn of the loop. This could cause the robot to miss detecting that it has been hit.
To overcome this problem, interrupts can be used. An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention, which in this case is the LDR stating that it has been hit. There are only two external interrupt pins on the Arduino Uno, INT0 and INT1, and they are mapped to Arduino pins 2 and 3. The interrupts can be set to trigger on RISING or FALLING signal edges, or on low level. It was decided that the interrupt should occur on the FALLING signal edge rather than on low level. This is because it means that the user will have to move the laser off the LDR before they can hit the robot again, making the game slightly harder. Otherwise, the user could just leave the laser pointing on the LDR and get a huge score.
The code was changed to use interrupts instead of a digital read. For interrupts to work, the interrupt library needs to be included in the code, therefore at the top of the program before anything else this line of code was added:
#include "avr/interrupt.h"Firstly, the pin that the LDR was on was changed from 7 to 2 (as pin 2 has an interrupt attached to it). In the setup method, the following code was added to enable the interrupt and set the interrupt to trigger on a falling edge.
sei(); //Enable global interrupts EIMSK |= (1 << INT0); //Enable external interrupt INT0 EICRA |= (1 << ISC01); //Trigger INT0 on falling edgeAn interrupt service routine (ISR) then needs to be written. An ISR is the code that is run when the interrupt is triggered. For the moment, the Arduino will just print out that it has been hit.
//interrupt service routine for when the LDR is hit ISR(INT0_vect) { Serial.println("HIT INTERRUPT"); }In the main loop of the program, the digital read is removed, as that is no longer needed. To get the program to still do something for the interrupt to interrupt, the Arduino will just print out that it is waiting for the interrupt. The whole code now looks like this:
int LDR = 2; //LDR attached to pin 2 (as pin 2 has an interrupt on it) int laser = 8; //Laser attached to pin 8 // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // make the LDR's pin an input: pinMode(LDR, INPUT); //make the laser's pin an output: pinMode(laser, OUTPUT); sei(); //Enable global interrupts EIMSK |= (1 << INT0); //Enable external interrupt INT0 EICRA |= (1 << ISC01); //Trigger INT0 on falling edge digitalWrite(laser, HIGH);//turn laser on } // the loop routine runs over and over again forever: void loop() { //print something so program has something to do Serial.println("Waiting for interrupt"); delay(1000); //wait one second } //interrupt service routine for when the LDR is hit ISR(INT0_vect) { Serial.println("HIT INTERRUPT"); }Running the code and watching on a serial monitor, the program outputs "Waiting for interrupt" every second until the interrupt is called, in which case it prints "HIT INTERRUPT".
UPDATING SCORES AND USING MILLIS
Now that the code works with interrupts, more functionality can be added. A score can be added into the code, so that every time the robot is hit, a score is incremented. To stop a user from continually hitting the robot and gaining a large score very quickly, an interval can be included to stop incrementing the score until 5 seconds has passed between hits. Finally, rather than using delays in the code which hold the whole program up, a function called millis() can be used. It is a command that returns the number of milliseconds since the Arduino board started running its current program. An example of using millis() is given in the Arduino examples, callled "Blink without Delay".
Combining all of the above, the final code looks like the following:
Combining all of the above, the final code looks like the following:
#include "avr/interrupt.h" int LDR = 2; //LDR attached to pin 2 (as pin 2 has an interrupt on it) int laser = 8; //Laser attached to pin 8 int score = 0; //score of the robot int scoreFront = 10; //score of hitting the LDR //introduce 5 second interval after hit before another hit can occur int interval = 5000; long lastBlinkTime = 0; //variable used with millis // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // make the LDR's pin an input: pinMode(LDR, INPUT); //make the laser's pin an output: pinMode(laser, OUTPUT); sei(); //Enable global interrupts EIMSK |= (1 << INT0); //Enable external interrupt INT0 EICRA |= (1 << ISC01); //Trigger INT0 on falling edge digitalWrite(laser, HIGH); } // the loop routine runs over and over again forever: void loop() { //make program do something digitalWrite(laser, HIGH); } //interrupt service routine for when the LDR is hit ISR(INT0_vect) { unsigned long hitMillis = millis(); //if there has been more than 5 seconds since the last hit if ((hitMillis - lastBlinkTime) > interval) { lastBlinkTime = hitMillis; //increment score score = score + scoreFront; Serial.println("Hit Interrupt"); Serial.println(score); } }Running this code, when the LDR is hit, the ISR is called and "Hit Interrupt" along with a score is printed, for example 10 for the first hit. When the user tries to hit the LDR again, nothing happens until 5 seconds has passed. The user hits the LDR again and now the Arduino prints out "Hit Interrupt" with a score, now equal to 20. This concludes the code that is needed for laser detection.
I DO HAVE SOME THINGS TO HELP WITH THIS KIND OF PROJECT
ReplyDeletehttp://www.ebay.com/itm/140930389517?ssPageName=STRK:MESELX:IT&_trksid=p3984.m1555.l2649
http://www.ebay.com/itm/140928107140?ssPageName=STRK:MESELX:IT&_trksid=p3984.m1555.l2649
http://www.ebay.com/itm/140930389517?ssPageName=STRK:MESELX:IT&_trksid=p3984.m1555.l2649
Please provide circuit diagram
ReplyDeleteCool and I have a tremendous offer you: How To Budget House Renovation home remodeling companies near me
ReplyDelete