Object Detection Test Code

Object Detection Test Code

Your BOE Shield-Bot’s infrared receivers are designed to detect infrared light (in the 980 nanometer range) flashing at a rate near 38 kHz.  To make the IR LED turn on/off at that rate,  we can use the familiar tone function that makes the speaker beep at the beginning of each sketch. 

Infrared detection takes three steps:

  1. Flash the IR LED on/off at 38 kHz.
  2. Delay for a millisecond or more to give the IR receiver time to send a low signal in response to sensing 38 kHz IR light reflecting off an object. 
  3. Check the state of the IR receiver for either a high signal (no IR detected), or a low signal (IR detected). 

Here is an example of the three steps applied to the left IR LED (pin 9) and IR receiver (pin 10). 

  tone(9, 38000, 8);                // IRLED 38 kHz for at least 1 ms
  delay(1);                         // Wait 1 ms
  int ir = digitalRead(10);         // IR receiver -> ir variable

The tone actually lasts about 1.1 ms.  Even though we would expect tone(9, 38000, 8) to generate a 38 kHz signal for 8 ms, the signal actually only lasts for about 1.1 ms as of Arduino software v1.0.  Given the name tone, the function may have been designed for and tested with audible tones.  If played on a speaker, a 38 kHz tone will not be audible.  It’s in the ultrasonic range, meaning it’s pitch is so high that it’s above the audible range for humans, which is about 20 Hz to 20 kHz.

The tone function generates a square wave that repeats its high/low cycle 38000 times per second.  Through experimentation with Arduino software v1.0, the author discovered that a call to tone with a duration of 8 ms resulted in a 38 kHz square wave that lasted about 1.1 ms.  . 

Remember that the tone function does its processing in the background.  Since the IR receiver needs a few tenths of a millisecond to respond to the 38 kHz signal, delay(1) prevents the ir = digitalRead(10) call from copying the IR receiver’s output until it’s ready.

The next sketch defines a function named irDetect with three parameters: one to specifiy the IR LED pin, one to specify the IR receiver pin, and one to set the frequency for flashing the IR LED.

  int irDetect(int irLedPin, int irReceiverPin, long frequency)

In the loop function you’ll see a call to irDetect:

  int irLeft = irDetect(9, 10, 38000);       // Check for object

This call passes 9 to the irLedPin parameter, 10 to irReceiverPin, and 38000 to the frequency parameter.  The function performs those three steps for infrared detection and returns 1 if no object is detected, or 0 if an object is detected.  That return value gets stored in irLeft.

Example Sketch: TestLeftIr

This sketch only tests the BOE Shield-Bot’s left IR detector.  This helps simplify trouble-shooting because you are focusing on only one of the two circuits.  This is yet another example of subsystem testing.  After the subsystems check out, we can move to system integration.  But first, you’ve got to make sure to test and correct any wiring or code entry errors that might have crept in.

Serial Monitor output of IR detector test - 0 means object detected, 1 means no object detected

  • Reconnect the battery pack to the Arduino.
  • Set the 3-position switch to position 1.
  • Enter, save, and upload the sketch TestLeftIr to your Arduino.
/*
 * Robotics with the BOE Shield - TestLeftIR
 * Display 1 if the left IR detector does not detect an object,
 * or 0 if it does.
 */

void setup()                                 // Built-in initialization block
{
  tone(4, 3000, 1000);                       // Play tone for 1 second
  delay(1000);                               // Delay to finish tone

  pinMode(10, INPUT);  pinMode(9, OUTPUT);   // Left IR LED & Receiver

  Serial.begin(9600);                        // Set data rate to 9600 bps
}  
 
void loop()                                  // Main loop auto-repeats
{
  int irLeft = irDetect(9, 10, 38000);       // Check for object

  Serial.println(irLeft);                    // Display 1/0 no detect/detect

  delay(100);                                // 0.1 second delay
}

// IR Object Detection Function

int irDetect(int irLedPin, int irReceiverPin, long frequency)
{
  tone(irLedPin, frequency, 8);              // IRLED 38 kHz for at least 1 ms
  delay(1);                                  // Wait 1 ms
  int ir = digitalRead(irReceiverPin);       // IR receiver -> ir variable
  delay(1);                                  // Down time before recheck
  return ir;                                 // Return 1 no detect, 0 detect
}  

  • Leave the BOE Shield-Bot connected to its programming cable,  and open the Serial Monitor when the sketch is done uploading.
  • Place an object, such as your hand or a sheet of paper, about an inch (2 to 3 cm) from the left IR object detector.
  • Verify that the Serial Monitor displays a 0 when you place an object in front of the IR object detector, and a 1 when you remove the object.
  • If the Serial Monitor displays the expected values for object not detected (1) and object detected (0), move on to the Your Turn section. 
  • If the Serial Monitor displays the expected values, go ahead and test the right IR Object Detector (below).  If not, go to the Troubleshooting section for help.

Your Turn – Test the Right IR Object Detector

Modifying the sketch to test the right IR object detector is a matter of replacing irLeft with irRight, and passing the correct pin numbers to the irDetect parameters to test the other circuit. Here’s a checklist of the changes:

  • Save the sketch TestLeftIr as TestRightIr.
  • Change pinMode(10, INPUT);  pinMode(9, OUTPUT) to pinMode(3, INPUT);  pinMode(2, OUTPUT).
  • Change int irLeft = irDetect(9, 10, 38000) to int irRight = irDetect(2, 3, 38000).
  • Change Serial.println(irLeft) to Serial.println(irRight).
  • Repeat the testing steps in this activity for the BOE Shield-Bot’s right IR object detector.  
  • If necessary, trouble-shoot any circuit or code entry errors.