Robotics with the BOE Shield-Bot for Arduino by Andy Lindsay Version 1.
WARRANTY Parallax warrants its products against defects in materials and workmanship for a period of 90 days from receipt of product. If you discover a defect, Parallax will, at its option, repair or replace the merchandise, or refund the purchase price. Before returning the product to Parallax, call for a Return Merchandise Authorization (RMA) number. Write the RMA number on the outside of the box used to return the merchandise to Parallax.
About This Tutorial ....................................................................................................................... 6 About This Edition ........................................................................................................................ 6 Why Study Robotics? .................................................................................................................... 6 A Bit of Background .....................................................................
Activity 2: Re-Test the Servos ..................................................................................................... 85 Activity 3: Start-Reset Indicator .................................................................................................. 89 Activity 4: Test Speed Control ..................................................................................................... 93 Chapter 3 Summary ......................................................................................
Chapter 6 Summary .................................................................................................................. 209 Chapter 6 Challenges ................................................................................................................ 210 Chapter 7. Navigating with Infrared Headlights ........................................... 216 Infrared Light Signals ................................................................................................................
About This Tutorial New to robotics? No problem! The activities and projects in this text start with an introduction to the BOE Shield-Bot’s brain, the Arduino® Uno. Next, you will build, test, and calibrate the BOE Shield-Bot. Then, you will learn to program the BOE Shield-Bot for basic maneuvers. After that, you’ll be ready to add different kinds of sensors, and write sketches to make the BOE Shield-Bot sense its environment and respond on its own.
A Bit of Background The BOE Shield-Bot is a small microcontroller development platform on wheels. It is designed for experimenting with circuit-building and programming, using standard electronic components. Board of Education ShieldBot with Arduino Uno brain It is a variation of the original Boe-Bot® robot with its BASIC Stamp® 2 brain, shown below. It was introduced by Parallax Inc.
Audience & Support This book is designed to promote technology literacy through an easy introduction to microcontroller programming and simple robotics. Are you a middle-school student? You can be successful by following the check-marked instructions with your teacher’s support.
Your Shield-Bot’s Brain • Chapter 1 Chapter 1. Your Shield-Bot's Brain Parallax Inc.’s BOE Shield-Bot robot is the focus of the activities and projects in this book. The robot’s Board of Education Shield mounts on a metal chassis along with servo motors, wheels, and a battery pack. An Arduino Uno module—the programmable brain—plugs in underneath the BOE Shield.
Chapter 1 • Your Shield-Bot’s Brain Arduino Module Options The Arduino Uno is the preferred module for the Shield-Bot robot. This tutorial was also tested with a Duemilanove and original Mega. These Arduino modules automatically decide whether to draw power from USB or an external source (like the Shield-Bot’s battery pack). Older Arduino Models are not guaranteed to work. If you have one, you may have to set its power selection jumper. (Don’t worry about this if you have an Uno, Duemilanove, or Mega.
Your Shield-Bot’s Brain • Chapter 1 Check Your Hardware Before continuing, is a good idea to make sure you have all of the correct parts to build and program your Shield-Bot. Use the pictures and part numbers on the following pages to double-check the robot chassis parts, small hardware, and electronic components. If you need anything, contact sales@parallax.com. (Kit parts and quantities subject to change without notice). Arduino Uno module (#32330).
Chapter 1 • Your Shield-Bot’s Brain Shield-Bot Chassis Parts In Chapter 3, you will build your Shield-Bot on an aluminum chassis. It will use 5 AA batteries for a power supply. 5-cell AA battery holder with barrel plug (#753-00007) aluminum chassis (#700-00022) Wheels will connect to servo motors to drive the Shield-Bot, and a tail wheel ball will attach to the chassis with a cotter pin. Note that the wheel and tire styles have changed over time. Yours may look different; that's okay.
Your Shield-Bot’s Brain • Chapter 1 Shield-Bot Hardware A bag of hardware supplies everything you will need to assemble your robot in Chapter 3, shown below. There will be some spare parts left over and not pictured— that is okay! Note that both regular nuts and Nylon-core lock-nuts are provided; you may choose to use either one. Replacement Robot Hardware Refresher Packs (#570-35000) are also sold separately.
Chapter 1 • Your Shield-Bot’s Brain Shield-Bot Electronics Parts A bag of electronic components is included with your kit, pictured on the next two pages (though parts and quantities are subject to change without notice.) You will use these parts to build circuits in almost every chapter of this book. These parts are available as the BoeBot and Shield-Bot Refresher Pack (#572-28132). Your Infrared Receivers may look different, since suppliers change over time.
Your Shield-Bot’s Brain • Chapter 1 (2) LEDs, infrared (#350-00003) (2) bags of 3” jumper wires (#800-00016) (2) LED standoffs (#350-90000, use with #350-90001) -or(2) LED shield bases (#350-90004, use with #350-90005) (2) 3-pin male-male headers (#451-00303) (2) tact switches, normally-open pushbuttons (#710-00007) (2) LED light shields (#350-90001, use with #350-90000) -or(2) LED shield caps (#350-90005, use with #350-90004) (1) piezospeaker (#900-000101) (2) whisker wires (#700-00056) (2) 0.
Chapter 1 • Your Shield-Bot’s Brain Activity 1: Download Example Sketches and Software Arduino programs are called sketches. All the example sketches in this book can be downloaded from http://learn.parallax.com/shieldrobot. But, if you type them in yourself, you will develop your programming skills faster! Getting Started with the Arduino IDE Software Arduino IDE software and drivers install on your Windows, Mac, or Linux computer. You do not need to be online to use it. Go to www.arduino.
Your Shield-Bot’s Brain • Chapter 1 Activity 2: Write a Simple "Hello!" Sketch Let's start programming! If you are using Arduino IDE, continue below. If you are using codebender : edu, turn to Try it with codebender : edu on page 19. Try It with Arduino IDE Software Here is a screen capture of the Arduino Development Environment. The edit pane contains a simple program, called a sketch, that sends a “Hello!” message to the Serial Monitor window on the right.
Chapter 1 • Your Shield-Bot’s Brain Open your Arduino software and carefully type in the code: void setup() { Serial.begin(9600); Serial.print("Hello!"); } void loop() { //Add code that repeats automatically here. } Be sure you have capitalized “Serial” both times, or the sketch won’t work. Also, notice in the figure that the sketch uses parentheses() and curly braces {}.
Your Shield-Bot’s Brain • Chapter 1 Try it with codebender : edu If you've never used codebender : edu before, take the time to register for a new account. If you are a student, your instructor may have already registered for your class, and would supply a link for your class to share. Take a look at the screen capture of the codebender : edu environment and its Serial Monitor on the next page.
Chapter 1 • Your Shield-Bot’s Brain Choose Open from this menu to re-open your sketch. Or, navigate to the unzipped example code archive you downloaded previously to open sketches used in this book.
Your Shield-Bot’s Brain • Chapter 1 Serial.print(val); passes the message “Hello!” to the val parameter. This tells the Arduino to send a series of binary ones and zeros to the Serial Monitor. The monitor decodes and displays that serial bitstream as the “Hello!” message. setup function Function definition Code block contained in curly braces { } void setup() { Serial.begin(9600); Serial.
Chapter 1 • Your Shield-Bot’s Brain Modify the Sketch to Repeat Microcontroller programs generally run in a loop, meaning that one or more statements are repeated over and over again. Remember that the loop function automatically repeats any code in its block (the statements in between its curly braces). Let’s try moving Serial.print("Hello!"); to the loop function. To slow down the rate at which the messages repeat, let’s also add a pause with the built-in delay(ms) function.
Your Shield-Bot’s Brain • Chapter 1 Save HelloMessage as HelloRepeated. Move Serial.print("Hello!"); from setup to the loop function. Add delay(1000); on the next line. Compare your changes to the figure and verify that they are correct. Run the sketch on the Arduino and then open the Serial Monitor again. The added line delay(1000) passes the value 1000 to the delay function’s ms parameter. It’s requesting a delay of 1000 milliseconds. 1 ms is 1/1000 of a second.
Chapter 1 • Your Shield-Bot’s Brain Open the Arduino Reference Still have questions? Try the Arduino Language Reference. It’s a set of pages with links you can follow to learn more about setup, loop, print, println, delay, and lots of other functions you can use in your sketches. If you are using the Arduino IDE, click Help and select Reference. If you are using codebender : edu, go to the following web address: https://www.arduino.
Your Shield-Bot’s Brain • Chapter 1 Serial.println(a); Serial.println(c); Serial.println(root2); One nice thing about variable types is that Serial.println recognizes each type and displays it correctly in the Serial Monitor. (Also, the C++ compiler in the Arduino software requires all declared variables to have a type, so you can’t leave it out.) Example Sketch – StoreRetrieveLocal Create a new sketch, and save it as StoreRetrieveLocal.
Chapter 1 • Your Shield-Bot’s Brain See that 'm' really is 109! There are two ways to prove that the ASCII code for 'm' really is 109. First, instead of declaring char c = 'm', you could use byte c = 'm'. Then, the println function will print the byte variable’s decimal value instead of the character it represents. Or, you could leave the char c declaration alone and instead use Serial.println(c, DEC) to display the decimal value c stores. Try both approaches.
Your Shield-Bot’s Brain • Chapter 1 a = 42; c = 'm'; root2 = sqrt(2.0); } void loop() { Serial.println(a); Serial.println(c); Serial.println(root2); delay(1000); } Your Turn – More Data Types There are lots more data types than just int, char, float, and byte. Open the Arduino Language Reference, and check out the Data Types list. Follow the float link and learn more about this data type. The long data type will be used in a later chapter; open both the long and int sections.
Chapter 1 • Your Shield-Bot’s Brain Create, save, and run SimpleMath on your Arduino. Check the result in the Serial Monitor. Is it correct? // Robotics with the BOE Shield - SimpleMath void setup() { Serial.begin(9600); int a = 89; int b = 42; int c = a + b; Serial.print("a + b = "); Serial.println(c); } void loop() { // Empty, no repeating code. } Fit your variables to the result values you need to store.
Your Shield-Bot’s Brain • Chapter 1 r, where r is the circle’s radius and π ≈ 3.14159. This calculation would be a lot easier to do with floating point math. Here is a snippet of code that gets the job done. Notice that it uses PI instead of 3.14159. PI is a built-in C language constant (a named value that does not change throughout the sketch). Also notice that all the values have decimal points. That makes them all floating-point values. float r = 0.75; float c = 2.
Chapter 1 • Your Shield-Bot’s Brain Activity 5: Make Decisions Your BOE Shield-Bot will need to make a lot of navigation decisions based on sensor inputs. Here is a simple sketch that demonstrates decision-making. It compares the value of a to b, and sends a message to tell you whether or not a is greater than b, with an if…else statement. If the condition (a > b) is true, it executes the if statement’s code block: Serial.print("a is greater than b").
Your Shield-Bot’s Brain • Chapter 1 void setup() { Serial.begin(9600); int a = 89; int b = 42; if(a > b) { Serial.print("a is greater than b"); } } Maybe your sketch needs to monitor for three conditions: greater than, less than, or equal. Then, you could use an if…else if…else statement. if(a > b) { Serial.print("a is greater than b"); } else if(a < b) { Serial.print("a is not greater than b"); } else { Serial.
Chapter 1 • Your Shield-Bot’s Brain if(a == b) { Serial.print("a and b are equal"); } Try these variations in a sketch. More conditions: You can chain more else if statements after the initial if. • The example in this activity only uses one else if, but you could use more. • The rest of the statement gets left behind after it finds a true condition. • If the if statement turns out to be true, its code block gets executed and the rest of the chain of else ifs gets passed by.
Your Shield-Bot’s Brain • Chapter 1 { // Empty, no repeating code. } How the for Loop Works The figure below shows the for loop from the last example sketch, CountTenTimes. It labels the three elements in the for loop’s parentheses that control how it counts. Condition (repeat again if true) Initialization (start value) Increment (step size) for(int i = 1; i <= 10; i++) { Serial.println(i); delay(500); } Initialization: the starting value for counting.
Chapter 1 • Your Shield-Bot’s Brain statement that follows the for loop’s code block. In this case, the condition is “if i is less than or equal to 10.” Increment: how to change the value of i for the next time through the loop. The expression i++ is equivalent to i = i + 1. It makes a nice shorthand approach for adding 1 to a variable. Notice that ++ comes after i, meaning “use i as-is this time through the function, and then increment it afterward.” This is the post increment use of the operator.
Your Shield-Bot’s Brain • Chapter 1 Want to condense your code a little? You can use the increment operator (++) to increase the value of i inside the Serial.println statement. Notice that ++ is on the left side of the i variable in the example below. When ++ is on the left of a variable, it adds 1 to the value of i before the println function executes. If you put ++ to the right, it would add 1 after println executes, so the display would start at zero. int i = 0; while(i < 10) { Serial.
Chapter 1 • Your Shield-Bot’s Brain Activity 7: Constants and Comments The next sketch, CountToTenDocumented, is different from CountToTen in several ways. First, it has a block comment at the top. A block comment starts with /* and ends with */, and you can write as many lines of notes in between as you want. Also, each line of code has a line comment (starting with // ) to its right, explaining what the code does.
Your Shield-Bot’s Brain • Chapter 1 • • Documented code can save you lots of time trying to remember what your code does, and how it does it, after you haven’t looked at it for a long time. In addition to making your code easier to read, constants allow you to adjust an often-used value quickly and accurately by updating a single constant declaration.
Chapter 1 • Your Shield-Bot’s Brain • • Using operators in if statements How to count and control repetitions with for and while loops Computer Skills • • • • What a baud rate is, and how to set it in your sketch and your Serial Monitor What ASCII characters are, and what they are used for Using your microcontroller’s language reference Why documenting code is important, and how to help make your code selfdocumenting Chapter 1 Challenges Questions 1. 2. 3. 4. 5. 6. 7. 8. 9.
Your Shield-Bot’s Brain • Chapter 1 Projects 1. 2. Write a sketch to display the printable ASCII characters. The first printable character is the space character, which is one press/release of your keyboard’s space bar between apostrophes, like this: ‘ ’. The last printable character is the tilde character ‘~’. Alternately, you could use 32 for the loop’s start value and 126 for the end value. Write a sketch that tells you if a variable is odd or even.
Chapter 1 • Your Shield-Bot’s Brain 3. Solution: 4. Solution: 5. Solution: 6. Solution: if(myVar % 2 == 0) { Serial.println("The variable is even. "); } else { Serial.println("The variable is odd. "); } for(int i = 21; i <= 39; i+=3) { Serial.print("i = "); Serial.println(i); } char c = "a"; Serial.print("Character = "); Serial.print(c); Serial.print(" ASCII value = "); Serial.println(c, DEC); for(char c = 'A'; c <='Z'; c++){} Project Solutions 1.
Your Shield-Bot’s Brain • Chapter 1 } Serial.println("All done!"); } void loop() { // Empty, no repeating code. } 2. This sketch is a modified version of SimpleDecisions that uses a variation of the solution from Exercise 3 to display whether the variable is odd or even. // Robotics with the BOE Shield - Chapter 1, Project 2 void setup() { Serial.begin(9600); int a = 20; if(a % 2 == 0) { Serial.print("a is even"); } else { Serial.print("a is odd"); } } void loop() { // Empty, no repeating code.
Chapter 2 • Shield, Lights, Servo Motors Chapter 2. Shield, Lights, Servo Motors In this chapter, you will use the Board of Education Shield for building and testing circuits with Parallax continuous rotation servos, resistors, and LED lights. Along the way, you’ll start learning the basics of building circuits and making the Arduino interact with them.
Shield, Lights, Servo Motors • Chapter 2 Parts List (1) (1) (4) (4) (3) (3) (3) Arduino module Board of Education Shield 1″ round aluminum standoffs pan head screws, 1/4″ 4-40 (metal, and rounded on top with a +) 1/2″ round Nylon spacers* Nylon nuts, 4-40* pan head screws, 7/8″, 4-40* (*Items also included in the Boe-Bot to Shield-Bot Retrofit Kit, (#32333). Instructions The four groups of pins under the Board of Education Shield plug into the four Arduino socket headers.
Chapter 2 • Shield, Lights, Servo Motors Uno R3 Mega R3 Disconnect the programming cable from your Arduino module. Remove the foam covering the metal pins on the bottom of the Board of Education Shield. Look closely at your Arduino module and the pins on the Board of Education Shield to see how the sockets and pins will line up for your particular boards.
Shield, Lights, Servo Motors • Chapter 2 Arduino’s power and programming ports are away from the BOE Shield’s breadboard Make sure the BOE Shield mounting holes align with the Arduino module’s. Hold a Nylon spacer over each mounting hole on your Arduino module, and look through it to see if the spacer can line up with the hole completely. For the mounting hole by the Arduino Uno reset button, a spacer may not fit.
Chapter 2 • Shield, Lights, Servo Motors Check to make ABSOLUTELY SURE your pins are seated in the sockets correctly. It is possible to misalign the pins, which can damage your board when it is powered. Uno R3 Correct: gap in pins lines up with gap in sockets. WRONG! STOP! There’s a pin between the gap in the sockets. Unplug it and try again. Uno R2 and older Thread a Nylon nut over each screw, and tighten gently.
Shield, Lights, Servo Motors • Chapter 2 Activity 2: Build and Test LED Indicator Lights Indicator lights give people a way to see a representation of what’s going on inside a device, or patterns of communication between two devices. Next, you will build indicator lights to display the communication signals that the Arduino will send to the servos. If you haven’t ever built a circuit before, don’t worry, this activity shows you how.
Chapter 2 • Shield, Lights, Servo Motors Resistor Color Code Values Each color bar on the resistor's case corresponds to a digit, as listed in the table below. Digit 0 1 2 3 4 5 6 7 8 9 Color black brown red orange yellow green blue violet gray white Tolerance Code First Digit Number of Zeros Second Digit Here’s how to find the resistor’s value, in this case proving that yellow-violet-brown is really 470 Ω: 1. 2. 3. The first stripe is yellow, which means the leftmost digit is a 4.
Shield, Lights, Servo Motors • Chapter 2 + Always check the LED’s plastic case. Usually, the longer lead is connected to the LED’s anode, and the shorter lead is connected to its cathode. But sometimes the leads have been clipped to the same length, or a manufacturer does not follow this convention. So, it’s best to always look for the flat spot on the case. If you plug an LED in backwards, it will not hurt it, but it won’t emit light until you plug it in the right way.
Chapter 2 • Shield, Lights, Servo Motors The prototyping area also has black sockets along the top, bottom, and left. Top: these sockets have three supply voltages for the breadboard: 3.3 V, Vin (input voltage from either battery pack or programming cable), and 5 V. Bottom-left: The first six sockets along the bottom-left are ground terminals, labeled GND; think of them as a supply voltage that’s 0 V. Collectively, the 3.
Shield, Lights, Servo Motors • Chapter 2 Always disconnect power to your board before building or modifying circuits! 1. Set the BOE Shield’s Power switch to 0. 2. Disconnect the programming cable and battery pack. Building the LED Test Circuits The image below shows the indicator LED circuit schematic on the left, and a wiring diagram example of the circuit built on your BOE Shield’s prototyping area on the right. Build the circuit shown below.
Chapter 2 • Shield, Lights, Servo Motors positive terminal of a 5 V battery. When you connect the circuit to GND, it’s like connecting to the negative terminal of the 5 V battery. On the left side of the picture, one LED lead is connected to 5 V and the other to GND. So, 5 V of electrical pressure causes electrons to flow through the circuit (electric current), and that current causes the LED to emit light. The circuit on the right side has both ends of the LED circuit connected to GND.
Shield, Lights, Servo Motors • Chapter 2 void setup() { pinMode(13, OUTPUT); } // Built-in initialization block // Set digital pin 13 -> output Now that digital pin 13 is set to output, we can use digitalWrite to turn the LED light on and off. Take a look at the next picture. On the left, digitalWrite(13, HIGH) makes the Arduino’s microcontroller connect digital pin 13 to 5 V, which turns on the LED. On the right, it shows how digitalWrite(13, LOW) makes it connect pin 13 to GND (0 V) to turn the LED off.
Chapter 2 • Shield, Lights, Servo Motors /* Robotics with the BOE Shield - HighLowLed Turn LED connected to digital pin 13 on/off once every second. */ void setup() { pinMode(13, OUTPUT); } // Built-in initialization block void loop() { digitalWrite(13, HIGH); delay(500); digitalWrite(13, LOW); delay(500); } // Main loop auto-repeats // Set digital pin 13 -> output // // // // Pin 13 = 5 V, LED emits light ..for 0.5 seconds Pin 13 = 0 V, LED no light ..for 0.
Shield, Lights, Servo Motors • Chapter 2 Try modifying your sketch to use delay(250). Don’t forget to change it in both places! How far can you reduce the delay before it just looks like the LED is dim instead of blinking on/off? Try it! Blinking the pin 12 LED is a simple matter of changing the pin parameter in the pinMode and two digitalWrite function calls. Modify the sketch so that pinMode in the setup function uses pin 12 instead of pin 13.
Chapter 2 • Shield, Lights, Servo Motors Example Sketch: ServoSlowMoCcw /* Create and save ServoSlowMoCcw, then run it on the Arduino. Verify that the pin 13 LED circuit pulses briefly every two seconds. Robotics with the BOE Shield - ServoSlowMoCcw Send 1/100th speed servo signals for viewing with an LED.
Shield, Lights, Servo Motors • Chapter 2 How to Use the Arduino Servo Library A better way to generate servo control signals is to include the Arduino Servo library in your sketch, one of the standard libraries of pre-written code bundled with the Arduino software. To see a list of Arduino libraries, click the Arduino software’s Help menu and select Reference. Or, if using codebender : edu, go to the Arduino Library reference page: https://www.arduino.
Chapter 2 • Shield, Lights, Servo Motors 4. Use the writeMicroseconds function to set the pulse time. You can do this inside either the setup or loop function: servoLeft.writeMicroseconds(1500); // 1.5 ms stay-still signal Seconds, Milliseconds, Microseconds • A millisecond is a one-thousandth of a second, abbreviated ms. • A microsecond is a one-millionth of a second, abbreviated μs. • There are 1000 microseconds (μs) in 1 millisecond (ms). • There are 1,000,000 microseconds in 1 second (s).
Shield, Lights, Servo Motors • Chapter 2 void loop() { } // Main loop auto-repeats // Empty, nothing needs repeating Your Turn – Check a Second Control Signal with the Pin 12 LED You’ll be using this code a lot, so it’s a good idea to practice declaring an instance of Servo, attaching the signal to a pin, and setting the pulse duration. Save LeftServoStayStill as BothServosStayStill. Add a second Servo declaration and name it servoRight.
Chapter 2 • Shield, Lights, Servo Motors } Activity 4: Connect Servo Motors and Batteries From the robot navigation standpoint, continuous rotation servos offer a great combination of simplicity, usefulness and low price. The Parallax continuous rotation servos are the motors that will make the BOE Shield-Bot’s wheels turn, under Arduino control.
Shield, Lights, Servo Motors • Chapter 2 Standard Servos vs. Continuous Rotation Servos Standard servos are designed to receive electronic signals that tell them what position to hold. These servos control the positions of radio controlled airplane flaps, boat rudders, and car steering. Continuous rotation servos receive the same electronic signals, but instead turn at certain speeds and directions. Continuous rotation servos are handy for controlling wheels and pulleys.
Chapter 2 • Shield, Lights, Servo Motors The picture below shows the schematic of the circuit you create by plugging the servos into ports 13 and 12 on the BOE Shield. Pay careful attention to wire color as you plug in the cables: the black wire should be at the bottom, and the white one should be at the top. Connect your servos to your BOE Shield as shown in the diagram below. The left servo connects to port 13 and the right servo connects to port 12.
Shield, Lights, Servo Motors • Chapter 2 Parts List (5) 1.5 volt AA batteries (1) 5-cell battery pack Load the Batteries Load the batteries into the battery pack. Plug the battery pack into the Arduino’s power jack. When you are done, it should resemble the picture below. Activity 5: Centering the Servos In this activity, you will run a sketch that sends the “stay-still” signal to the servos. You will then use a screwdriver to adjust the servos so that they actually stay still.
Chapter 2 • Shield, Lights, Servo Motors Tool Required You’ll need a Phillips #1 point screwdriver with a 1/8″ (3.18 mm) or smaller shaft. Sending the Center Signals If a servo has not yet been centered, it may turn, vibrate, or make a humming noise when it receives the “stay-still” signal. Reconnect your programming cable, and re-load Example Sketch: LeftServoStayStill from page 58. Set the BOE Shield’s Power switch to 2, to provide power to the servos.
Shield, Lights, Servo Motors • Chapter 2 Your Turn – Center the Servo Connected to Pin 12 Repeat the process for the pin 12 servo using the sketch RightServoStayStill. /* Robotics with the BOE Shield – RightServoStayStill Transmit the center or stay still signal on pin 12 for center adjustment. */ #include // Include servo library Servo servoRight; // Declare right servo void setup() { servoRight.attach(12); servoRight.
Chapter 2 • Shield, Lights, Servo Motors Pulse Width Controls Speed and Direction This timing diagram shows how a Parallax continuous rotation servo turns full speed clockwise when you send it 1.3 ms pulses. Full speed falls in the 50 to 60 RPM range. 1.3 ms 1.3 ms Vdd (5 V) standard servo www.parallax.com Vss (0 V) 20 ms What’s RPM? Revolutions Per Minute—the number of full rotations turned in one minute.
Shield, Lights, Servo Motors • Chapter 2 Save the modified sketch and run it on the Arduino. Verify that the servo connected to pin 13 now rotates the other direction, which should be counterclockwise, at about 50 to 60 RPM. 1.7 ms 1.7 ms Vdd (5 V) standard servo www.parallax.com GND (0 V) 20 ms Example Sketch: RightServoClockwise Save LeftServoClockwise as RightServoClockwise. Replace all instances of servoLeft with servoRight. Replace all instances of 13 with 12.
Chapter 2 • Shield, Lights, Servo Motors Controlling Servo Speed and Direction For BOE Shield-Bot navigation, we need to control both servos at once. Create and save ServosOppositeDirections, and run it on the Arduino. Verify that the servo connected to pin 13 turns counterclockwise and the one connected to pin 12 turns clockwise.
Shield, Lights, Servo Motors • Chapter 2 Pulse Width Modulation: Adjusting the property of a signal to carry information is called modulation. We’ve discovered that servo control signals are a series of high pulses separated by low resting states. How long the high pulse lasts—how wide the high pulse looks in a timing diagram—determines the speed and direction that the servo turns. That adjustable pulse width carries the servo setting information.
Chapter 2 • Shield, Lights, Servo Motors How To Control Servo Run Time It’s easy to control how long the servos run when using the Servo library. Once set, a servo will maintain its motion until it receives a new setting. So, to make a servo run for a certain length of time, all you have to do is insert a delay after each setting. Example Sketch: ServoRunTimes Create and save the ServoRunTimes sketch, and run it on your Arduino.
Shield, Lights, Servo Motors • Chapter 2 Chapter 2 Summary The focus of this chapter was calibrating and testing the servos, and building indicator lights to monitor the servo signals. In addition to some hardware setup, many concepts related to electronics, programming, and even a few good engineering concepts were introduced along the way.
Chapter 2 • Shield, Lights, Servo Motors Chapter 2 Challenges Questions 1. 2. 3. 4. 5. 6. 7. How do you connect two leads together using a breadboard? What function sets a digital pin’s direction? What function sets pin 13 to 5 V? What function sets it to 0 V? How can a sketch control the duration of a 5 V signal? What are the pulse durations that tell a continuous rotation servo to turn a. full speed clockwise, b. full speed counterclockwise, c. stay still. Which call would make a servo turn faster? a.
Shield, Lights, Servo Motors • Chapter 2 Question Solutions 1. 2. 3. Plug the two leads into the same 5-socket row on the breadboard. The pinMode function. The digitalWrite function does both, depending on its value parameter: 4. Assuming a pin has just been set high, the delay call can keep it high for a certain amount of time. Then, a digitalWrite call can set it low. (a)1.3 ms pulses for full speed clockwise, (b)1.7 ms pulses for full speed clockwise, and (c)1.5 ms pulses for stay still.
Chapter 2 • Shield, Lights, Servo Motors servoRight.writeMicroseconds(1500); // 1.5 ms -> stop delay(1200); // ..for 1.2 seconds servoLeft.writeMicroseconds(1500); // 1.5 ms -> stop } 3. In this example, the pin 13 servo starts counterclockwise and the pin 12 servo starts out clockwise. This goes on for 1.5 seconds. Then, the pin 12 servo is changed to counterclockwise, and this goes on for another 1.5 seconds. After that, both servos are stopped. void setup() { servoLeft.attach(13); servoRight.
Shield, Lights, Servo Motors • Chapter 2 servoRight.attach(12); // Attach right signal to pin 12 servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1300); delay(3000); servoLeft.detach(); servoRight.detach(); // // // // // Pin 13 counterclockwise Pin 12 clockwise ..for 3 seconds Stop servo signal to pin 13 Stop servo signal to pin 12 } void loop() { } 2. // Main loop auto-repeats // Empty, nothing needs repeating Solution is the sketch ForwardLeftRightBackward, from a later chapter.
Chapter 3 • Assemble and Test your BOE Shield-Bot Chapter 3. Assemble and Test your BOE Shield-Bot This chapter contains instructions for building and testing your BOE Shield-Bot. It’s especially important to complete the testing portion before moving on to the next chapter. By doing so, you can help avoid a number of common mistakes that could otherwise lead to mystifying BOE Shield-Bot behavior. Here is a summary of what you will do: • • • • Build the BOE Shield-Bot.
Assemble and Test your BOE Shield-Bot • Chapter 3 Tools All of the tools needed are common and can be found in most households and school shops. They can also be purchased at local hardware stores. The Parallax screwdriver is included in the Robotics Shield Kit, and the other two are optional but handy to have.
Chapter 3 • Assemble and Test your BOE Shield-Bot Instructions Remove the 1″ aluminum standoffs from the BOE Shield, and save the standoffs and screws. Insert the 13/32″ rubber grommet into the hole in the center of the chassis. Make sure the groove in the outer edge of the rubber grommet is seated on the metal edge of the hole. Use two of the 1/4″ 4-40 screws to attach two of the standoffs to the top front of the chassis as shown. Save the other two standoffs and screws for a later step.
Assemble and Test your BOE Shield-Bot • Chapter 3 output shafts Mount the Servos on the Chassis Parts List (2) BOE Shield-Bot Chassis, partially assembled.
Chapter 3 • Assemble and Test your BOE Shield-Bot Instructions STOP! Before taking the next step, you must have completed these Chapter 2 activities: Activity 4: Connect Servo Motors and Batteries on page 60, and Activity 5: Centering the Servos on 63. Decide how you want to mount your servos from the two options described and pictured below. Option 2 (right) is considered our standard small robot configuration, and our navigation code examples assume you have set up your robot this way.
Assemble and Test your BOE Shield-Bot • Chapter 3 Mount the Battery Pack Parts List (2) Nylon flat-head slotted screws, 3/8″ 4-40 (2) 1" standoffs (removed from BOE Shield previously) (1) 5-cell battery pack with 2.1 mm center-positive plug 3/8” Nylon screws will go through outer holes and be secured to chassis with 1” standoffs. Instructions Place the empty battery pack inside the chassis positioned as shown above.
Chapter 3 • Assemble and Test your BOE Shield-Bot Insert the two Nylon flat-head screws through the inside of the battery pack. Use the smaller set of holes that line up with the chassis mounting holes for the front standoffs. From the top of the chassis, thread a 1" standoff on each screw and tighten. Pull the battery pack’s power cord and servo lines through the rubber grommet hole in the center of the chassis, as shown below.
Assemble and Test your BOE Shield-Bot • Chapter 3 Instructions The robot’s tail wheel is merely a plastic ball with a hole through the center. A cotter pin holds it to the chassis and functions as an axle for the wheel. Line up the hole in the tail wheel with the holes in the tail portion of the chassis. Run the cotter pin through all three holes (chassis left, tail wheel, chassis right). Bend the ends of the cotter pin apart so that it can’t slide back out of the hole.
Chapter 3 • Assemble and Test your BOE Shield-Bot Attach the BOE Shield to the Chassis Parts List (4) pan-head screws, 1/4″ 4-40 (1) Board of Education Shield mounted to your Arduino module and secured with standoffs. Instructions Set the BOE Shield on the four standoffs, lining them up with the four mounting holes on the outer corner of the board. Make sure the white breadboard is closer to the drive wheels, not the tail wheel. Attach the board to the standoffs with the pan-head screws.
Assemble and Test your BOE Shield-Bot • Chapter 3 From the underside of the chassis, pull any excess servo and battery cable through the rubber grommet hole, and tuck the excess cable lengths between the servos and the chassis. Activity 2: Re-Test the Servos In this activity, you will test to make sure that the electrical connections between your board and the servos are correct. The picture below shows your BOE Shield-Bot’s front, back, left, and right.
Chapter 3 • Assemble and Test your BOE Shield-Bot Testing the Left and Right Wheels Test the Right Wheel First The next example sketch will test the servo connected to the right wheel, shown below. The sketch will make this wheel turn clockwise for three seconds, then stop for one second, then turn counterclockwise for three seconds.
Assemble and Test your BOE Shield-Bot • Chapter 3 servoRight.attach(12); // Attach right signal to pin 12 servoRight.writeMicroseconds(1300); delay(3000); // Right wheel clockwise // ...for 3 seconds servoRight.writeMicroseconds(1500); delay(1000); // Stay still // ...for 3 seconds servoRight.writeMicroseconds(1700); delay(3000); // Right wheel counterclockwise // ...for 3 seconds servoRight.
Chapter 3 • Assemble and Test your BOE Shield-Bot If the left wheel/servo does behave properly, then your BOE Shield-Bot is functioning properly. You are ready to move on to Activity 3: Start-Reset Indicator on page 89. Servo Troubleshooting The servo doesn’t turn at all. Make sure the battery pack has fresh batteries, all oriented properly in the case. Make sure the BOE Shield’s power switch is set to position-2. Then re-run the program by pressing and releasing the board’s RESET button.
Assemble and Test your BOE Shield-Bot • Chapter 3 Activity 3: Start-Reset Indicator In this activity, we’ll build a small noise-making circuit on the BOE Shield’s prototyping area that will generate a tone if the robot’s batteries run too low. When the voltage supply drops below the level a device needs to function properly, it’s called brownout. The device (your Arduino) typically shuts down until the supply voltage returns to normal. Then, it will restart whatever sketch it was running.
Chapter 3 • Assemble and Test your BOE Shield-Bot Build the Piezospeaker Circuit Parts Required (1) piezospeaker (just peel off the “Remove the seal after washing” sticker if it has one) (misc.) jumper wires Building the Start/Reset Indicator Circuit Always disconnect power before building or modifying circuits! • Set the Power switch to 0. • Unplug the battery pack. • Unplug the programming cable. The next picture shows a wiring diagram for adding a piezospeaker to the breadboard.
Assemble and Test your BOE Shield-Bot • Chapter 3 Programming the Start-Reset Indicator The next example sketch tests the piezospeaker using calls to the Arduino’s tone function. True to its name, this function sends signals to speakers to make them play tones. There are two options for calling the tone function. One allows you to specify the pin and frequency (pitch) of the tone. The other allows you to specify pin, frequency, and duration (in milliseconds).
Chapter 3 • Assemble and Test your BOE Shield-Bot Verify that, after each reset, the piezospeaker makes a clearly audible tone for one second, and then the “Waiting for reset…” messages resumes. Try disconnecting and reconnecting your battery supply and programming cable, and then plugging them back in. This should also trigger the start-alert tone. /* * Robotics with the BOE Shield - StartResetIndicator * Test the piezospeaker circuit. */ void setup() { Serial.begin(9600); Serial.
Assemble and Test your BOE Shield-Bot • Chapter 3 Activity 4: Test Speed Control The transfer curve graph on the next page shows pulse time vs. servo speed. The graph’s horizontal axis shows the pulse width in microseconds (µs), and the vertical axis shows the servo’s response in RPM. Clockwise rotation is shown as negative, and counterclockwise is positive.
Chapter 3 • Assemble and Test your BOE Shield-Bot 3. more likely to result in closely matched speeds than picking two values in the 1400 to 1600 µs range. Between 1400 and 1600 µs, speed control is more or less linear. In this range, a certain change in pulse width will result in a corresponding change in speed. Use pulses in this range to control your servo speeds.
Assemble and Test your BOE Shield-Bot • Chapter 3 Click the transmit pane at the top, type any character, and click the Send button. Count the number of turns the wheel makes, and multiply by 10 for RPMs. (Don’t forget to make a note of direction; it will change after the 5th test.
Chapter 3 • Assemble and Test your BOE Shield-Bot How TestServoSpeed Works The sketch TestServoSpeed increments the value of a variable named pulseWidth by 25 each time through a for loop. // Loop counts with pulseWidth from 1375 to 1625 in increments of 25. for(int pulseWidth = 1375; pulseWidth <= 1625; pulseWidth += 25) With each repetition of the for loop, it displays the value of the next pulse width that it will send to the pin 13 servo, along with a user prompt. Serial.
Assemble and Test your BOE Shield-Bot • Chapter 3 After the Arduino receives a character from the keyboard, it displays the “Running…” message and then makes the servo turn for 6 seconds. Remember that the for loop this code is in starts the pulseWidth variable at 1375 and adds 25 to it with each repetition. So, the first time through the loop, servoLeft is 1375, the second time through it’s 1400, and so on all the way up to 1625. Each time through the loop, servoLeft.
Chapter 3 • Assemble and Test your BOE Shield-Bot Pulse Width and RPM for Parallax Continuous Rotation Servo Pulse Width (µs) Rotational Velocity (RPM) Pulse Width (µs) Rotational Velocity (RPM) Pulse Width (µs) Rotational Velocity (RPM) Pulse Width (µs) 1300 1400 1500 1600 1310 1410 1510 1610 1320 1420 1520 1620 1330 1430 1530 1630 1340 1440 1540 1640 1350 1450 1550 1650 1360 1460 1560 1660 1370 1470 1570 1670 1380 1480 1580 1680 1390 1490 1590 1690 1700 98
Assemble and Test your BOE Shield-Bot • Chapter 3 Chapter 3 Summary This chapter covered BOE Shield-Bot assembly and testing. Assembly involved both mechanical construction and circuit-building, and testing used some new programming concepts.
Chapter 3 • Assemble and Test your BOE Shield-Bot Chapter 3 Challenges Questions 1. 2. 3. 4. 5. What are some of the symptoms of brownout on the BOE Shield-Bot? What is a reset? How can a piezospeaker be used to announce that brownout just occurred? What function makes the speaker play tones? What’s a hertz? What’s its abbreviation? 1. Write a statement that makes a tone, one that sounds different from the startalert tone, to signify the end of a sketch.
Assemble and Test your BOE Shield-Bot • Chapter 3 Project Solutions 1. Add E2 solution to the end of the for loop. /* Robotics with the BOE Shield – Chapter 3, Project 1 */ #include // Include servo library Servo servoLeft; Servo servoRight; // Declare left servo signal // Declare right servo signal void setup() { tone(4, 3000, 1000); delay(1000); // Built in initialization block Serial.begin(9600); servoLeft.
Chapter 3 • Assemble and Test your BOE Shield-Bot servoRight.writeMicroseconds(1500 + (1500 – pulseWidth)) Remember to add a servoRight.writeMicroseconds(1500) after the 6-second run time. /* Robotics with the BOE Shield – Chapter 3, Project 2 */ #include // Include servo library Servo servoLeft; Servo servoRight; // Declare left servo signal // Declare right servo signal void setup() { tone(4, 3000, 1000); delay(1000); // Built in initialization block Serial.begin(9600); servoLeft.
BOE Shield-Bot Navigation • Chapter 4 Chapter 4. BOE Shield-Bot Navigation This chapter introduces different programming strategies to make the BOE Shield-Bot move. Once we understand how basic navigation works, we’ll make functions for each maneuver. In later chapters, we’ll write sketches that call these functions in response to sensor input, which will allow the BOE Shield-Bot to navigate on its own.
Chapter 4 • BOE Shield-Bot Navigation Activity 1: Basic BOE Shield-Bot Maneuvers Have you ever thought about what direction a car’s wheels have to turn to propel it forward? The wheels turn opposite directions on opposite sides of the car. Likewise, to make the BOE Shield-Bot go forward, its left wheel has to turn counterclockwise, but its right wheel has to turn clockwise.
BOE Shield-Bot Navigation • Chapter 4 void setup() { tone(4, 3000, 1000); delay(1000); // Built-in initialization block // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.attach(12); // Attach left signal to pin 13 // Attach right signal to pin 12 // Full speed forward servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1300); delay(3000); // Left wheel counterclockwise // Right wheel clockwise // ...for 3 seconds servoLeft.detach(); servoRight.
Chapter 4 • BOE Shield-Bot Navigation As with all motion sketches, the first action setup takes is making the piezospeaker beep. The tone function call transmits a signal to digital pin 4 that makes the piezospeaker play a 3 kHz tone that lasts for 1 second. Since the tone function works in the background while the code moves on, delay(1000) prevents the BOE Shield-Bot from moving until the tone is done playing.
BOE Shield-Bot Navigation • Chapter 4 Your Turn – Adjusting Distance Want to change the distance traveled? Just change the time in delay(3000). For example, delay(1500) will make the BOE Shield-Bot go for only half the time, which in turn will make it travel only half as far. Likewise, delay(6000) will make it go for twice the time, and therefore twice the distance. Change delay(3000) to delay(1500) and re-load the sketch.
Chapter 4 • BOE Shield-Bot Navigation Servo servoRight; void setup() { tone(4, 3000, 1000); delay(1000); // Built-in initialization block // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.attach(12); // Attach left signal to pin 13 // Attach right signal to pin 12 // Full speed forward servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1300); delay(2000); // Left wheel counterclockwise // Right wheel clockwise // ...
BOE Shield-Bot Navigation • Chapter 4 // Pivot forward-right servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1500); // Left wheel counterclockwise // Right wheel stop // Pivot backward-left servoLeft.writeMicroseconds(1500); servoRight.writeMicroseconds(1700); // Left wheel stop // Right wheel counterclockwise // Pivot backward-right servoLeft.writeMicroseconds(1300); servoRight.
Chapter 4 • BOE Shield-Bot Navigation Place the Shield-Bot on a long stretch of smooth, bare floor. Hold the Reset button down while you move the Power switch to 2, then let go. Press the Reset button, then watch closely to see if your BOE Shield-Bot veers to the right or left as it travels forward for ten seconds. // Robotics with the BOE Shield - ForwardTenSeconds // Make the BOE Shield-Bot roll forward for ten seconds, then stop. #include
BOE Shield-Bot Navigation • Chapter 4 Let’s say that your BOE Shield-Bot gradually turns left. That means the right wheel is turning faster than the left. Since the left wheel is already going as fast as it possibly can, the right wheel needs to be slowed down to straighten out the robot’s path. To slow it down, change the us parameter in servoRight.writeMicroseconds(us) to a value closer to 1500. First, try 1400. Is it still going too fast? Raise it 1410.
Chapter 4 • BOE Shield-Bot Navigation The smallest change that actually makes a difference is 20. Servo control pulses are sent every 20 ms, so adjust your delay function call’s ms parameter in multiples of 20. If you find yourself with one value slightly overshooting 90° and the other slightly undershooting, choose the value that makes it turn a little too far, then slow down the servos slightly.
BOE Shield-Bot Navigation • Chapter 4 U.S. customary units example: If you’re 140 miles away from your destination, and you’re traveling 70 miles per hour, it’s going to take 2 hours to get there. 140 miles 70 miles/hour 1 hour = 140 miles × 70 miles = 2 hours time = Metric units example: If you’re 200 kilometers away from your destination, and you’re traveling 100 kilometers per hour, it’s going to take 2 hours to get there.
Chapter 4 • BOE Shield-Bot Navigation Press the Reset button on your board to re-run the sketch. Measure how far your BOE Shield-Bot traveled by recording the measurement where the wheel is now touching the ground here:_______________ (in or cm). // Robotics with the BOE Shield - ForwardOneSecond // Make the BOE Shield-Bot roll forward for one second, then stop. #include
BOE Shield-Bot Navigation • Chapter 4 U.S. customary units example: At 9 in/s, your BOE Shield-Bot has to travel for 2.22 s to travel 20 in. time = 20 in 9 in/s = 20 in × 1s 9 in = 2.22 s Metric units example: At 23 cm/s, your BOE Shield-Bot has to travel for 2.22 s to travel 51 cm. time = 51 cm 23 cm/s = 51 cm × 1s 23 cm = 2.22 s Both examples above resolve to the same answer: 1000 ms s 1000 ms = 2.
Chapter 4 • BOE Shield-Bot Navigation ms servo run time = robot distance 1000 ms × robot speed s Modify ForwardOneSecond to make your BOE Shield-Bot travel forward the amount of time that you determined, and try it out. How close does it come? Encoders: Increase the accuracy of your BOE Shield-Bot distances with devices called encoders which count the holes in the BOE Shield-Bot’s wheels as they pass.
BOE Shield-Bot Navigation • Chapter 4 Keep on in this manner until the… • 50th trip: speed is 100, with servoLeft.writeMicroseconds(1600) and servoRight.writeMicroseconds(1400). Remember, that’s pretty close to full speed; 1700 and 1300 are overkill. Example Sketch: StartAndStopWithRamping Create, save, and run the sketch StartAndStopWithRamping. Verify that the BOE Shield-Bot gradually accelerates to full speed, maintains full speed for a while, and then gradually decelerates to a full stop.
Chapter 4 • BOE Shield-Bot Navigation Your Turn – Add Ramping to Other Maneuvers You can also create routines to combine ramping with other maneuvers. Here’s an example of how to ramp up to full speed going backward instead of forward. The only difference between this routine and the forward ramping routine is that the value of speed starts at zero and counts to –100. for(int speed = 0; speed >= -100; speed -= 2)// { servoLeft.writeMicroseconds(1500+speed); // servoRight.
BOE Shield-Bot Navigation • Chapter 4 functions to your sketch as well as a few different approaches to creating reusable maneuvers with those functions. Minimal Function Call The diagram below shows part of a sketch that contains a function named example added at the end, below the loop function. It begins and gets named with the function definition void example().
Chapter 4 • BOE Shield-Bot Navigation Example Sketch – SimpleFunctionCall Create, save, and run the SimpleFunctionCall sketch. Watch the upload progress, and as soon as it’s done, open the Serial Monitor. Watch your terminal and verify that the sequence of messages start with Before, then During, then After. // Robotics with the BOE Shield – SimpleFunctionCall // This sketch demonstrates a simple function call. void setup() { Serial.begin(9600); Serial.println("Before example function call.
BOE Shield-Bot Navigation • Chapter 4 of -32,768 to 32,767. Here, the term int Hz in the parentheses defines a parameter for the pitch function; in this case, it declares a local variable Hz of data type int. Local variables, remember, are declared within a function, and can only be seen and used inside that function. If a local variable is created as a parameter in the function declaration, as void pitch(int Hz) is here, initialize it by passing a value to it each time the function is called.
Chapter 4 • BOE Shield-Bot Navigation // Robotics with the BOE Shield – FunctionCallWithParameter // This program demonstrates a function call with a parameter. void setup() { Serial.begin(9600); Serial.println("Playing higher pitch tone..."); pitch(3500); // pitch function call passes 3500 to Hz parameter delay(1000); Serial.println("Playing lower pitch tone...
BOE Shield-Bot Navigation • Chapter 4 pitch(3500, 500); pitch(2000, 1500); Notice that each of these calls to pitch includes two values, one to pass to the Hz parameter, and one to pass to the ms parameter. The number of values in a function call must match the number of parameters in that function’s definition, or the sketch won’t compile. Save FunctionCallWithParameter as FunctionCallWithTwoParameters. Replace the pitch function with the two-parameter version.
Chapter 4 • BOE Shield-Bot Navigation } void forward(int time) { servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1300); delay(time); } void turnLeft(int time) { servoLeft.writeMicroseconds(1300); servoRight.writeMicroseconds(1300); delay(time); } void turnRight(int time) { servoLeft.writeMicroseconds(1700); servoRight.
BOE Shield-Bot Navigation • Chapter 4 Cut the function calls to forward(2000), turnLeft(600), turnRight(600), and backward(2000) out of the setup function and paste them into the loop function. It should look like this when you’re done: void setup() { tone(4, 3000, 1000); delay(1000); servoLeft.attach(13); servoRight.
Chapter 4 • BOE Shield-Bot Navigation • • Positive values for the number of ms to execute the maneuver –1 to disable the servo signal Here is what calls to this function will look like for the familiar forward-backward-left-rightstop sequence: maneuver(200, 200, 2000); maneuver(-200, 200, 600); maneuver(200, -200, 600); maneuver(-200, -200, 2000); maneuver(0, 0, -1); // // // // // Forward 2 seconds Left 0.6 seconds Right 0.
BOE Shield-Bot Navigation • Chapter 4 { servoLeft.detach(); servoRight.detach(); } delay(msTime); // Stop servo signals // Delay for msTime } Your Turn – Customize Speed and Duration Control With the maneuver function, 0 is stop, 100 to –100 is the speed control range, and 200 and -200 are overkill to keep the servos running as fast as they possibly can. The TestManeuverFunction sketch makes it easy to define custom maneuvers quickly.
Chapter 4 • BOE Shield-Bot Navigation maneuvers and maneuver times. If your sketch needs to store lists of maneuvers, the variable array is the best tool for storing these lists. This activity introduces arrays with some simple musical applications using the piezospeaker. Then, it examines two different approaches for using arrays to store sequences of maneuvers for playback while the sketch is running. What’s an Array? An array is a collection of variables with a common name.
BOE Shield-Bot Navigation • Chapter 4 Then, your sketch could fill in the values of each element later, perhaps with sensor measurements, values entered from the Serial Monitor, or whatever numbers you need to store. The diagram below shows the musical notes on the right side of a piano keyboard. Each key press on a piano key makes a string (or a speaker if it’s electric) vibrate at a certain frequency. Compare the frequencies of the leftmost eight white keys to the values in the note array.
Chapter 4 • BOE Shield-Bot Navigation Example Sketch – PlayOneNote Here is an example that displays an individual array element’s value in the Serial Monitor, and also uses that value to make the BOE Shield-Bot’s piezospeaker play a musical note. Create, save, and run the PlayOneNote sketch, and run it on the Arduino. Open the Serial Monitor as soon as the sketch is done loading. Verify that the Serial Monitor displays “note = 1397.” Verify that the speaker played a tone.
BOE Shield-Bot Navigation • Chapter 4 Verify that the Serial Monitor displays each note in the array as the speaker plays it. // Robotics with the BOE Shield – PlayNotesWithLoop // Displays and plays another element from note array. int note[] = {1047, 1147, 1319, 1397, 1568, 1760, 1976, 2093}; void setup() { Serial.begin(9600); for(int index = 0; index < 8; index++) { Serial.print("index = "); Serial.println(index); Serial.print("note[index] = "); Serial.
Chapter 4 • BOE Shield-Bot Navigation int elementCount = sizeof(note) / sizeof(int); Later, your for loop can use the elementCount variable to play all the notes in the array, even if you add or delete elements: for(int index = 0; index < elementCount; index++) Create, save, and run PlayAllNotesInArray. Open the Serial Monitor as soon as the sketch is done loading. Verify again that the Serial Monitor displays each note in the array as the speaker plays it.
BOE Shield-Bot Navigation • Chapter 4 int note[] = {1047, 1147, 1319, 1397, 1568, 1760, 1976, 2093, 2349, 2637}; If you are musically inclined, try writing an array that will play a very short tune. Navigation with Arrays Remember the maneuver function from the last activity? Here are three arrays of values, one for each parameter in the maneuver function. Together, they make up the same forward-leftright-backward-stop sequence we’ve been doing through the chapter.
Chapter 4 • BOE Shield-Bot Navigation for(int index = 0; index < elementCount; index++) { maneuver(speedsLeft[index], speedsRight[index], times[index]); } Each time through the loop, index increases by 1. So, with each maneuver call, the next element in each array gets passed as a parameter to the maneuver function. The first time through the loop, index is 0, so the maneuver call’s parameters become the zeroth element from each array, like this: maneuver(speedsLeft[0], speedsRight[0], times[0]).
BOE Shield-Bot Navigation • Chapter 4 } void loop() { } // Main loop auto-repeats // Empty, nothing needs repeating void maneuver(int speedLeft, int speedRight, int msTime) { // speedLeft, speedRight ranges: Backward Linear Stop Linear Forward // -200 -100......0......100 200 servoLeft.writeMicroseconds(1500 + speedLeft); // Left servo speed servoRight.writeMicroseconds(1500 - speedRight); // right servo speed if(msTime==-1) // if msTime = -1 { servoLeft.detach(); // Stop servo signals servoRight.
Chapter 4 • BOE Shield-Bot Navigation Character Arrays and switch-case The last example in this activity is a sketch for performing maneuvers using a list of characters in an array. Each character represents a certain maneuver, with a 200 ms run time. Since the run time is fixed, it’s not as flexible as the last approach, but it sure makes it simple to build a quick sequence of maneuvers.
BOE Shield-Bot Navigation • Chapter 4 } while(maneuvers[index++] != 's');} void loop() { } // Main loop auto-repeats // Empty, nothing needs repeating void go(char c) // go function { switch(c) // Switch to code based on c { case 'f': // c contains 'f' servoLeft.writeMicroseconds(1700); // Full speed forward servoRight.writeMicroseconds(1300); break; case 'b': // c contains 'b' servoLeft.writeMicroseconds(1300); // Full speed backward servoRight.
Chapter 4 • BOE Shield-Bot Navigation least once. Each time through the loop, go(maneuvers[index]) passes the character at maneuvers[index] to the go function. The ++ in index++ adds one to the index variable for the next time through the loop—recall that this is the post increment operator. This continues while(maneuvers[index] != 's') which means “while the value fetched from the maneuvers array is not equal to 's' .” Now, let’s look at the go function.
BOE Shield-Bot Navigation • Chapter 4 case 'h': servoLeft.writeMicroseconds(1550); servoRight.writeMicroseconds(1450); break; // c contains 'h' // Half speed forward Add ten or so h characters to your maneuvers character array. Keep in mind that they have to be added to the left of the s character for the sketch to get to them. Experiment a little, and add another case statement for a different maneuver, such as pivot-backward-left, then add some characters for the new maneuver to your array string.
Chapter 4 • BOE Shield-Bot Navigation • • Controlling robot maneuver run-time to make the BOE Shield-Bot travel a predetermined distance or to rotate to a particular angle Compensating for hardware variance by adjusting servo speeds for straight travel Engineering Skills • • • Making observations and measurements to derive constants for a simple formula that characterizes the cause-and-effect relationship between system input and system output.
BOE Shield-Bot Navigation • Chapter 4 Projects 1. 2. It is time to fill in column 3 of the writeMicroseconds table on page 69. To do this, modify the us arguments in the writeMicroseconds calls in the ForwardThreeSeconds sketch using each pair of values from column 1. Record your BOE Shield-Bot’s resultant behavior for each pair in column 3. Once completed, this table will serve as a reference guide when you design your own custom BOE Shield-Bot maneuvers. The diagram shows two simple courses.
Chapter 4 • BOE Shield-Bot Navigation 4. Given the data below, it should take about 3727 milliseconds to travel 36 inches: BOE Shield-Bot speed = 11 in/s BOE Shield-Bot distance = 36 in/s time = (BOE Shield-Bot distance / BOE Shield-Bot speed) * (1000 ms / s) = (36 / 11 ) * (1000) = 3.727272…s * 1000 ms/s ≈ 3727 ms 5. 6. 7. 8. 9.
BOE Shield-Bot Navigation • Chapter 4 servoRight.writeMicroseconds(1700); delay(300); // 60/180 = 1/3, so use 1200/3 = 400 servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1700); delay(400); 3. Solution: // forward 1 second servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1700); delay(1000); // ramp into pivot for(int speed = 0; speed <= 100; speed+=2) { servoLeft.writeMicroseconds(1500); servoRight.
Chapter 4 • BOE Shield-Bot Navigation Project Solutions 1. Solution (though the table looks a little different than the one you may have printed out.) Servo ports connected to: 2.
BOE Shield-Bot Navigation • Chapter 4 { tone(4, 3000, 1000); delay(1000); // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.attach(12); // Attach left signal to pin 13 // Attach right signal to pin 12 // Arc to the right servoLeft.writeMicroseconds(1600); // Left wheel counterclockwise servoRight.writeMicroseconds(1438); // Right wheel clockwise slower delay(25500); // ...for 25.5 seconds servoLeft.detach(); servoRight.
Chapter 4 • BOE Shield-Bot Navigation // Turn left 120 degrees servoLeft.writeMicroseconds(1300); // Left wheel counterclockwise servoRight.writeMicroseconds(1300); // Right wheel clockwise slower delay(700); } servoLeft.detach(); servoRight.
Tactile Navigation with Whiskers • Chapter 5 Chapter 5. Tactile Navigation with Whiskers Tactile switches are also called bumper switches or touch switches, and they have many uses in robotics. A robot programmed to pick up an object and move it to another conveyer belt might rely on a tactile switch to detect the object. Automated factory lines might use tactile switches to count objects, and to align parts for a certain step in a manufacturing process.
Chapter 5 • Tactile Navigation with Whiskers Activity 1: Build and Test the Whiskers Remember subsystem testing? First, we’ll build the whiskers circuits and write code to check their input states before using them in navigation sketches. Whisker Circuit and Assembly Gather the whisker hardware in the parts list. Disconnect power from your board and servos.
Tactile Navigation with Whiskers • Chapter 5 Thread a Nylon washer and then a ½″ round spacer on each of the 7/8″ screws. Attach the screws through the holes in your board and into the standoffs below, but do not tighten them all the way yet. Slip the hooked ends of the whisker wires around the screws, one above a washer and the other below a washer, positioning them so they cross over each other without touching. Tighten the screws into the standoffs.
Chapter 5 • Tactile Navigation with Whiskers 150 • Robotics with the BOE Shield-Bot
Tactile Navigation with Whiskers • Chapter 5 How Whisker Switches Work The whiskers are connected to ground (GND) because the plated holes at the outer edge of the board are all connected to GND. The metal standoffs and screws provide the electrical connection to each whisker. Since each whisker is connected to digital I/O, the Arduino can be programmed to detect which voltage is applied to each circuit, 5 V or 0 V.
Chapter 5 • Tactile Navigation with Whiskers When neither whisker is pressed up against its 3-pin header, you can expect your Serial Monitor to display two columns of 1’s, one for each whisker. If you press just the right whisker, the right column should report 0, and the display should read 10. If you press just the left whisker, the left column should report 1 and the display should read 01. Of course, if you press both whiskers, it should display 00.
Tactile Navigation with Whiskers • Chapter 5 Serial.begin(9600); // Set data rate to 9600 bps } void loop() { byte wLeft = digitalRead(5); byte wRight = digitalRead(7); // Main loop auto-repeats // Copy left result to wLeft // Copy right result to wRight Serial.print(wLeft); Serial.println(wRight); // Display left whisker state // Display right whisker state delay(50); // Pause for 50 ms } Look at the values displayed in the Serial Monitor.
Chapter 5 • Tactile Navigation with Whiskers Next, Serial.print displays the value of wLeft to the Serial Monitor, and Serial.println displays the value of wRight and a carriage return. Serial.print(wLeft); Serial.println(wRight); // Display left whisker state // Display right whisker state Before the next repetition of the loop function, there’s a delay(50). This slows down the number of messages the Serial Monitor receives each second.
Tactile Navigation with Whiskers • Chapter 5 Flat spot on plastic case indicates cathode. This lead is the anode. This lead is the anode. Flat spot on plastic case indicates cathode. Programming the LED Whisker Testing Circuits Re-save WhiskerStates as TestWhiskersWithLEDs. Add pinMode calls to the setup function, setting digital pins 8 and 2 to output.
Chapter 5 • Tactile Navigation with Whiskers pinMode(2, OUTPUT); // Right LED indicator -> output To make the whisker input states control the LEDs, insert these two if...else statements between the Serial.
Tactile Navigation with Whiskers • Chapter 5 void setup() { pinMode(7, pinMode(5, pinMode(8, pinMode(2, // Built-in initialization block INPUT); INPUT); OUTPUT); OUTPUT); // // // // Set right whisker pin to input Set left whisker pin to input Left LED indicator -> output Right LED indicator -> output tone(4, 3000, 1000); delay(1000); // Play tone for 1 second // Delay to finish tone Serial.
Chapter 5 • Tactile Navigation with Whiskers Whisker Navigation Overview The RoamingWithWhiskers sketch makes the BOE Shield-Bot go forward while monitoring its whisker inputs, until it encounters an obstacle with one or both of them. As soon as the Arduino senses whisker electrical contact, it uses an if…else if…else statement to decide what to do. The decision code checks for various whisker pressed/not pressed combinations, and calls navigation functions to execute back-up-and-turn maneuvers.
Tactile Navigation with Whiskers • Chapter 5 { backward(1000); turnLeft(800); } else if(wLeft == 0) { backward(1000); turnRight(400); } else if(wRight == 0) { backward(1000); turnLeft(400); } else { forward(20); } // Back up 1 second // Turn left about 120 degrees // If only left whisker contact // Back up 1 second // Turn right about 60 degrees // If only right whisker contact // Back up 1 second // Turn left about 60 degrees // Otherwise, no whisker contact // Forward 1/50 of a second } void forward(int
Chapter 5 • Tactile Navigation with Whiskers == 0)). Translated to English, it reads “if the wLeft variable AND the wRight variable both equal zero.” If both variables are zero, the two calls in the if statement’s code block get executed: backward(1000) and turnLeft(800).
Tactile Navigation with Whiskers • Chapter 5 forward(20); // Forward 1/50 of a second } The forward, backward, turnLeft and turnRight functions were introduced in Chapter 4, Activity 5: Simplify Navigation with Functions on page 118, and are used in the MovementsWithSimpleFunctions sketch. These functions certainly simplified the coding. (Hopefully, they also help demonstrate that all the navigation coding practice from Chapter 4 has its uses!) Your Turn You can also modify the sketch’s if...else if...
Chapter 5 • Tactile Navigation with Whiskers Remember to set the digital pins to outputs in the setup function so they can actually supply current to the LEDS: pinMode(8, OUTPUT); pinMode(2, OUTPUT); // Left LED indicator -> output // Right LED indicator -> output Activity 4: Artificial Intelligence for Escaping Corners You may have noticed that with the last sketch, the BOE Shield-Bot tends to get stuck in corners.
Tactile Navigation with Whiskers • Chapter 5 #include
Chapter 5 • Tactile Navigation with Whiskers // Whisker Navigation if((wLeft == 0) && (wRight == 0)) { backward(1000); turnLeft(800); } else if(wLeft == 0) { backward(1000); turnRight(400); } else if(wRight == 0) { backward(1000); turnLeft(400); } else { forward(20); } // If both whiskers contact // Back up 1 second // Turn left about 120 degrees // If only left whisker contact // Back up 1 second // Turn right about 60 degrees // If only right whisker contact // Back up 1 second // Turn left about 60 deg
Tactile Navigation with Whiskers • Chapter 5 How Escaping Corners Works This sketch is a modified version of RoamingWithWhiskers, so we’ll just look at the new code for detecting and escaping corners. First, three global byte variables are added: wLeftOld, wRightOld, and counter. The wLeftOld and wRightOld variables store the whisker states from a previous whisker contact so that they can be compared with the states of the current contact.
Chapter 5 • Tactile Navigation with Whiskers if((wLeft != wLeftOld) && (wRight != wRightOld)) { counter++; // Increase count by one wLeftOld = wLeft; // Record current for next rep wRightOld = wRight; If this is the fourth consecutive alternate whisker contact, then it’s time to reset the counter variable to 0 and execute a U-turn. When the if(counter == 4) statement is true, its code block tricks the whisker navigation routine into thinking both whiskers are pressed.
Tactile Navigation with Whiskers • Chapter 5 statement also has an else condition with a block that sets counter to zero if the whisker values are not opposite from those of the previous contact.
Chapter 5 • Tactile Navigation with Whiskers Chapter 5 Summary This chapter introduced the first sensor system for the BOE Shield-Bot, and allowed the robot to roam around on its own and navigate by touch.
Tactile Navigation with Whiskers • Chapter 5 4. 5. What statements did this chapter use to call different navigation functions based on whisker states? What is the purpose of having nested if statements? Exercises 1. 2. 3. 4. Write a routine that uses a single variable named whiskers to track whisker contacts. It should store a 3 when no whiskers are contacted, a 2 if the right whisker is contacted, a 1 if the left whisker is contacted, or 0 if both whiskers are contacted.
Chapter 5 • Tactile Navigation with Whiskers 5. If one condition turns out to be true, the code might need to evaluate another condition with a nested if statement. Exercise Solutions 1. Since digitalRead returns 1 or 0, your code can multiply digitalRead(5) by 2 and store the result in the whiskers variable. It can then add the result of digitalRead(7) to the whiskers variable and the result will be 3 for no whiskers.
Tactile Navigation with Whiskers • Chapter 5 backward(1000); turnLeft(800); } else if(wLeft == 0) { pause(500); backward(1000); turnRight(400); } else if(wRight == 0) { pause(500); backward(1000); turnLeft(400); } else { forward(20); } // Back up 1 second // Turn left about 120 degrees // If only left whisker contact // Pause motion for 0.5 seconds // Back up 1 second // Turn right about 60 degrees // If only right whisker contact // Pause motion for 0.
Chapter 5 • Tactile Navigation with Whiskers turnRight(400); } else if(wRight == 0) { pause(500); backward(1000); turnLeft(400); } else { forward(20); } // Turn right about 60 degrees // If only right whisker contact // Pause motion for 0.5 seconds // Back up 1 second // Turn left about 60 degrees // Otherwise, no whisker contact // Forward 1/50 of a second } Project Solutions 1. The key to solving this problem is to write a statement that makes a beep with the required parameters.
Tactile Navigation with Whiskers • Chapter 5 tone(4, 4000, 100); pause(200); tone(4, 4000, 100); pause(200); backward(1000); turnLeft(800); } else if(wLeft == 0) { tone(4, 4000, 100); pause(200); backward(1000); turnRight(400); } else if(wRight == 0) { tone(4, 4000, 100); pause(200); backward(1000); turnLeft(400); } else { forward(20); } // // // // // // Play Stop Play Stop Back Turn a 0.1 ms tone for 0.2 seconds a 0.1 ms tone for 0.
Chapter 5 • Tactile Navigation with Whiskers void backward(int time) { servoLeft.writeMicroseconds(1300); servoRight.writeMicroseconds(1700); delay(time); } 2. // // // // // Backward function // Left wheel clockwise // Right wheel counterclockwise // Maneuver for time ms Start with the Circle sketch, from the Chapter 4 Project Solutions that begin on page 144.
Tactile Navigation with Whiskers • Chapter 5 void loop() { int wLeft = digitalRead(5); int wRight = digitalRead(7); // Main loop auto-repeats // Nothing needs repeating if(wLeft == 0) { turn -= 10; } else if(wRight == 0) { turn += 10; } // Arc to the right servoLeft.writeMicroseconds(1600); // Left wheel counterclockwise servoRight.writeMicroseconds(1438 + turn); // Rt wheel clockwise slower delay(50); // ...for 25.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Chapter 6. Light-Sensitive Navigation with Phototransistors Light sensors have many applications in robotics and industrial control: finding the edge of a roll of fabric in a textile mill, determining when to activate streetlights at different times of the year, when to take a picture, or when to deliver water to a crop of plants.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Introducing the Phototransistor A transistor is like a valve that regulates the amount of electric current that passes through two of its three terminals. The third terminal controls just how much current passes through the other two. Depending on the type of transistor, the current flow can be controlled by voltage, current, or in the case of the phototransistor, by light.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Light Waves In the ocean, you can measure the distance between the peaks of two adjacent waves in feet or meters. With light, which also travels in waves, the distance between adjacent peaks is measured in nanometers (nm) which are billionths of meters. The figure below shows the wavelengths for colors of light we are familiar with, along with some the human eye cannot detect, such as ultraviolet and infrared.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Ambient means ‘existing or present on all sides’ according to Merriam Webster’s dictionary. For the light level in a room, think about ambient light as the overall level of brightness.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Flat Spot, Shorter Pin Disconnect the battery pack and programming cable from your Arduino, and set the BOE Shield’s switch to 0. Remove the whisker circuits, but leave the piezospeaker circuit in place. Build the circuit shown, using the 2 kΩ resistor. Double-check to make sure you connect the phototransistor’s emitter lead (by the flat spot) to the resistor, and its collector to 5V.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Low light Light getting brighter Bright light Back to low light Reconnect programming cable and battery pack power to your board. Put the BOE Shield’s power switch in position 1. Create and save the PhototransistorVoltage sketch, and run it on your Arduino. Slowly move the flashlight or lamp over the phototransistor, and watch the value of A3 in the Serial Monitor.
Chapter 6 • Light-Sensitive Navigation with Phototransistors void setup() { Serial.begin(9600); } // Built-in initialization block void loop() { Serial.print("A3 = "); Serial.print(volts(A3)); Serial.
Light-Sensitive Navigation with Phototransistors • Chapter 6 #include // Include servo library Servo servoLeft; Servo servoRight; // Declare left and right servos void setup() { tone(4, 3000, 1000); delay(1000); // Built-in initialization block // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.attach(12); // Attach left signal to pin 13 // Attach right signal to pin 12 servoLeft.writeMicroseconds(1700); servoRight.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Example: the analogRead function returns 645; how many volts is that? Answer: 5V 1024 = 3.1494140625 V ≈ 3.15 V V = 645 × The sketches have been calling the volts function with volts(A3). When they do that, they pass A3 to its adPin parameter. Inside the function, analogRead(adPin) becomes analogRead(A3). It returns a value in the 0 to 1023 range that represents the voltage applied to A3.
Light-Sensitive Navigation with Phototransistors • Chapter 6 The Arduino Map Function In the PhototransistorVoltage sketch, we converted measurements from the 0 to 1023 range to the 0.0 to 4.995 volt range for display. For other applications, you might need to convert the value to some other range of integers so that your sketch can pass it to another function, maybe for motor control, or maybe for more analysis. That's where the Arduino’s map function comes in handy.
Chapter 6 • Light-Sensitive Navigation with Phototransistors If you replace the 2 kΩ resistor with a 1 kΩ resistor, V A3 will see smaller values for the same currents. In fact, it will take twice as much current to get V A3 to the same voltage level, which means the light will have to be twice as bright to reach the 3.5 V level, the default voltage in HaltUnderBrightLight to make the BOE Shield-Bot stop. So, a smaller resistor in series with the phototransistor makes the circuit less sensitive to light.
Light-Sensitive Navigation with Phototransistors • Chapter 6 measured in ohms which is abbreviated with the Greek letter omega (Ω). The current levels you are likely to see through this circuit are in milliamps (mA). The lower-case m indicates that it’s a measurement of thousandths of amps. Similarly, the lower-case k in kΩ indicates that the measurement is in thousands of ohms.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Example 2: 1 = 0.25 mA and R = 2 kΩ V A3 = I × R = 0. 25mA× 2 kΩ 0. 25 A × 2000 Ω 1000 = 0. 25 A × 2 Ω = 0. 5 AΩ = 0. 5 V = Your Turn – Ohm’s Law and Resistor Adjustments Let’s say that the ambient light in your room is twice as bright as the light that resulted in V A3 = 3.5 V for bright light and 0.5 V for shade. Another situation that could cause higher current is if the ambient light is a stronger source of infrared.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Introducing the Capacitor A capacitor is a device that stores charge, and it is a fundamental building block of many circuits. Batteries are also devices that store charge, and for these activities it will be convenient to think of capacitors as tiny batteries that can be charged, discharged, and recharged. How much charge a capacitor can store is measured in farads (F).
Chapter 6 • Light-Sensitive Navigation with Phototransistors Parts List (2) phototransistors (2) capacitors, 0.1 μF (104) (2) resistors, 1 kΩ (brown-black-red) (2) jumper wires Disconnect batteries and programming cable from your board. Remove the old phototransistor circuit, and build the circuits shown below. Double-check your circuits against the wiring diagram to make sure your phototransistors are not plugged in backwards, and that the leads are not touching.
Light-Sensitive Navigation with Phototransistors • Chapter 6 About Charge Transfer and the Phototransistor Circuit Think of each capacitor in this circuit as a tiny rechargeable battery, and think of each phototransistor as a light-controlled current valve. Each capacitor can be charged to 5 V and then allowed to drain through its phototransistor.
Chapter 6 • Light-Sensitive Navigation with Phototransistors QT Circuit: A common abbreviation for charge transfer is QT. The letter Q refers to electrical charge (an accumulation of electrons), and T is for transfer. Connected in Parallel: The phototransistor and capacitor shown above are connected in parallel; each of their leads are connected to common terminals (also called nodes).
Light-Sensitive Navigation with Phototransistors • Chapter 6 If there’s no output to the Serial Monitor, or if it is just stuck at one value regardless of light level, there could be a wiring error. Double-check your circuit (and your code too, if you hand-entered it.) Move the object casting the shadow closer to the top of the phototransistor to make the shadow darker. Make a note of the measurement. Experiment with progressively darker shadows, even cupping your hand over the phototransistor.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Your Turn: Test the Other Phototransistor Circuit Before moving on to navigation, you’ll need to run the same test on the right (pin 6) light sensor circuit. Both circuits have to be working well before you can move on to using them for navigation—there’s that subsystem testing again! In the rcTime call, change the pin parameter from 8 to 6. Change all instances of tLeft to tRight.
Light-Sensitive Navigation with Phototransistors • Chapter 6 A charge transfer measurement takes seven steps: (1) (2) (3) (4) (5) (6) (7) { Set the I/O pin high to charge the capacitor. Wait long enough for the capacitor to charge. Change the I/O pin to input. Check the time. Wait for the voltage to decay and pass below the Arduino’s 2.1 V threshold. Check the time again. Subtract the step-3 time from the step-6 time. That’s the amount of time the decay took.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Optional Advanced Topic: Voltage Decay Graphs The next graph shows the BOE Shield-Bot’s left and right QT circuit voltage responses while the BothLightSensors sketch is running. The device that measures and graphs these voltage responses over time is called an oscilloscope. The two lines that graph the two voltage signals are called traces.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Activity 3: Light Measurements for Roaming We now have circuits that can work under a variety of lighting conditions. Now we need some code that can adapt as well. An example of sketch code that cannot adapt to change would be: if(tLeft > 2500)… // Not good for navigation. Maybe that statement would work well for turning away from shadows in one room, but take it to another with brighter lights, and it might never detect a shadow.
Chapter 6 • Light-Sensitive Navigation with Phototransistors The final measurement will be stored in a floating point variable named ndShade, so that gets declared first. Then, the next line does the zero-justified normalized differential shade math. The result will be a value in the –0.5 to +0.5 range that represents the fraction of total shade that tRight detects, compared to tLeft. When ndShade is 0, it means tRight and tLeft are the same values, so the sensors are detecting equally bright light.
Light-Sensitive Navigation with Phototransistors • Chapter 6 /* * Robotics with the BOE Shield - LightSensorValues * Displays tLeft, ndShade and tRight in the Serial Monitor. */ void setup() { tone(4, 3000, 1000); delay(1000); // Built-in initialization block // Play tone for 1 second // Delay to finish tone Serial.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Light Measurement Graphic Display The Serial Monitor screen capture below shows an example of a graphical display of the ndShade variable. The asterisk will be in the center of the -0.5 to +0.5 scale if the light or shade is the same over both sensors. If the shade is darker over the BOE Shield-Bot’s right sensor, the asterisk will position to the right in the scale. If it’s darker over the left, the asterisk will position toward the left.
Light-Sensitive Navigation with Phototransistors • Chapter 6 tone(4, 3000, 1000); delay(1000); Serial.begin(9600); // Play tone for 1 second // Delay to finish tone // Set data rate to 9600 bps } void loop() { float tLeft = float(rcTime(8)); float tRight = float(rcTime(6)); // Main loop auto-repeats // Get left light & make float // Get right light & make float float ndShade; // Normalized differential shade ndShade = tRight / (tLeft+tRight) - 0.5; // Calculate & subtract 0.
Chapter 6 • Light-Sensitive Navigation with Phototransistors ndShade = tRight / (tLeft+tRight) - 0.5; // Calculate & subtract 0.5 Next, this for loop places the cursor in the right place for printing an asterisk. Take a close look at the for loop’s condition. It takes ndShade and multiples it by 40. It also has to add 20 to the value because if ndShade is –0.5, we want that to print with zero leading spaces. So (–0.5 × 40) + 20 = 0.
Light-Sensitive Navigation with Phototransistors • Chapter 6 int speedLeft, speedRight; // Declare speed variables if (ndShade > 0.0) // Shade on right? { // Slow down left wheel speedLeft = int(200.0 - (ndShade * 1000.0)); speedLeft = constrain(speedLeft, -200, 200); speedRight = 200; // Full speed right wheel } This diagram shows an example of how this works when ndShade is 0.125. The left wheel slows down because 200 – (0.125×1000) = 75.
Chapter 6 • Light-Sensitive Navigation with Phototransistors The larger ndShade is, the more it subtracts from 200. That’s not a problem in this example, but if ndShade were 0.45, it would try to store –250 in the speedLeft variable. Since the speeds we’ll want to pass to the maneuver function need to be in the -200 to 200 range, we’ll use the Arduino’s constrain function to prevent speedLeft from going out of bounds: speedLeft = constrain(speedLeft, –200, 200).
Light-Sensitive Navigation with Phototransistors • Chapter 6 About equal light, full speed forward ndShade < 0 shade over left Slow down speedRight ndShade > 0 shade over right Slow down speedLeft Back to almost equal light and nearly full speed forward Example Sketch – Light Seeking Display Make sure the power switch is set to 1. Create, save, and run the sketch LightSeekingDisplay. Open the Serial Monitor.
Chapter 6 • Light-Sensitive Navigation with Phototransistors Serial.begin(9600); // Set data rate to 9600 bps } void loop() { float tLeft = float(rcTime(8)); float tRight = float(rcTime(6)); // Main loop auto-repeats // Get left light & make float // Get right light & make float float ndShade; // Normalized differential shade ndShade = tRight / (tLeft+tRight) - 0.5; // Calculate & subtract 0.5 int speedLeft, speedRight; // Declare speed variables if (ndShade > 0.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Activity 5: Shield-Bot Navigating by Light At this point, the LightSeekingDisplay sketch needs four things to take it from displaying what it’s going to do to actually doing it: Remove the Serial.print calls. Add servo code. Add the maneuver function. Add a call to the loop function to pass speedLeft and speedRight to the maneuver function. The result is the LightSeekingShieldBot sketch.
Chapter 6 • Light-Sensitive Navigation with Phototransistors speedLeft = int(200.0 - (ndShade * 1000.0)); speedLeft = constrain(speedLeft, -200, 200); speedRight = 200; // Full speed right wheel } else // Shade on Left? { // Slow down right wheel speedRight = int(200.0 + (ndShade * 1000.
Light-Sensitive Navigation with Phototransistors • Chapter 6 Here are several more light-sensing navigation ideas for your BOE Shield-Bot that can be made with adjustments to the loop function: To make your BOE Shield-Bot follow shade instead of light, place ndShade = -ndShade right before the if…else statement. Curious about how or why this works? Check out Project 2 at the end of this chapter.
Chapter 6 • Light-Sensitive Navigation with Phototransistors • How to use the Arduino’s constrain function to set upper and lower limits for a variable value Robotics Skills • Using a pair of phototransistors for autonomous sensor navigation in response to light level Engineering Skills • • • Subsystem testing of circuits and code routines The concept of resolution, in the context of the Arduino reporting a 10-bit value from an analog input Using an equation to get a zero-justified normalized differen
Light-Sensitive Navigation with Phototransistors • Chapter 6 8. 9. What happens when the voltage applied to an I/O pin that has been set to input is above or below the threshold voltage? If the amount of charge a capacitor stores decreases, what happens to the voltage at its terminals? Exercises 1. 2. 3. 4. 5. 6. Solve for V A3 if I = 1 mA in the circuit above. Calculate the current through the resistor if V A3 in the circuit above is 4.5 V. Calculate the value of a capacitor that has been stamped 105.
Chapter 6 • Light-Sensitive Navigation with Phototransistors 6. 7. 8. 9. The phototransistor supplies the resistor with more or less current. Change the 2 kΩ resistor to a higher value. If the applied voltage is above the threshold voltage, the input register bit for that pin stores a 1. If it’s below threshold voltage, the input register bit stores a 0. The voltage decreases. Exercise Solutions 1. 2. 3. 4. 5. 6. V = I × R = 0.001 A × 2000 Ω = 2 V. V = I × R → I = V ÷ R = 4.5 ÷ 2000 = 0.00225 A = 2.
Light-Sensitive Navigation with Phototransistors • Chapter 6 float volts(int adPin) // Measures volts at adPin { // Returns floating point voltage return float(analogRead(adPin)) * 5.0 / 1024.0; } 2. The solution for this one is to make a copy of LightSeekingShieldBot, and add one command to the loop function: ndShade = -ndShade. Add it right before the if…else statement. Then, instead of indicating shade to turn away from, it indicates bright light to turn away from.
Chapter 6 • Light-Sensitive Navigation with Phototransistors #include // Include servo library Servo servoLeft; Servo servoRight; // Declare left and right servos void setup() { tone(4, 3000, 1000); delay(1000); // Built-in initialization block servoLeft.attach(13); servoRight.
Light-Sensitive Navigation with Phototransistors • Chapter 6 long time = micros(); while(digitalRead(pin)); time = micros() - time; return time; // // // // Mark the time Wait for voltage < threshold Calculate decay time Returns decay time } // maneuver function void maneuver(int speedLeft, int speedRight, int msTime) { servoLeft.writeMicroseconds(1500 + speedLeft); // Left servo speed servoRight.writeMicroseconds(1500 - speedRight); // Right servo speed if(msTime==-1) // if msTime = -1 { servoLeft.
Chapter 7 • Navigating with Infrared Headlights Chapter 7. Navigating with Infrared Headlights The BOE Shield-Bot can already use whiskers to get around, but it only detects obstacles when it bumps into them. Wouldn’t it be convenient if the BOE Shield-Bot could just “see” objects and then decide what to do about them? Well, that’s what it can do with infrared headlights and eyes like the ones shown below.
Navigating with Infrared Headlights • Chapter 7 A TV remote flashes the IR LED on/off at ≈38 kHz for certain periods of time, with periods of off-time in between. It makes a different flashing/off pattern for each key on the remote. IR Receiver IR LED The TV remote sends messages by flashing the IR LED very fast, at a rate of about 38 kHz (about 38,000 times per second). The IR receiver only responds to infrared if it’s flashing at this rate.
Chapter 7 • Navigating with Infrared Headlights With a button pressed and held, the IR LED doesn’t look any different. Through a digital camera display, the IR LED appears as a bright white light. The pixel sensors inside the digital camera detect red, green, and blue light levels, and the processor adds up those levels to determine each pixel’s color and brightness. Regardless of whether a pixel sensor detects red, green, or blue, it detects infrared.
Navigating with Infrared Headlights • Chapter 7 5V GND Signal Infrared LED 5V GND Signal Infrared Receiver Infrared LED Shield Assembly Check the figure below to make sure you have selected infrared LEDs and not phototransistors. The infrared LED has a taller and more rounded plastic dome, and is shown on the right side of this drawing.
Chapter 7 • Navigating with Infrared Headlights IR Object Detection Circuit The next figures show the IR object detection schematic and wiring diagram. One IR object detector (IR LED and receiver pair) is mounted on each corner of the breadboard closest to the very front of the BOE Shield-Bot. Disconnect the power and programming cables. Build the circuit in the schematic below, using the wiring diagram as a reference for parts placement.
Navigating with Infrared Headlights • Chapter 7 Left anode (+) lead Right anode (+) lead 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. 2. 3. Flash the IR LED on/off at 38 kHz.
Chapter 7 • Navigating with Infrared Headlights 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.
Navigating with Infrared Headlights • Chapter 7 1’s → no object detected 0’s → object detected /* * 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() { tone(4, 3000, 1000); delay(1000); pinMode(10, INPUT); // Built-in initialization block // Play tone for 1 second // Delay to finish tone pinMode(9, OUTPUT); Serial.
Chapter 7 • Navigating with Infrared Headlights 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, go ahead and test the right IR Object Detector (below). If not, go to the Troubleshooting section for help.
Navigating with Infrared Headlights • Chapter 7 Parts List (2) Red LEDs (2) Resistors, 220 Ω (red-red-brown) (misc) Jumper wires Disconnect the programming and power cables. Add the red LED circuits shown in the schematic to the BOE Shield, using the wiring diagram to help with parts placement.
Chapter 7 • Navigating with Infrared Headlights Testing the System There are quite a few components involved in this system, and this increases the likelihood of a wiring error. That’s why it’s important to have a test sketch that shows you what the infrared detectors are sensing. Use this sketch to verify that all the circuits are working before unplugging the BOE Shield-Bot from its programming cable.
Navigating with Infrared Headlights • Chapter 7 delay(100); // 0.
Chapter 7 • Navigating with Infrared Headlights Make sure the battery pack is connected to your Arduino and the BOE Shield’s Power switch is set to 1. Unplug your BOE Shield-Bot from the programming cable, and test again with objects in the area where you plan to make it navigate. Test the detection range with different colored objects.
Navigating with Infrared Headlights • Chapter 7 one of its buttons. If the BOE Shield-Bot responds by sounding the alarm, you know your IR interference sniffer is working. /* * Robotics with the BOE Shield - IrInterferenceSniffer * Test for external sources of IR interference. If IR interference is * detected: Serial Monitor displays warning, piezospeaker plays alarm, * and indicator lights flash.
Chapter 7 • Navigating with Infrared Headlights If the source turns out to be sunlight streaming in through a window, close the blinds and retest, or move your obstacle course to a location that’s well away from the window. Always use this IrInterferenceSniffer to make sure that any area where you are using the BOE Shield-Bot is free of infrared interference.
Navigating with Infrared Headlights • Chapter 7 // Robotics with the BOE Shield - LeftLedOn // Turn on left LED for brightness testing void setup() { tone(4, 3000, 1000); delay(1000); pinMode(8, OUTPUT); digitalWrite(8, HIGH); // Built-in initialization block // Play tone for 1 second // Delay to finish tone // Left indicator LED } void loop() { } // Main loop auto-repeats Testing LED Brightness with Different Resistors Remember to disconnect power and the programming cable before you make changes to a
Chapter 7 • Navigating with Infrared Headlights Replace the 2 kΩ resistors that connect pin 2 and pin 9 to the IR LED anodes with 4.7 kΩ resistors. Determine the furthest distance at which the same sheet of paper is detected, and record your data. Repeat with 1 kΩ resistors, 470 Ω resistors, and 220 Ω resistors. (For the smaller resistor values, they may end up making the detectors so sensitive that they see the table surface in front of your robot.
Navigating with Infrared Headlights • Chapter 7 return ir; } 3. Replace these digitalRead calls: 4. …with these calls to irDetect: 5. Replace all instances of wLeft with irLeft and wRight with irRight. Open RoamingWithWhiskers. Save it as RoamingWithIr. Modify it so that it matches the sketch below. Save the sketch and run it on the Arduino. Disconnect the BOE Shield-Bot from its programming cable. Reconnect the battery pack and move the 3-position switch to position 2.
Chapter 7 • Navigating with Infrared Headlights tone(4, 3000, 1000); delay(1000); // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.
Navigating with Infrared Headlights • Chapter 7 } void turnRight(int time) { servoLeft.writeMicroseconds(1700); servoRight.writeMicroseconds(1700); delay(time); } // Right turn function void backward(int time) { servoLeft.writeMicroseconds(1300); servoRight.
Chapter 7 • Navigating with Infrared Headlights Servo servoLeft; Servo servoRight; // Declare left and right servos void setup() // Built-in initialization block { pinMode(10, INPUT); pinMode(9, OUTPUT); // Left IR LED & Receiver pinMode(3, INPUT); pinMode(2, OUTPUT); // Right IR LED & Receiver tone(4, 3000, 1000); delay(1000); // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.
Navigating with Infrared Headlights • Chapter 7 servoRight.writeMicroseconds(1500 - speedRight); // Right servo speed if(msTime==-1) // If msTime = -1 { servoLeft.detach(); // Stop servo signals servoRight.detach(); } delay(msTime); // Delay for msTime } How FastIrRoaming Works This sketch uses the maneuver function from the TestManeuverFunction sketch. The maneuver function expects three parameters: speedLeft, speedRight, and msTime.
Chapter 7 • Navigating with Infrared Headlights Your Turn Save FastIrRoaming as FastIrRoamingYourTurn. Add code to make the LEDs indicate that the BOE Shield-Bot has detected an object. Try modifying the values that speedLeft and speedRight are set to so that the BOE Shield-Bot does everything at half speed. (Remember that 200 and -200 are overkill, so try 50 for half speed forward and –50 for half speed backward).
Navigating with Infrared Headlights • Chapter 7 Build a course like one shown below. For electrical tape, make a small test patch on a piece of paper first to make sure the infrared detectors cannot see a reflection from it. If it does not reflect infrared, use three strips edge to edge on the poster board with no paper visible between the strips.
Chapter 7 • Navigating with Infrared Headlights If you want to try a tabletop: Try an electrical tape or paint course first! Remember to follow the same steps you followed before running the BOE ShieldBot in the electrical tape or paint delimited course! Always be ready to pick your BOE Shield-Bot up from above as it approaches the edge of the table it’s navigating. If the BOE Shield-Bot tries to drive off the edge, pick it up before it takes the plunge.
Navigating with Infrared Headlights • Chapter 7 void setup() // Built-in initialization block { pinMode(10, INPUT); pinMode(9, OUTPUT); // Left IR LED & Receiver pinMode(3, INPUT); pinMode(2, OUTPUT); // Right IR LED & Receiver tone(4, 3000, 1000); delay(1000); // Play tone for 1 second // Delay to finish tone servoLeft.attach(13); servoRight.
Chapter 7 • Navigating with Infrared Headlights servoRight.detach(); } delay(msTime); // Delay for msTime } How AvoidTableEdge Works Since AvoidTableEdge is just FastIrRoaming with a modified if…else if…else statement in its loop function, let’s look at the two statements side by side.
Navigating with Infrared Headlights • Chapter 7 the left IR detector does see the table, but the right one does not. So the code makes the robot turn left for 0.375 seconds with maneuver(-200, 200, 375). This should make it avoid a drop-off that must have been detected on the right. In response to else if (irRight == 0), FastIrRoaming turns left for 20 ms, taking an incremental step toward avoiding an obstacle on the right.
Chapter 7 • Navigating with Infrared Headlights Programming • • • How to use the familiar Arduino tone function for a new purpose: to modulate an infrared light signal, instead of control the pitch of a sound How to repurpose an existing sketch from one sensor system for use with a different sensor system, so long as both sensors have a similar output signal How to repurpose an existing sketch designed for a specific behavior (avoiding obstacles) to a new behavior (detecting a drop-off) Robotics Skills •
Navigating with Infrared Headlights • Chapter 7 Projects 1. 2. 3. Design a BOE Shield-Bot application that sits still until you wave your hand in front of it, then it starts roaming. Design a BOE Shield-Bot application that slowly rotates in place until it detects an object. As soon as it detects an object, it locks onto and chases the object. This is a classic ‘SumoBot’ behavior.
Chapter 7 • Navigating with Infrared Headlights Project Solutions 1. One approach would be to add this code at the end of the setup function in FastIrRoaming. It will wait until an object is detected before allowing the code to move on to the roaming code in the loop function. int irLeft = 1; int irRight = 1; // Declare IR variables and // initialize both to 1 while((irLeft == 1) && (irRight == 1)) { irLeft = irDetect(9, 10, 38000); irRight = irDetect(2, 3, 38000); } // Wait for detection 2.
Navigating with Infrared Headlights • Chapter 7 else if(irLeft == 0) { maneuver(-200, 200, 20); } else if(irRight == 0) { maneuver(200, -200, 20); } else { maneuver(200, 200, 20); } // If only left side detects // Left toward object 20 ms // If only right side detects // Right toward object 20 ms // Otherwise, no IR detects // Forward 20 ms } 3. The example above goes forward for 20 ms if it does not see the object.
Chapter 7 • Navigating with Infrared Headlights if((irLeft == 0) || (irRight == 0)) { for(int i = 0; i < 5; i++) { digitalWrite(7, HIGH); digitalWrite(8, HIGH); tone(4, 4000, 10); delay(20); digitalWrite(7, LOW); digitalWrite(8, LOW); } } // Repeat 5 times // Turn indicator LEDs on // Sound alarm tone // 10 ms tone, 10 between tones // Turn indicator LEDs off // Roam irLeft = irDetect(9, 10, 38000); irRight = irDetect(2, 3, 38000); // Check for object on left // Check for object on right if((irLeft ==
Robot Control with Distance Detection • Chapter 8 Chapter 8. Robot Control with Distance Detection In the previous chapter, we used the infrared LEDs and receivers to detect whether an object is in the BOE Shield-Bot’s way without actually touching it. Wouldn’t it be nice to also get some distance information from the IR sensors? There is a way to accomplish some rough, close-range detection with the very same IR circuit from the previous chapter.
Chapter 8 • Robot Control with Distance Detection Activity 1: Testing the Frequency Sweep Here's a graph from one specific brand of IR detector’s datasheet (Panasonic PNA4602M; a different brand may have been used in your kit). The graph shows that the IR detector is most sensitive at 38 kHz—its peak sensitivity —at the top of the curve. Notice how quickly the curve drops on both sides of the peak. This IR detector is much less sensitive to IR signals that flash on/off at frequencies other than 38 kHz.
Robot Control with Distance Detection • Chapter 8 In this example, an object is in Zone 3. That means that the object can be detected when 38000 and 39000 Hz is transmitted, but it cannot be detected with 40000, 41000, or 42000 Hz. If you were to move the object into Zone 2, then the object would be detected when 38000, 39000, and 40000 Hz are transmitted, but not with 41000 or 42000 Hz.Z The irDistance function from the next sketch performs distance measurement using the technique shown above.
Chapter 8 • Robot Control with Distance Detection Displaying Both Distances It’s important to test that the detection distances are roughly the same for both IR LED/receiver pairs. They don’t have to be identical, but if they are too far apart, the BOE Shield-Bot might have difficulty following an object in front of it because it will keep trying to turn to one side. More subsystem testing! A common cause of mismatched distance measurement is mismatched resistors used with the IR LEDs.
Robot Control with Distance Detection • Chapter 8 If it turns out that the detection range of one side is twice as far as the other (or more), check the resistors connected to the IR LEDs. You may have a mismatch there; make sure both resistors are 2 kΩ (red-black-red). If there isn’t a mismatch, try adjusting IR LED resistor values until the detection ranges of both sides are in the same neighborhood.
Chapter 8 • Robot Control with Distance Detection int ir = digitalRead(irReceiverPin); delay(1); return ir; // IR receiver -> ir variable // Down time before recheck // Return 1 no detect, 0 detect } Your Turn – More Distance Tests Try measuring the detection range for objects with different colors and textures.
Robot Control with Distance Detection • Chapter 8 Our machine is the BOE Shield-Bot. The measured value we want it to maintain is the distance to the leader-object, with a set point of 2 (for zone 2). The machine’s processor is the Arduino. The IR LED/receiver pairs are the sensors that take distance value measurements to the leader-object.
Chapter 8 • Robot Control with Distance Detection The next time through the loop, the measured distance might change, but that’s okay. Regardless of the measured distance, this control loop will calculate a value that will cause the servo to move to correct any error. The correction is always proportional to the error.
Robot Control with Distance Detection • Chapter 8 Example Sketch: FollowingShieldBot The FollowingShieldBot sketch repeats the proportional control loops just discussed at a rate of about 25 times per second. So, all the proportional control calculations and servo speed updates happen 25 times each second. The result is a BOE Shield-Bot that will follow your hand, a book, or another robot. Create, save, and run the sketch FollowingShieldBot.
Chapter 8 • Robot Control with Distance Detection // Left and right proportional control calculations int driveLeft = (setpoint - irLeft) * kpl; int driveRight = (setpoint - irRight) * kpr; maneuver(driveLeft, driveRight, 20); // Drive levels set speeds } // IR distance measurement function int irDistance(int irLedPin, int irReceivePin) { int distance = 0; for(long f = 38000; f <= 42000; f += 1000) { distance += irDetect(irLedPin, irReceivePin, f); } return distance; } // IR Detection function int irDete
Robot Control with Distance Detection • Chapter 8 const int setpoint = 2; const int kpl = -50; const int kpr = -50; // Target distances // Proportional control constants The convenient thing about declaring constants for these values is that you can change them in one place, at the beginning of the sketch. The changes you make at the beginning of the sketch will be reflected everywhere these constants are used.
Chapter 8 • Robot Control with Distance Detection Follow the Leader Here's a leader BOE Shield-Bot followed by a shadow BOE Shield-Bot. The lead robot is running a modified version of FastIrRoaming, with maneuver speeds reduced to +/- 40. The shadow BOE Shield-Bot is running FollowingShieldBot. One lead robot can string along a chain of 6 or 7 shadow robots. Just add the paper panel to the rest of the shadow BOE Shield-Bots in the chain.
Robot Control with Distance Detection • Chapter 8 /* * Robotics with the BOE Shield - SlowerIrRoamingForLeaderBot * Adaptation of RoamingWithWhiskers with IR object detection instead of * contact switches */ #include
Chapter 8 • Robot Control with Distance Detection int ir = digitalRead(irReceiverPin); delay(1); return ir; // IR receiver -> ir variable // Down time before recheck // Return 1 no detect, 0 detect } void maneuver(int speedLeft, int speedRight, int msTime) { // speedLeft, speedRight ranges: Backward Linear Stop Linear Forward // -200 -100......0......100 200 servoLeft.writeMicroseconds(1500 + speedLeft); // Left servo speed servoRight.
Robot Control with Distance Detection • Chapter 8 Shield-Bot Roaming with PING))) A PING))) Ultrasonic Distance Sensor on a servo turret mounts on the front of the Shield-Bot, for autonomous navigation. The ultrasonic distance sensor detects objects up to 10 feet (3 m) away. When an obstacle is detected, the Shield-Bot stops, sweeps the sensor from side to side, and then turns down the clear path.
Chapter 8 • Robot Control with Distance Detection IR Remote Controlled Shield-Bot A simple universal remote control, programmed to use the Sony protocol, can also control your Shield-Bot using the same IR Receiver included in the kit. The project code allows you to switch between 3 modes on the go: remote control, autonomous roaming with object avoidance, and follow-the-leader behavior. http://learn.parallax.
Robot Control with Distance Detection • Chapter 8 Chapter 8 Summary This chapter used the infrared IR LED/receiver pairs for simple distance detection, to make a BOE Shield-Bot shadow vehicle.
Chapter 8 • Robot Control with Distance Detection 3. 4. 5. 6. What statement is used to sweep through the list of frequencies used for IR distance measurements? What’s a summing junction? In our closed loop proportional control block diagrams, what two values are used to calculate the error term? How do delays in the loop function contribute to setting the sampling rate? Exercise 1. Write a segment of code that does the frequency sweep for just four frequencies instead of five. 1.
Robot Control with Distance Detection • Chapter 8 Project Solution 1. One quick and simple solution would be to average the driveLeft and driveRight values in the FollowingShieldBot sketch. The resulting single value can be applied both left and right speed parameters in the maneuver call.
Index • Index For your convenience, this book is available as a free, searchable PDF download from the #122-32335 product page at www.parallax.com. -- decrement operator .............................. 34 ! = not equal operator ............................. 165 ! NOT operato XE "operators:/ division" r 27 #include..................................................... 57 % modulus operator ................................. 27 && boolean AND operator ....................... 31 * multiplication ................
• Index switch/case................................................. 138 tone function .............................................. 221 true ............................................................... 35 variable type ................................................. 24 void setup ..................................................... 21 volts function.............................................. 183 while loop ......................................... 32, 34, 35 writeMicroseconds ...................
Index • Codebender ........................................ 10, 16 collector, phototransistor ....................... 177 comment ................................................... 21 block ............................................................. 36 line ............................................................... 36 purpose of .................................................... 36 comparison of equals ................................ 31 compiler ..............................................
• Index nesting calls ................................................ 154 General Motors .......................................... 6 global variables ......................................... 26 GND .......................................................... 52 GND sockets.............................................. 50 go function.............................................. 138 graph, voltage decay............................... 196 graphic light display ................................
Index • navigation with distance detection......... 254 navigation, following object.................... 254 nearsighted object detection .................. 239 negative numbers ..................................... 28 nesting function calls .............................. 154 noise, in measurements .......................... 252 normalized differential measurement .... 197 normally open switch.............................. 151 Not (!) Operator ...................................... 227 note frequencies ...
• Index resistor ...................................................... 47 color code value ........................................... 48 tolerance ...................................................... 47 resolution, A/D ....................................... 183 result values.............................................. 28 Retrofit Kit ............................................ 9, 43 Robot Hardware Refresher Packs ............. 13 robot kit parts pictures .............................
Index • PlayAllNotesInArray ................................... 132 PlayNotesWithLoop.................................... 131 PlayOneNote .............................................. 130 RightServoClockwise .................................... 67 RightServoStayStill ....................................... 65 RoamingWithIr ........................................... 233 RoamingWithWhiskers ............................... 158 ServoSlowMoCcw .........................................