User Tools

Site Tools


tutorials:learn:sensors:ir.html

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
tutorials:learn:sensors:ir.html [2010/10/07 15:19]
daigo created
tutorials:learn:sensors:ir.html [2016/01/28 18:05] (current)
Line 1: Line 1:
 ====  ==== ====  ====
-[[../../​make/​logshield/​Documents/​ladyada_net-www/​ladyada_net-www/​images/​sensors/​pna4602.jpg|{{ http://​www.ladyada.net/​images/​sensors/​pna4602_t.jpg?​500x385 |}}]] +[[http://www.ladyada.net/​images/​sensors/​pna4602.jpg|{{ http://​www.ladyada.net/​images/​sensors/​pna4602_t.jpg?​nolink&500x385 |}}]] 
 ==== What is an IR detection sensor? ​ ==== ==== What is an IR detection sensor? ​ ====
  
Line 8: Line 8:
  
  
-There are a few difference between these and say a [[cds.html|CdS Photocells]]:​ \\ +There are a few difference between these and say a [[http://​www.ladyada.net/​learn/​sensors/​cds.html|CdS Photocells]]:​ \\ 
  
  
-  *IR detectors are specially filtered for Infrared light, they are not good at detecting visible light. On the other hand, [[cds.html|]] ​photocells are good at detecting yellow/​green visible light, not good at IR light+  *IR detectors are specially filtered for Infrared light, they are not good at detecting visible light. On the other hand, photocells are good at detecting yellow/​green visible light, not good at IR light
   *IR detectors have a **demodulator** inside that looks for modulated IR at 38 KHz. Just shining an IR LED wont be detected, it has to be PWM blinking at 38KHz. Photocells do not have any sort of demodulator and can detect any frequency (including DC) within the response speed of the photocell (which is about 1KHz)   *IR detectors have a **demodulator** inside that looks for modulated IR at 38 KHz. Just shining an IR LED wont be detected, it has to be PWM blinking at 38KHz. Photocells do not have any sort of demodulator and can detect any frequency (including DC) within the response speed of the photocell (which is about 1KHz)
   *IR detectors are digital out - either they detect 38KHz IR signal and output low (0V) or they do not detect any and output high (5V). Photocells act like resistors, the resistance changes depending on how much light they are exposed to   *IR detectors are digital out - either they detect 38KHz IR signal and output low (0V) or they do not detect any and output high (5V). Photocells act like resistors, the resistance changes depending on how much light they are exposed to
Line 18: Line 18:
  
  
-  *[[#test|Test your IR sensor to make sure its working]] +  *[[#testing_your_ir_detector|Test your IR sensor to make sure its working]] 
-  *[[#rawir|Read raw IR codes into a microcontroller]] +  *[[#ir_remote_signals|Read raw IR codes into a microcontroller]] 
-  *[[#intervalometer|Create a camera intervalometer]] +  *[[#making_an_intervalometer|Create a camera intervalometer]] 
-  *[[#ircommand|Listen for '​commands'​ from a remote control on your microcontroller]] ​+  *[[#reading_ir_commands|Listen for '​commands'​ from a remote control on your microcontroller]] ​ 
 ==== Some stats  ==== ==== Some stats  ====
  
Line 35: Line 36:
   ***[[http://​www.ladyada.net/​media/​sensors/​PNA4602.pdf|PNA4602 Datasheet]]** (now discontinued) or **[[http://​www.adafruit.com/​datasheets/​GP1UX31QS.pdf|GP1UX311QS]]** Datasheet (a pin-compatible replacement) ​   ***[[http://​www.ladyada.net/​media/​sensors/​PNA4602.pdf|PNA4602 Datasheet]]** (now discontinued) or **[[http://​www.adafruit.com/​datasheets/​GP1UX31QS.pdf|GP1UX311QS]]** Datasheet (a pin-compatible replacement) ​
 ==== What you can measure ​ ==== ==== What you can measure ​ ====
-{{  http://​www.ladyada.net/​images/​sensors/​irsensitive.gif?​559x430 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​irsensitive.gif?​nolink&559x430 ​ |}}
  
  
Line 47: Line 48:
  
 ==== Testing your IR detector ​ ==== ==== Testing your IR detector ​ ====
-{{  http://​www.ladyada.net/​images/​sensors/​pna4602pinout.gif?​391x441 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​pna4602pinout.gif?​nolink&391x441 ​ |}}
  
  
Line 64: Line 65:
 When the detector sees IR signal, it will pull the output low, turning on the LED - since the LED is red its much easier for us to see than IR! When the detector sees IR signal, it will pull the output low, turning on the LED - since the LED is red its much easier for us to see than IR!
  
-{{  http://​www.ladyada.net/​images/​sensors/​irremotetest.gif?​376x540 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​irremotetest.gif?​nolink&376x540 ​ |}}
  
  
Line 92: Line 93:
 Lets pretend we have a Sony remote, and we can look at exactly what light is being blasted out of the IR LED. We'll hookup a basic light sensor (like a basic photocell!) and listen in. We won't use a decoder like a PNA4602 (just yet) because we want to see the undecoded signal. What we see is the following: Lets pretend we have a Sony remote, and we can look at exactly what light is being blasted out of the IR LED. We'll hookup a basic light sensor (like a basic photocell!) and listen in. We won't use a decoder like a PNA4602 (just yet) because we want to see the undecoded signal. What we see is the following:
  
-{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepulses.JPG?​640x480 ​ |}}+{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepulses.JPG?​nolink&640x480 ​ |}}
  
 Basically we see pulses or IR signal. the yellow '​blocks'​ are when the IR LED is transmitting and when there is only a line, the IR LED is off. (Note that the voltage being at 3VDC is just because of the way I hooked up the sensor, if I had swapped the pullup for a pulldown it would be at ground.) Basically we see pulses or IR signal. the yellow '​blocks'​ are when the IR LED is transmitting and when there is only a line, the IR LED is off. (Note that the voltage being at 3VDC is just because of the way I hooked up the sensor, if I had swapped the pullup for a pulldown it would be at ground.)
Line 100: Line 101:
 If you zoom into one of those blocks... If you zoom into one of those blocks...
  
-{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepulsezoom.JPG?​640x480 ​ |}}+{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepulsezoom.JPG?​nolink&640x480 ​ |}}
  
 You see that they'​re not really '​blocks'​ but actually very fast pulses! You see that they'​re not really '​blocks'​ but actually very fast pulses!
Line 106: Line 107:
 If you zoom in all the way... If you zoom in all the way...
  
-{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepwm.JPG?​640x480 ​ |}}+{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepwm.JPG?​nolink&640x480 ​ |}}
  
 You can measure the frequency of the IR pulses. As you can tell by the cursors and the measurements on the side, the frequency is about 37.04KHz You can measure the frequency of the IR pulses. As you can tell by the cursors and the measurements on the side, the frequency is about 37.04KHz
Line 124: Line 125:
 Looking back at the first scope picture Looking back at the first scope picture
  
-{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepulses.JPG?​640x480 ​ |}}+{{  http://​www.ladyada.net/​images/​tvbgone/​sonycodepulses.JPG?​nolink&640x480 ​ |}}
  
 The first pulse is 2.5ms. We can use the cursors to measure the remaining pulses. I'll spare you the 12 images and let you know that the pulses are: \\  The first pulse is 2.5ms. We can use the cursors to measure the remaining pulses. I'll spare you the 12 images and let you know that the pulses are: \\ 
Line 147: Line 148:
  
 ==== Reading out IR codes from an Arduino ​ ==== ==== Reading out IR codes from an Arduino ​ ====
-{{  http://​www.ladyada.net/​images/​sensors/​arduinopna4602.gif?​618x416 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​arduinopna4602.gif?​nolink&618x416 ​ |}}
  
-The good news is that it is very easy to hook up this sensor. ​ Just connect the output to a digital pin. The bad news is that the Arduino'​s friendly **digitalRead()** procedure is a tad too slow to reliably read the fast signal as its coming in. Thus we use the hardware pin reading function directly from pin D2, thats what the line IRpin_PIN & (1 << ​IRpin)does. ​+The good news is that it is very easy to hook up this sensor. ​ Just connect the output to a digital pin. The bad news is that the Arduino'​s friendly **digitalRead()** procedure is a tad too slow to reliably read the fast signal as its coming in. Thus we use the hardware pin reading function directly from pin D2, thats what the line "IRpin_PIN & BV(IRpin))" ​does. 
  
 [[http://​github.com/​adafruit/​Raw-IR-decoder-for-Arduino|You can also get the latest version of this code on github]]<​code C> [[http://​github.com/​adafruit/​Raw-IR-decoder-for-Arduino|You can also get the latest version of this code on github]]<​code C>
 +
 /* Raw IR decoder sketch! /* Raw IR decoder sketch!
  
Line 196: Line 198:
   ​   ​
 //  while (digitalRead(IRpin)) { // this is too slow! //  while (digitalRead(IRpin)) { // this is too slow!
-    while (IRpin_PIN & (1 << ​IRpin)) {+    while (IRpin_PIN & _BV(IRpin)) {
      // pin is still HIGH      // pin is still HIGH
  
Line 241: Line 243:
   }   }
 } }
- 
 </​code>​ </​code>​
  
-If you run this while pointing a Sony IR remote and pressing the ON button you will get the following {{  http://​www.ladyada.net/​images/​sensors/​sonyread.gif?​472x405 ​ |}}+If you run this while pointing a Sony IR remote and pressing the ON button you will get the following {{  http://​www.ladyada.net/​images/​sensors/​sonyread.gif?​nolink&472x405 ​ |}}
  
 If you ignore the first OFF pulse (its just the time from when the Arduino turned on to the first IR signal received) and the last ON pulse (it the beginning of the next code) you'll find the Sony power code: If you ignore the first OFF pulse (its just the time from when the Arduino turned on to the first IR signal received) and the last ON pulse (it the beginning of the next code) you'll find the Sony power code:
Line 263: Line 264:
  
 ==== Making an Intervalometer ​ ==== ==== Making an Intervalometer ​ ====
-[[http://​www.ladyada.net/​images/​sensors/​invervalcam.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​invervalcam_t.jpg?​500x374 ​ |}}]]+[[http://​www.ladyada.net/​images/​sensors/​invervalcam.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​invervalcam_t.jpg?​nolink&500x374 ​ |}}]]
  
  
Line 269: Line 270:
 OK now that we can read IR codes, lets make a basic project. The first one we will do is to make an intervalometer. An intervalometer is basically a electronic thingy that makes a camera go off every few minutes or so. This can be used for timelapse projects or kite arial photography or other photo projects. The camera we'll be using has an IR remote you can use to set it off (most higher-end cameras have these). ​ OK now that we can read IR codes, lets make a basic project. The first one we will do is to make an intervalometer. An intervalometer is basically a electronic thingy that makes a camera go off every few minutes or so. This can be used for timelapse projects or kite arial photography or other photo projects. The camera we'll be using has an IR remote you can use to set it off (most higher-end cameras have these). ​
  
-[[http://​www.ladyada.net/​images/​sensors/​canonremote.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​canonremote_t.jpg?​500x383 ​ |}}]]+[[http://​www.ladyada.net/​images/​sensors/​canonremote.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​canonremote_t.jpg?​nolink&500x383 ​ |}}]]
  
  
Line 277: Line 278:
  
  
-OK step one is easy, point the remote control at the IR sensor and press the button, we got the following for our ML-L3 Canon remote+OK step one is easy, point the remote control at the IR sensor and press the button, we got the following for our ML-L3 Nikon remote
  
-{{  http://​www.ladyada.net/​images/​sensors/​canonirread.gif?​385x307 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​canonirread.gif?​nolink&385x307 ​ |}}
  
  
Line 313: Line 314:
 Next up we'll need to connect an IR 940nm LED to the output of the Arduino Next up we'll need to connect an IR 940nm LED to the output of the Arduino
  
-{{  http://​www.ladyada.net/​images/​sensors/​intervalometer.gif?​499x415 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​intervalometer.gif?​nolink&499x415 ​ |}}
  
 Then we'll write a sketch which will pulse pin #13 on and off very fast in the proper code sequence Then we'll write a sketch which will pulse pin #13 on and off very fast in the proper code sequence
 +
  
 <code C> <code C>
-// This sketch will send out a canon D50 trigger signal (probably works with most canons)+// This sketch will send out a Nikon D50 trigger signal (probably works with most Nikons)
 // See the full tutorial at http://​www.ladyada.net/​learn/​sensors/​ir.html // See the full tutorial at http://​www.ladyada.net/​learn/​sensors/​ir.html
 // this code is public domain, please enjoy! // this code is public domain, please enjoy!
Line 337: Line 339:
   Serial.println("​Sending IR signal"​);​   Serial.println("​Sending IR signal"​);​
   ​   ​
-  ​SendCanonCode();+  ​SendNikonCode();
  
   delay(60*1000); ​ // wait one minute (60 seconds * 1000 milliseconds)   delay(60*1000); ​ // wait one minute (60 seconds * 1000 milliseconds)
Line 363: Line 365:
 } }
  
-void SendCanonCode() { +void SendNikonCode() { 
-  // This is the code for my particular ​Canon, for others use the tutorial+  // This is the code for my particular ​Nikon, for others use the tutorial
   // to '​grab'​ the proper code from the remote   // to '​grab'​ the proper code from the remote
   ​   ​
Line 392: Line 394:
  
  
-If you look at     SendCanonCode() you will see the IR command code that we deduced in the previous project by timing the pulses from the IR sensor. ​+If you look at     SendNikonCode() you will see the IR command code that we deduced in the previous project by timing the pulses from the IR sensor. ​
  
-[[http://​www.ladyada.net/​images/​sensors/​intervalometer.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​intervalometer_t.jpg?​500x463 ​ |}}]]+[[http://​www.ladyada.net/​images/​sensors/​intervalometer.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​intervalometer_t.jpg?​nolink&500x463 ​ |}}]]
  
  
Line 410: Line 412:
 For a remote in this example we'll be using an Apple clicker remote. You can use any kind of remote you wish, or you can steal one of these from an unsuspecting hipster. For a remote in this example we'll be using an Apple clicker remote. You can use any kind of remote you wish, or you can steal one of these from an unsuspecting hipster.
  
-[[http://​www.ladyada.net/​images/​sensors/​appleremote.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​appleremote_t.jpg?​500x250 ​ |}}]]+[[http://​www.ladyada.net/​images/​sensors/​appleremote.jpg|{{ ​ http://​www.ladyada.net/​images/​sensors/​appleremote_t.jpg?​nolink&500x250 ​ |}}]]
  
  
Line 446: Line 448:
 I uploaded the new sketch and pressed the **Play** button on the Apple remote and got the following: I uploaded the new sketch and pressed the **Play** button on the Apple remote and got the following:
  
-<p class="​codefragment"​>int IRsignal[] = { \\ // ON, OFF (in 10's of microseconds) ​\\ 912, 438, \\ 68, 48, \\ 68, 158, \\ 68, 158, \\ 68, 158, \\ 68, 48, \\ 68, 158, \\ 68, 158, \\ 68, 158, \\ 70, 156, \\ 70, 158, \\ 68, 158, \\ 68, 48, \\ 68, 46, \\ 70, 46, \\ 68, 46, \\ 68, 160, \\ 68, 158, \\ 70, 46, \\ 68, 158, \\ 68, 46, \\ 70, 46, \\ 68, 48, \\ 68, 46, \\ 68, 48, \\ 66, 48, \\ 68, 48, \\ 66, 160, \\ 66, 50, \\ 66, 160, \\ 66, 52, \\ 64, 160, \\ 66, 48, \\ 66, 3950, \\ 908, 214, \\ 66, 3012, \\ 908, 212, \\ 68, 0};+<code> 
 +int IRsignal[] = { // ON, OFF (in 10's of microseconds) ​ 
 +912, 438,  
 +68, 48,  
 +68, 158,  
 +68, 158,  
 +68, 158,  
 +68, 48,  
 +68, 158,   
 +68, 158,   
 +68, 158,   
 +70, 156,   
 +70, 158,   
 +68, 158,   
 +68, 48,  
 +68, 46,   
 +70, 46,   
 +68, 46,   
 +68, 160,   
 +68, 158,   
 +70, 46,   
 +68, 158,   
 +68, 46,   
 +70, 46, 
 +68, 48,   
 +68, 46,   
 +68, 48,   
 +66, 48,   
 +68, 48,   
 +66, 160,   
 +66, 50,   
 +66, 160,   
 +66, 52,   
 +64, 160,  
 +66, 48,   
 +66, 3950,   
 +908, 214,  
 +66, 3012,  
 +908, 212,  
 +68, 0}; 
 +</​code>​ 
  
  
  
 We'll try to detect that code. Lets start a new sketch called **IR Commander [[http://​github.com/​adafruit/​IR-Commander|(you can download the final code from github) ]]** this will use parts of our previous sketch. The first part we'll do is to create a function that just listens for an IR code an puts the pulse timings into the **pulses[]** array. It will return the number of pulses it heard as a return-value. We'll try to detect that code. Lets start a new sketch called **IR Commander [[http://​github.com/​adafruit/​IR-Commander|(you can download the final code from github) ]]** this will use parts of our previous sketch. The first part we'll do is to create a function that just listens for an IR code an puts the pulse timings into the **pulses[]** array. It will return the number of pulses it heard as a return-value.
- 
  
 <code C> <code C>
 +
 int listenForIR(void) { int listenForIR(void) {
   currentpulse = 0;   currentpulse = 0;
Line 512: Line 555:
 </​code>​ </​code>​
  
-When we run this it will print out something like{{ ​ http://​www.ladyada.net/​images/​sensors/​pulsecounter.gif?​358x193 ​ |}}+When we run this it will print out something like{{ ​ http://​www.ladyada.net/​images/​sensors/​pulsecounter.gif?​nolink&358x193 ​ |}}
  
  
Line 518: Line 561:
 OK time to make the sketch compare what we received to what we have in our stored array: OK time to make the sketch compare what we received to what we have in our stored array:
  
-{{  http://​www.ladyada.net/​images/​sensors/​ircompare.gif?​427x688 ​ |}}+{{  http://​www.ladyada.net/​images/​sensors/​ircompare.gif?​nolink&427x688 ​ |}}
  
  
  
 As you can see, there is some variation. So when we do our comparison we can't look for preciesely the same values, we have to be a little '​fuzzy'​. We'll say that the values can vary by 20% - that should be good enough As you can see, there is some variation. So when we do our comparison we can't look for preciesely the same values, we have to be a little '​fuzzy'​. We'll say that the values can vary by 20% - that should be good enough
 +
  
 <code C> <code C>
Line 566: Line 610:
 } }
  
-</​code> ​   {{  http://​www.ladyada.net/​images/​sensors/​codecompareok.gif?​414x700 ​ |}}+</​code> ​   {{  http://​www.ladyada.net/​images/​sensors/​codecompareok.gif?​nolink&414x700 ​ |}}
  
 This loop, as it goes through each pulse, does a little math. It compares the absolute (**abs()**) difference between the code we heard and the code we're trying to match  abs(oncode - ApplePlaySignal[i*2 + 0]) and then makes sure that the error is less than FUZZINESS percent of the code length (oncode * FUZZINESS / 100) This loop, as it goes through each pulse, does a little math. It compares the absolute (**abs()**) difference between the code we heard and the code we're trying to match  abs(oncode - ApplePlaySignal[i*2 + 0]) and then makes sure that the error is less than FUZZINESS percent of the code length (oncode * FUZZINESS / 100)
Line 650: Line 694:
 We check against all the codes we know about and print out whenever we get a match. You could now take this code and turn it into something else, like a robot that moves depending on what button is pressed. ​ We check against all the codes we know about and print out whenever we get a match. You could now take this code and turn it into something else, like a robot that moves depending on what button is pressed. ​
  
-After testing, success!{{ ​ http://​www.ladyada.net/​images/​sensors/​mulitirbutton.gif?​403x355 ​ |}} \\ +After testing, success!{{ ​ http://​www.ladyada.net/​images/​sensors/​mulitirbutton.gif?​nolink&403x355 ​ |}} 
/home/ladyada/public_html/wiki/data/attic/tutorials/learn/sensors/ir.html.1286464797.txt.gz · Last modified: 2016/01/28 18:05 (external edit)