Many TVs and other equipment are controlled by infrared remotes. When you point the remote at the TV and press the channel-up button, it changes the channel for you. Pressing the button makes the remote flash a pattern of infrared light at the TV. Infrared light is not visible to humans, but the TV’s infrared receiver detects the flashing light pattern. The TV’s microcontroller decodes this pattern and uses that information to change the channel for you.
The infrared light (IR LED) and receiver work great as "flashlights" and "eyes" for your ActivityBot. The IR LEDs shine forward, and the IR receivers detect reflections off of nearby obstacles.
The Propeller microcontroller receives reflection data from the IR receivers and uses it to make navigation decisions. In this way, your ActivityBot can roam around obstacles without first bumping into them.
In this activity, you will build and test the infrared object sensor system to make sure they detect objects in front of the ActivityBot. Just like the whisker circuits, there is one on the right and one on the left so the ActivityBot can determine which way to turn in relation to the obstacle.
In this case, each side needs two electronic components: an LED that rapidly flashes infrared light, and an infrared receiver to detect a reflection of that infrared light bouncing off of objects nearby.
(2) IR LEDs
(2) IR receivers
(2) 1 k-ohm resistors (brown-black-red)
(2) 220-ohm resistors (red-red-brown)
To direct the IR LED’s light, just like a flashlight beam, you will use an IR LED standoff (longer tube) and shield (shorter tube).
Although the shield friction-fits into the standoff, it can be helpful to place a small piece of clear tape around the tube where they meet to hold them together securely. Make sure the tape does not extend beyond the end of the tube or cover the IR LED.
The IR LED’s cathodes are connected to D/A0 and D/A1. For object detection, the D/A outputs are set to 0 V = GND. Their voltage can be increased to make the IR LEDs dimmer, for closer range detection. (They can even be tested at different voltages, or levels of dimness, to get a rough idea of the object’s distance, but that's for another activity.)
*P14/P15 resistors are needed only for ActivityBot kits using External Encoders (#32500 [1]).
The test code displays the state of each IR detector: 1 = no infrared reflection detected, 0 = yes, infrared reflected from an object is detected.
It is essential to make sure that both IR detectors work correctly before continuing.
What the IR Sensors Can't See
Remember, the IR sensor system is looking for reflected infrared light. Shiny, light-colored objects reflect infrared light well, while dull, dark-colored objects absorb infrared light instead of reflecting it. So, if your IR sensors can't see your black shoes or a black plastic wastebasket, don't worry, that is normal.
First, the program makes I/O pins P26 and P27 output low (0 V). Not only does this turn off the P26 and P27 LEDs, but it also connects the D/A0 and D/A1 sockets to 0 V. The IR LED cathodes are connected to these sockets, using them for a ground connection. (We will explain why in a later activity.)
The rest of the code is inside a repeat forever loop. First, a frequency out block generates a 38000 Hz signal on P11, for 1 millisecond. P11 connects to an IR LED, causing it to strobe on/off very rapidly in a 1 ms burst.
This block is followed immediately by a check PIN block, which stores the input state of P10 in a variable named irLeft. P10 connects to the left IR receiver circuit. These IR receivers detect not just the presence of infrared light but are most sensitive to IR light that is strobing on/off very rapidly, at 38 kHz (38000 Hz). The IR detector sends a low signal (0 V) when a reflected 38 kHz IR signal is detected, and a high signal when no such signal is detected.
The process is duplicated for the right-side IR circuitry with another frequency PIN + check PIN block pair, storing the IR receiver's output in the irRight variable.
The next six lines should look familiar by now. The four Terminal print blocks display labels and values for the irLeft and irRight variables. A pause (ms) 150 block slows down the loop for optimal display. Finally, a Terminal clear screen block erases the old data before the next trip through the loop.
Infrared — It means “below red,” and it refers to the fact that the light’s frequency is below that of red on the color spectrum.
Filtering — The IR receiver has a filter built in that makes it look for infrared that flashes on/off 38000 times per second (38 kHz). This allows it to differentiate between infrared coming from the TV remote and other IR sources such as halogen and incandescent lamps as well as sunlight streaming in through a nearby window.
Sunlight — Even though the IR receiver filters for sunlight, direct sunlight can often swamp the IR LED’s signal. Try to keep it indoors and out of any sunlight streaming in through windows.
The P26 and P27 lines are currently in use providing 0 V to the IR LED cathodes, so you cannot use their LEDs for indicating the IR detector states like you did with whiskers. So, let’s build some LEDs on the breadboard for "object detected" indicators.
*P14/P15 resistors are only needed for ActivityBot kits using External Encoders (#32500 [1]).
Next, you will need to modify the code to turn a given light on if its IR receiver returns 0, or off if it returns 1.
If you have an infrared remote, you can further modify your IR detection code so that it sounds an alarm if it detects IR interference from the environment. This is a useful test to find out if nearby fluorescent lights or other devices are sending out signals that could affect your robot's behavior. The key is not to emit any infrared with the IR LEDs. If the receivers still send a low signal, there must be IR interference coming from another source.
If interference is detected, make the piezospeaker get your attention with a series of six 50 ms, 4 kHz chirps separated by six 50 ms pauses. You can use a TV remote to test this.
Now you can disconnect the robot from the computer and walk around your workspace. Try pointing your robot at different light sources. If you hear the beeping alarm, you know that a 38 kHz infrared signal is detected. The ballast on some styles of fluorescent tube lighting is notorious for causing this kind of IR interference.
With your IR object sensors built and tested, you are ready to make your ActivityBot roam and avoid obstacles without bumping into them.
The IR Roaming code example makes the ActivityBot go forward until it detects an obstacle. If it sees an obstacle on the left, it will turn right. Likewise, if it sees one on the right, it will turn left. And if it sees obstacles on both left and right, it will back up.
Remember, not all obstacles are visible to this infrared system.
Many dark colored objects will absorb infrared light instead of reflecting it. If in doubt, use your LED indicator program from the previous page. The red LEDs on the breadboard will show you if an object is visible to the IR object detectors.
Your ActivityBot should promptly turn away from your hand and roam in a different direction until it detects another obstacle.
The project begins with the now familiar frequency out block for the piezospeaker brownout alarm on P4. Next comes the required Robot ActivityBot initialize block, and a Robot set acceleration block. As we learned from previous projects, 600 ticks/s2 is a moderate acceleration value that works well with the Robot drive speed block's default value 64.
Remember that the make PIN...low blocks for P26 and P27 are needed to connect the IR LED cathodes to ground.
The rest of the code blocks are in a repeat forever loop. The next four blocks are the same as in the IR Detectors project. For each IR LED/Receiver pair, a frequency out block sends a 1 ms pulse of infrared light at 38 kHz; then a check PIN block immediately stores the IR receiver's response in a variable. The variables irLeft and irRight will each store a zero if that receiver detects an infrared reflection off of an object, and 1 if no object is detected. (Remember, the IR receivers are set up as active-low circuits.)
A single if...do block with four conditions and potential actions makes up the rest of the repeat forever loop. Those conditions check the combined state of the irLeft and irRight variables. The possible conditions are:
The conditions are tested one at a time in order. The first condition that is true runs the code in its ...do section, and then the program flow returns to the top of the repeat forever loop.
The first if... condition uses a boolean comparison block to test whether it is true that both irLeft and irRight variables are storing a 1. That means neither IR receiver detected an object, and the ActivityBot can drive forward with Robot drive speed left 64, right 64.
The second if... condition also uses a boolean comparison block to test whether it is true that both irLeft and irRight variables are storing a zero. That means both IR receivers detected an object, and the ActivityBot can back up with Robot drive speed left -64, right -64.
If the first two conditions get skipped, it must mean that the two variables are not storing the same value. So, the next two conditions test each variable alone to see if either one detects an object.
The third if... condition checks whether irLeft is storing a zero. That means an object is detected on the left, and the ActivityBot can turn right to avoid it with Robot drive speed left 64, right -64.
The fourth if... condition checks whether irRight storing a zero. That means the an object was detected on the right, and the ActivityBot can turn left to avoid it with Robot drive speed left -64, right 64.
Conserving Conditions — Since this project has only four possible conditions to check for, your if....do loop did not really need to test for the fourth. Logic tells us, if the first three conditions are false, the fourth condition must be true. So the last else...if in the if...do loop could have just been an else containing the Robot drive speed left -64, right 64 block.
Compact vs. Easy to Read — Using all four conditions is an example of building code so that it is easy to understand, rather than as short as it can possibly be. When you are first developing a project, it can be helpful to make the code as easy to understand as possible. Then save a copy, and work on making it more compact by eliminating blocks that are not necessary. However, if you will be sharing your code, or if it is a very complex project, it may be wiser to keep it readable.
Adding visible light feedback for the IR recivers can help you understand what is happening if your robot seems to behave in unexpected ways.
If your sensor input, light and motion output system logic is now working well, it's time to tune it for performance. Your goal is to get your ActivityBot navigating as rapidly as it can without running into objects or doing nose-wheelies.
Links
[1] https://www.parallax.com/product/32500