|
|
|
|
||||||||||||
|
The demo version of the PicBasic Pro compiler is limited to a maximum 31 lines of code. We can't compile programs as large or complex as the full version examples, but we can still get a lot of things accomplished even with this limitation. This example shows how to put together a basic infrared object detection & navigation system similar to the full version infrared navigation project shown HERE but staying within the 31 line limitation of the demo version Pro compiler. Operation is simple. Here's how it works.
1. Configure the 16F628 internal
hardware PWM for 40KHz [the internal bandpass frequency of the 40KHz IR
detector]. The idle [not receiving data] output state of the infrared detector module is logic 1 or +5V when no infrared energy modulated at 40KHz is detected, and logic 0 or ground when IR energy modulated at 40KHz is striking the face of the detector. Very simple, yet very effective. We use the internal hardware PWM feature of the PIC16F628 to generate the 40KHz carrier. The 40KHz carrier is applied to the anode side of each infrared LED. We then use two additional PortB I/O-pins connected to each infrared LED cathode side to control each LED. As shown below, when the 40KHz PWM carrier is on, logic 0 on PortB.0 will turn on the LED. Logic 1 on PortB.0 will turn off the LED. The C indicates the cathode lead of the LED. The A indicates the anode lead of the LED.
When PortB.0 is at ground, and the 40KHz carrier is on, the LED is on. When PortB.0 is high, the LED is off. Refer to the circuit in Figure #1 below for the complete schematic for both LEDs. Current Through The LED: The OED-EL-8L infrared LEDs supplied with each Micro-Bot have a typical forward voltage drop of 1.5V. We subtract this 1.5V from our operating voltage of 5V. This leaves us with 3.5V. We take 3.5V / 430Ω to find our peak current of 8.1mA. If we set our PWM duty-cycle to 20%, we then have an average current of 8.1mA x 20% for 1.6mA supplied to each LED. |
||||||||||||||
|
Detecting Objects:
Infrared Object Detection |
||||||||||||||
|
As shown above in the illustration, an object in the path of the IR beam will reflect the IR energy back onto the face of the infrared detector module. We simply turn on the PWM carrier, take the LED cathode low, and sample the output of the IR detector. A logic 0 indicates the IR energy is striking the detector, and an object is in our path. A logic 1 on the detectors output indicates there is no object present to reflect IR energy back onto the face of the detector. Simple enough..! This method of infrared object detection and navigation is simple, and inexpensive for robotics applications. |
||||||||||||||
|
Parts List:
|
||||||||||||||
|
|
||||||||||||||
|
Place two pieces of heat shrink over the both of the infrared LEDs as shown on the left LED in Figure #1a below. The end of each LED lens should slightly stick out from the heat shrink. We include the heat shrink pre-cut to simplify the process. The black heat shrink prevents IR energy from exiting the rear by covering the LED leads, and also keeps IR energy from spreading sideways, directing the IR beam forward. Since we'll be detecting the IR beams being reflected from objects, we want to concentrate the infrared energy in a forward direction. Note: Be careful not to overheat the LEDs during the process. Use a candle flame, cigarette lighter, or heat gun to slowly warm the heat shrink until it closes around the LED leads and lens as shown below on the left LED. Once you're finished applying the heat shrink, wire both infrared LEDs to PortB as shown above in figure #1 schematic.
|
||||||||||||||
|
Port Pins Used & Configuration:
|
||||||||||||||
|
|
||||||||||||||
|
Wire in the TSOP1740 infrared photo detector circuit shown in Figure #2. Place the infrared detector in the center area of the bread board or solder it to the center prototyping solder pads similar to this photo HERE. We have included a pin connection diagram of the TSOP1740 and other components HERE. Note: We have supplied the TSOP1740 IR detector module with Micro-Bot for enhanced serial communications. This particular detector module will work at baud rates up to 2400 bps, and provides better noise rejection than most off-the-shelf types. You'll notice our programming techniques here are quite a bit different than the full version code examples HERE for a similar project. With the full version compiler, we we're not restricted to 31 lines of code, and we had plenty of room to make our code easy to follow and understand. One of the real advantages of programming in BASIC is the ability to write, review, and quickly understand what task each line of code or sub-routine is taking care of. With BASIC we use commands that are very similar to the way we speak. Example: If the window = open, and it's cold outside, then shut the window. Now take a programming language like the PicBasic Pro compiler that's every bit as simple as this BASIC example, and you're on your way to programming the PIC microcontroller without a degree in rocket science, long hours in a classroom, and a ton of cash out of pocket. About The Demo Code: There are a few tricky parts here that were necessary to squeeze in enough functionality for infrared object detection, a little decision making, and the servo motor control loop. If you're new to PicBasic or microcontrollers in general, this example may look a bit intimidating, but hang in there, and we'll explain how it all works at the end. For now, see if you can figure it out without scrolling to the bottom. |
||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
|
How It Works: We'll break down the code here and explain each section.
Or we can simply use PULSOUT Left_Servo, ForwardLeft. Either way, it's much easier to look at your code and know what's happening. Much easier than using something like PULSOUT, Left_Servo, 800. You don't have to keep looking things up.
|
||||||||||||||
Left_Led VAR PortB.0 ' PortB.0 = left IRLED output |
||||||||||||||
|
Our main routine Begin is shown below. This is where code execution begins, and it's also the routine we jump back to each time to begin everything over after moving servos forward or backwards. The first line in Begin writes a value of 12 to the CCP1CON register. CCP1CON is the hardware Capture/Compare/PWM configuration register. Writing a value of 12 to CCP1CON sets the Mode Select bits to use PWM, and turns it on. Writing a value of 0 to CCP1CON turns off hardware PWM. Notice in the start we write 12 to CCP1CON to turn on PWM, and at the end, after sampling the IR detector output, we write 0 to CCP1CON to turn hardware PWM back off. Hardware PWM consumes a lot of power, and when not in use, we simply turn it back off. We only need PWM on to generate the carrier frequency while driving the infrared LEDs during the object detection section of our code.
|
||||||||||||||
| With hardware PWM now turned on, we simply take each LED cathode to ground by making a port pin low. LOW Left_LED sets PortB.0 to ground, and turns on the left IR LED. The short pause time after turning on each LED allows time for the infrared detector to respond to the reflected infrared light. After the 10mS pause, we sample & record the output logic state of the infrared detector while the LED is on. This value is recorded in Hits[0] for the left LED, and Hits[1] for the right LED. | ||||||||||||||
|
Notice that we don't use HIGH
Left_LED to turn the LED back off. This would require two lines of code. One
HIGH Left_LED followed by one LOW Right_LED to turn on the
right infrared LED. We do both in a single line using PortB=%00000001. This
sets PortB.0 to 1 turning the left LED off, and PortB.1 to 0 turning the
right LED on, and saves us 1 valuable line of code space. As mentioned previously, after checking for an object on both sides, we turn hardware PWM back off until it's needed again by writing 0 to CCP1CON. |
||||||||||||||
|
Now For The Tricky Part:
Here's where it gets interesting. As shown above, we're using a mere four lines of code to find which side objects were detected on, and then decide which way to make Micro-Bot turn to avoid these obstacles if present. Since we don't have the luxury of making our code longer and easier to understand with the demo version compiler, we just have to get a little more creative. Remember, when an object is detected, the infrared detectors output pin will be at logic 0. When nothing reflects the LEDs infrared energy back onto the detector, its logic state will be 1 indicating no object detected. Any bit in the Hits bit array that is logic 1 indicates there was no object when the bit was recorded. A bit holding a logic 0 indicates there was an object in the path when the bit was recorded. Hence, 1=No, 0=Yes, and we have a simple method of checking which direction we need to make Micro-Bot turn to avoid hitting obstacles in its path. Hits[0] records the output logic
state of the IR detector module when the left LED is on. As shown before, we used a few constants to declare our motor directions like this;
We split the word variable MotorDir into two separate byte sized portions. The high byte contains $3C or 3C hex. The lower byte contains $50 or 50 hex. Notice how $3C = 60d or 60 decimal, and $50 = 80d or 80 decimal. The high byte or MotorDir.HighByte holds the right servo direction value. The low byte or MotorDir.LowByte holds the left servo direction value. Example:
This gives us 600 for forward motion of the right servo, and 800 for forward motion of the left servo after we multiply each byte value by a factor of 10, as shown below.
|
||||||||||||||
|
Copyright © 2007
Reynolds Electronics |
||||||||||||||