jmichael

NV-DRD 2.0 Alpha 2

Nov 21st, 2011
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.78 KB | None | 0 0
  1. /*
  2.  *  nv:drd v2.0 alpha 2 by Jason Adams <[email protected]>
  3.  *
  4.  *  DONE:
  5.  *  + complete rewrite of the code for efficiency and reworkability
  6.  *  + the bot now, every so often, spins around like a puppy for a few seconds and goes to sleep
  7.  *  + made the bot stop and do a dance every so often
  8.  *  + created a function that alternately fades and flashes the LEDs
  9.  *  + put blinking and backing-up in their own functions and added the ability to pass
  10.  *    parameters to them to change the number of blinks and the duration of backing-up each time
  11.  *  + created functions for turning left and right, with the ability to pass params (as ints)
  12.  *    to determine how long to turn
  13.  *  + implemented a way to detect that the bot is no longer moving forward and is therefore
  14.  *    likely stuck on something outside its field of view
  15.  *  + the bot takes a forward reading after turning but before moving again, to make sure there
  16.  *    is a fair amount of distance to travel. It then continues to look around and turn
  17.  *    until it detects enough room to move
  18.  *  + found the bug that causes the bot to see a nonexistent obsticle as soon as loop() starts
  19.  *  + the function in which the bot decides which direction to next travel can now be called
  20.  *    in two ways:
  21.  *        1) 'forward' is considered a viable direction to choose
  22.  *        2) 'forward' is ignored and the bot will turn either left or right
  23.  *
  24.  *  TODO:
  25.  *  - tweak the bot's dance, to make it do a better dance and to make the code a bit more efficient
  26.  *    and less monotonous
  27.  *  - correct for the max distance the sensor can return so it doesn't interpret a large,
  28.  *    open room in which it can see to it's farthest ability for a length of time as being stuck
  29.  *  - the bot could determine that it's "still" stuck after making an attempt to back up to free itself,
  30.  *    and therefore make another, different attempt to free itself, say by alternatly backing up each
  31.  *    wheel individually a couple times, and then together. if repeated attempts fail, it can stop and
  32.  *    signal that it knows it's very stuck
  33.  *  - could add a cheap gyroscope chip to determine when the bot has tipped over onto its side, then stop
  34.  *    the wheels and play some kind of LED animation or something
  35.  *
  36.  *  NEEDS TESTING:
  37.  *  x make the trigger mechanism for the bot determining it's stuck less precise than one centimeter.
  38.  *    Maybe make it three cm; one less and one more than the reading taken - ALTHOUGH IT SEEMS TO WORK
  39.  *    VERY WELL, I NEED TO VERIFY THAT THIS CODE WORKS BY WATCHING THE SERIAL OUTPUT
  40.  *
  41.  */
  42.  
  43. char version[] = "nv:drd v2.0 alpha 2";
  44.  
  45. #include <AFMotor.h>
  46. #include <Servo.h>
  47.  
  48.  
  49. // create the motor objects
  50. AF_DCMotor motor1(1, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
  51. AF_DCMotor motor2(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
  52. Servo headTurner;                    // create servo object for turning the Ping))) sensor
  53.  
  54.  
  55. // the calibrated servo motor positions for forward, left, and right.
  56. #define forward  99
  57. #define left     180
  58. #define right    20
  59.  
  60.  
  61. // pin assignments
  62. #define servoPin          9     // servo motor on pin 9
  63. #define pingSensorPin     19    // Ping))) sensor on A5 (analog pins 0-5 can be used as digital pins 14-19)
  64. #define leftAntennaeLED   6
  65. #define rightAntennaeLED  5
  66.  
  67.  
  68. // unchanging variables that act as defaults
  69. int noForward           = 0;      // do not consider going forward when choosing the next direction to travel
  70. int yesForward          = 1;      // consider forward as valid a direction as left and right when choosing the next direction
  71. int defaultBrightness   = 50;     // default LED brightness using analogWrite(). the scale is 0-255
  72. int minDistance         = 1500;   // the minimum distance to an object before the bot refuses to go forward anymore
  73. int defaultTurn         = 550;    // the length of time, in milliseconds, to turn left or right after encountering an obsticle
  74. int sleepTurn           = 5000;   // length of time, in milliseconds, to spin around like a puppy before falling asleep
  75. int flinchDuration      = 300;    // the length of time, in milliseconds, that the bot jumps back after detecting an obsticle
  76.                                   // in front of it
  77. int stuckBackup         = 2000;   // the length of time, in milliseconds, that the bot backs up after deciding it's stuck
  78.  
  79.  
  80. // changing variables
  81. boolean switchTurn      = false;  // false = right, true = left - this bool is for alternating the direction
  82.                                   // the bot decides to turn when the right and left readings are the same.
  83.                                   // One time it'll go right, the next time left, etc.
  84. boolean allowStuckCheck = false;  // this gets flipped to true after the Ping))) sensor has recorded
  85.                                   // distances (converted to cm) in all four of the ints below. it then
  86.                                   // gets flipped false again after running the block of code that gets run
  87.                                   // when the bot attempts to get unstuck. this will prevent it from immediately
  88.                                   // thinking it's stuck again
  89. int directionToGo       = 0;      // 0 = forward, 1 = left, 2 = right
  90. int sleepTimer          = 0;      // a counter to increment until the next time the bot stops and "sleeps"
  91. int danceTimer          = 0;      // a counter to increment until the next time the bot dances
  92. int logTimer            = 0;      // a counter to regulate the logging of forward Ping))) sensor readings
  93. int counterToConfusion  = 0;      // a counter to trigger he "confused" LED animation after multiple failed
  94.                                   // attempts to turn to a direction that offers enough room to move forward
  95. int storeFRead1         = 0;      // <- these four are for storing the forward distance readings to aid the bot
  96. int storeFRead2         = 0;      // <- in determining whether it is stuck on something outside its detection
  97. int storeFRead3         = 0;      // <- range
  98. int storeFRead4         = 0;      // <-
  99. long pingSensorReading, forwardReading, leftReading, rightReading; // these store the ping sensor readings
  100.  
  101.  
  102. // setup() (gets run once)
  103. void setup() {
  104.   // initiate the LEDs
  105.   pinMode(leftAntennaeLED, OUTPUT);
  106.   pinMode(rightAntennaeLED, OUTPUT);
  107.  
  108.   // set up Serial library at 9600 bps
  109.   Serial.begin(9600);
  110.   Serial.println(version);
  111.  
  112.   // set the speeds to 200/255
  113.   motor1.setSpeed(255);
  114.   motor2.setSpeed(255);
  115.  
  116.   // attach the servo object to the pin the servo motor is on
  117.   headTurner.attach(servoPin);
  118.   delay(100);
  119.  
  120.   // turn Ping))) sensor forward, just to orient it for show immediately upon starting  
  121.   headTurner.write(forward);
  122.  
  123.   // turn antennae lights on
  124.   analogWrite(leftAntennaeLED, defaultBrightness);
  125.   analogWrite(rightAntennaeLED, defaultBrightness);
  126.  
  127.   // choose which direction to go
  128.   chooseDirection(yesForward);
  129.  
  130.   // travel forward
  131.   goForward();
  132.  
  133.   // travel forward for at least one second. this helps squash the fantom-obsticle bug that appears between setup() and loop()
  134.   delay(1000);
  135. }
  136.  
  137.  
  138. // loop() (gets run repeatedly)
  139. void loop() {
  140.   // see if we're nearing an object while moving forward
  141.   forwardReading = readPingSensor();
  142.   Serial.print("forward reading: ");
  143.   Serial.println(forwardReading);
  144.   delay(100);
  145.  
  146.   // increment the timer that helps decide when to next stop and go to sleep
  147.   sleepTimer++;
  148.  
  149.   // increment the timer that helps decide when it's time to DANCE!
  150.   danceTimer++;
  151.  
  152.   // increment the timer that triggers storing of forwardReading values, to help determine we might be stuck
  153.   logTimer++;
  154.  
  155.   // log every fifth forward reading to see if we're making any forward progress or possibly stuck on an object outside the sensor's view
  156.   if (logTimer == 5) {
  157.     storeFRead4 = storeFRead3;
  158.     storeFRead3 = storeFRead2;
  159.     storeFRead2 = storeFRead1;
  160.     storeFRead1 = (forwardReading * 0.03434);
  161.  
  162.     // announce the readings to serial
  163.     Serial.println("");
  164.     Serial.print("storeFRead1: ");
  165.     Serial.println(storeFRead1);
  166.     Serial.print("storeFRead2: ");
  167.     Serial.println(storeFRead2);
  168.     Serial.print("storeFRead3: ");
  169.     Serial.println(storeFRead3);
  170.     Serial.print("storeFRead4: ");
  171.     Serial.println(storeFRead4);
  172.     Serial.println("");
  173.    
  174.     /* THIS HAS NOT BEEN TESTED */ /* IT SEEMS TO WORK IN PRACTICE, BUT NEEDS TO BE VERIFIED BY WATCHING SERIAL */
  175.     // this will allow for the log entries to be considered the same if they're one cm more or less than the newer reading, creating
  176.     // a slightly "fuzzier" log in hopes of better determining when the bot is stuck
  177.     Serial.println("");
  178.     Serial.println("altering the log to fuzzy the readings a little");
  179.     if (storeFRead2 == storeFRead1 + 1 || storeFRead2 == storeFRead1 - 1) { storeFRead2 = storeFRead1; }
  180.     if (storeFRead3 == storeFRead2 + 1 || storeFRead3 == storeFRead2 - 1) { storeFRead3 = storeFRead2; }
  181.     if (storeFRead4 == storeFRead3 + 1 || storeFRead4 == storeFRead3 - 1) { storeFRead4 = storeFRead3; }
  182.  
  183.     // announce the new readings to serial so we can see the difference
  184.     Serial.println("");
  185.     Serial.print("new storeFRead1: ");
  186.     Serial.println(storeFRead1);
  187.     Serial.print("new storeFRead2: ");
  188.     Serial.println(storeFRead2);
  189.     Serial.print("new storeFRead3: ");
  190.     Serial.println(storeFRead3);
  191.     Serial.print("new storeFRead4: ");
  192.     Serial.println(storeFRead4);
  193.     Serial.println("");
  194.     /* END CODE THAT HASN'T BEEN TESTED */
  195.    
  196.     // reset the log timer so this logging only happens every 5 readings
  197.     logTimer = 0;
  198.    
  199.     // now that we have an updated set of  readings, we'll allow the code below to analyz them. otherwise it will be skipped
  200.     allowStuckCheck = true;
  201.   }
  202.  
  203.   // see if it looks like we're no longer making forward progress, indicating we may be stuck
  204.   if (allowStuckCheck == true && storeFRead1 == storeFRead2 && storeFRead2 == storeFRead3 && storeFRead3 == storeFRead4) {
  205.     // see if it looks like we're in a very large open area, rather than stuck
  206.     //if (test one of the variables above to see if it is at the highest end of the Ping))) sensor's range) {
  207.       //Serial.println("it appears i'm in a very large room or outside);
  208.     //} else {
  209.       Serial.println("oops! i think i'm stuck!");
  210.  
  211.       allStop(); // stop moving
  212.       blinkLEDs(2); // blink
  213.       goReverse(stuckBackup); // back up
  214.    
  215.       // choose between turning left or right, whichever offers the farthest distance to move
  216.       chooseDirection(noForward);
  217.    
  218.       // travel forward
  219.       goForward();
  220.      
  221.       // I THINK RESETTING THESE VARS IS NOT NECESSARY BECAUSE THE dontAllowStuck BOOL BELOW SERVES THE SAME PURPOSE,
  222.       // BUT ACTUALLY EFFECTIVELY. HOWEVER, I COULD BE WRONG ATM
  223.       // reset the logging variables so a full examination is required again to determine if we're stuck
  224.       storeFRead4 = 0;
  225.       storeFRead3 = 0;
  226.       storeFRead2 = 0;
  227.      
  228.       allowStuckCheck = false;
  229.     //}
  230.    
  231.     // if we are nearing an object, stop moving...
  232.   } else if (forwardReading <= minDistance) {
  233.     Serial.println("i see something getting close!");
  234.  
  235.     allStop(); // stop moving
  236.     blinkLEDs(2); // blink
  237.     goReverse(flinchDuration); // back up
  238.  
  239.     chooseDirection(noForward); // choose a new direction; left or right only
  240.    
  241.     goForward(); // travel forward
  242.  
  243.     // see if it's time to sleep yet
  244.   } else if (sleepTimer >= 900) {
  245.     // go to sleep roughly every five minutes (900 seconds)
  246.     /* (I put this inside an 'else if' in order to avoid the bot sleeping immediately after detecting that it's stuck or
  247.        too close to an object. It will catch the next time around, considering neither of the other two conditions are met) */
  248.     stopAndSleep(); // stop and sleep
  249.  
  250.     sleepTimer = 0; // reset the sleep timer variable
  251.  
  252.     chooseDirection(yesForward); // choose a new direction; left, right, or forward
  253.    
  254.     goForward(); // travel forward    
  255.     // see if it's time to sleep yet
  256.   } else if (danceTimer >= 500) {
  257.     // dance every 1000 times through the loop
  258.     /* (I put this inside an 'else if' in order to avoid the bot danceing immediately after detecting that it's stuck or
  259.        too close to an object. It will catch the next time around, considering neither of the other two conditions are met) */
  260.     allStop();
  261.    
  262.     Serial.println("i think it's time to DANCE!");
  263.    
  264.     dance(); // dance
  265.  
  266.     danceTimer = 0; // reset the dance timer variable
  267.  
  268.     chooseDirection(yesForward); // choose a new direction; left, right, or forward
  269.    
  270.     goForward(); // travel forward    
  271.   }
  272.  
  273.   // wait 3/10 of a second so the Ping))) sensor gets polled 3x/sec when driving forward.
  274.   // (this delay combined with the 100 millisecond delay taken immediately after the forward reading
  275.   // combine to make 333 milliseconds)
  276.   delay(233);
  277. }
  278.  
  279.  
  280. /*
  281.   FUNCTIONS:
  282.     chooseDirection(int)           // Tested
  283.     stopAndSleep()                 // Tested
  284.     dance()                        // Tested
  285.     readPingSensor()               // Tested
  286.     alternatingLEDs(int)           // Tested
  287.     snoreLEDs(int)                 // Tested
  288.     blinkLEDs(int)                 // Tested
  289.     goForward()                    // Tested
  290.     goReverse(int)                 // Tested
  291.     turnLeft(int)                  // Tested
  292.     turnRight(int)                 // Tested
  293.     allStop()                      // Tested
  294. */
  295.  
  296.  
  297. void chooseDirection(int considerForwardDirection) {
  298.   // turn Ping))) sensor to look forward and then take a reading
  299.   headTurner.write(forward);
  300.   delay(500);
  301.   forwardReading = readPingSensor();
  302.   Serial.print("forward reading: ");
  303.   Serial.println(forwardReading);
  304.   delay(250);
  305.  
  306.   // turn Ping))) sensor to look left and then take a reading
  307.   headTurner.write(left);
  308.   delay(500);
  309.   leftReading = readPingSensor();
  310.   Serial.print("left reading: ");
  311.   Serial.println(leftReading);
  312.   delay(250);
  313.  
  314.   // turn Ping))) sensor to look right and then take a reading
  315.   headTurner.write(right);
  316.   delay(650);
  317.   rightReading = readPingSensor();
  318.   Serial.print("right reading: ");
  319.   Serial.println(rightReading);
  320.   delay(250);
  321.  
  322.   if (forwardReading <= minDistance && leftReading <= minDistance && rightReading <= minDistance) {
  323.  
  324.     if (leftReading > rightReading) {
  325.       turnLeft(defaultTurn);
  326.     } else if (leftReading < rightReading) {
  327.       turnRight(defaultTurn);
  328.     } else if (leftReading == rightReading) {
  329.       if (switchTurn == false) {
  330.         Serial.println("  right and left readings are the same; going right this time");
  331.         turnRight(defaultTurn);
  332.       } else {
  333.         Serial.println("  right and left readings are the same; going left this time");
  334.         turnLeft(defaultTurn);
  335.       }
  336.       switchTurn = !switchTurn;
  337.     }
  338.  
  339.     while (forwardReading <= minDistance && leftReading <= minDistance && rightReading <= minDistance ){
  340.      
  341.       // keep track of when to, and then play, the 'confusion' LED animation after multiple unsuccessful attempts
  342.       // to turn in a direction that offers enough space to start moving
  343.       counterToConfusion++;
  344.       if (counterToConfusion == 3) {
  345.         headTurner.write(forward);
  346.         delay(500);
  347.         alternatingLEDs(5);
  348.         counterToConfusion = 0;
  349.       }
  350.      
  351.       // turn Ping))) sensor to look forward and then take a reading
  352.       headTurner.write(forward);
  353.       delay(500);
  354.       forwardReading = readPingSensor();
  355.       Serial.print("*forward reading: ");
  356.       Serial.println(forwardReading);
  357.       delay(250);
  358.      
  359.       // turn Ping))) sensor to look left and then take a reading
  360.       headTurner.write(left);
  361.       delay(500);
  362.       leftReading = readPingSensor();
  363.       Serial.print("*left reading: ");
  364.       Serial.println(leftReading);
  365.       delay(250);
  366.        
  367.       // turn Ping))) sensor to look right and then take a reading
  368.       headTurner.write(right);
  369.       delay(650);
  370.       rightReading = readPingSensor();
  371.       Serial.print("*right reading: ");
  372.       Serial.println(rightReading);
  373.       delay(250);
  374.  
  375.       // compare the 'forward' and 'left' readings to see which direction offers more distance to travel
  376.       if (forwardReading >= leftReading) {
  377.         directionToGo = 0;
  378.         Serial.println("* determining i'd rather go forward than left");
  379.       } else {
  380.         directionToGo = 1;
  381.         Serial.println("* determining i'd rather go left than forward");
  382.       }
  383.  
  384.       // compare the 'right' reading to the winner of the previous comparison to see which direction we should go
  385.       if (directionToGo == 0 && rightReading > forwardReading) {
  386.         Serial.println("* determining i should go right instead of forward");
  387.         turnRight(defaultTurn);
  388.         if (rightReading > minDistance) { break; }
  389.       } else if (directionToGo == 1 && rightReading > leftReading) {
  390.         Serial.println("* determining i should go right instead of left");
  391.         turnRight(defaultTurn);
  392.         if (rightReading > minDistance) { break; }
  393.       } else if (directionToGo == 1 && rightReading < leftReading) {
  394.         Serial.println("* determining i should go left instead of right");
  395.         turnLeft(defaultTurn);
  396.         if (leftReading > minDistance) { break; }
  397.       } else if (directionToGo == 1 && rightReading == leftReading) {
  398.         if (switchTurn == false) {
  399.           Serial.println("* right and left readings are the same; going right this time");
  400.           turnRight(defaultTurn);
  401.         } else {
  402.           Serial.println("* right and left readings are the same; going left this time");
  403.           turnLeft(defaultTurn);
  404.         }
  405.         switchTurn = !switchTurn;
  406.         if (leftReading > minDistance) { break; }
  407.       } else if (directionToGo == 0 && rightReading <= forwardReading && leftReading <= forwardReading) {
  408.         if (forwardReading > minDistance) {
  409.           break;
  410.         } else {
  411.           if (switchTurn == false) {
  412.             Serial.println("* forward reading was the largest, but i have to turn; going right this time");
  413.             turnRight(defaultTurn);
  414.           } else {
  415.             Serial.println("* forward reading was the largest, but i have to turn; going left this time");
  416.             turnLeft(defaultTurn);
  417.           }
  418.           switchTurn = !switchTurn;
  419.         }
  420.       }
  421.     }
  422.   } else {
  423.  
  424.     // if the function was called with 'noForward' (aka 0), choose between left and right, ignoring forward
  425.     if (considerForwardDirection == 0) {
  426.       // compare the 'left' and 'right' readings to see which direction offers more distance to travel.
  427.       // we ignore 'forward' here because it's very unsatisfying seeing the bot choose to go forward after
  428.       // having just stopped because it detected an obsticle
  429.       if (leftReading > rightReading) {
  430.         Serial.println("  determining i'd rather go left than right");
  431.         turnLeft(defaultTurn);
  432.       } else if (leftReading < rightReading) {
  433.         Serial.println("  determining i'd rather go right than left");
  434.         turnRight(defaultTurn);
  435.       } else if (leftReading == rightReading) {
  436.         if (switchTurn == false) {
  437.           Serial.println("  right and left readings are the same; going right this time");
  438.           turnRight(defaultTurn);
  439.         } else {
  440.           Serial.println("  right and left readings are the same; going left this time");
  441.           turnLeft(defaultTurn);
  442.         }
  443.         switchTurn = !switchTurn;
  444.       }
  445.       // if the function was called with 'yesForward' (aka 1), consider forward when choosing which direction to next travel
  446.     } else if (considerForwardDirection == 1) {
  447.       // compare the 'forward' and 'left' readings to see which direction offers more distance to travel
  448.       if (forwardReading >= leftReading) {
  449.         directionToGo = 0;
  450.         Serial.println("  determining i'd rather go forward than left");
  451.       } else {
  452.         directionToGo = 1;
  453.         Serial.println("  determining i'd rather go left than forward");
  454.       }
  455.    
  456.       // compare the 'right' reading to the winner of the previous comparison to see which direction we should go
  457.       if (directionToGo == 0 && rightReading > forwardReading) {
  458.         Serial.println("  determining i should go right instead of forward");
  459.         turnRight(defaultTurn);
  460.       } else if (directionToGo == 1 && rightReading > leftReading) {
  461.         Serial.println("  determining i should go right instead of left");
  462.         turnRight(defaultTurn);
  463.       } else if (directionToGo == 1 && rightReading == leftReading) {
  464.         if (switchTurn == false) {
  465.           Serial.println("  right and left readings are the same; going right this time");
  466.           turnRight(defaultTurn);
  467.         } else {
  468.           Serial.println("  right and left readings are the same; going left this time");
  469.           turnLeft(defaultTurn);
  470.         }
  471.         switchTurn = !switchTurn;
  472.       }
  473.     }
  474.   }
  475.  
  476.   // look forward again in preparation for moving forward again
  477.   headTurner.write(forward);
  478.   delay(250);
  479. }
  480.          
  481.  
  482. void stopAndSleep() {
  483.   // announce over serial that it's time to sleep
  484.   Serial.println("getting sleepy. think i'll take a nap right here");
  485.  
  486.   // stop moving forward
  487.   allStop();
  488.   delay(750);
  489.  
  490.   // fade the antennae LEDs to indicate sleepiness
  491.   for(int fadeValue = defaultBrightness; fadeValue >= 0; fadeValue -= 1) {
  492.     analogWrite(leftAntennaeLED, fadeValue);
  493.     analogWrite(rightAntennaeLED, fadeValue);
  494.     delay(75);
  495.   }
  496.   delay(1000);
  497.  
  498.   // choose a direction, left or right, and spin in place like a puppy about to lay down
  499.   if (switchTurn == false){
  500.     turnRight(sleepTurn);
  501.   } else {
  502.     turnLeft(sleepTurn);
  503.   }
  504.  
  505.   // set this bool so the next time the bot will turn the other direction
  506.   switchTurn = !switchTurn;
  507.  
  508.   // orient the head forward
  509.   headTurner.write(forward);
  510.   delay(1000);
  511.  
  512.   snoreLEDs(10);
  513.  
  514.   // fade the LEDs back on quickly, like the bot is waking up
  515.   for(int fadeValue = 0 ; fadeValue <= defaultBrightness; fadeValue +=2) {
  516.     analogWrite(leftAntennaeLED, fadeValue);
  517.     analogWrite(rightAntennaeLED, fadeValue);
  518.     delay(20);
  519.   }
  520.   delay(1000);
  521.  
  522.   blinkLEDs(2);
  523.  
  524.   delay(500);
  525. }
  526.  
  527.  
  528. void dance() {
  529.   // look left twice, then right twice, each time turning off the opposite LED
  530.   for (int n = 0; n < 2; n++) {
  531.     headTurner.write(left);
  532.     analogWrite(rightAntennaeLED, 0);
  533.     delay(400);
  534.     headTurner.write(forward);
  535.     analogWrite(rightAntennaeLED, defaultBrightness);
  536.     delay(400);
  537.   }
  538.   for (int n = 0; n < 2; n++) {
  539.     headTurner.write(right);
  540.     analogWrite(leftAntennaeLED, 0);
  541.     delay(400);
  542.     headTurner.write(forward);
  543.     analogWrite(leftAntennaeLED, defaultBrightness);
  544.     delay(400);
  545.   }
  546.  
  547.   // do the same as above, but also turn the bot's body along with the head movements
  548.   for (int n = 0; n < 2; n++) {
  549.     headTurner.write(left);
  550.     analogWrite(rightAntennaeLED, 0);
  551.     motor1.run(BACKWARD);
  552.     motor2.run(FORWARD);
  553.     delay(400);
  554.     motor1.run(RELEASE);
  555.     motor2.run(RELEASE);
  556.     headTurner.write(forward);
  557.     analogWrite(rightAntennaeLED, defaultBrightness);
  558.     motor1.run(FORWARD);
  559.     motor2.run(BACKWARD);
  560.     delay(400);
  561.     motor1.run(RELEASE);
  562.     motor2.run(RELEASE);
  563.   }
  564.   for (int n = 0; n < 2; n++) {
  565.     headTurner.write(right);
  566.     analogWrite(leftAntennaeLED, 0);
  567.     motor1.run(FORWARD);
  568.     motor2.run(BACKWARD);
  569.     delay(400);
  570.     motor1.run(RELEASE);
  571.     motor2.run(RELEASE);
  572.     headTurner.write(forward);
  573.     analogWrite(leftAntennaeLED, defaultBrightness);
  574.     motor1.run(BACKWARD);
  575.     motor2.run(FORWARD);
  576.     delay(400);
  577.     motor1.run(RELEASE);
  578.     motor2.run(RELEASE);
  579.   }
  580.  
  581.   delay(400);
  582.  
  583.   // spin around
  584.   headTurner.write(left);
  585.   analogWrite(rightAntennaeLED, 0);
  586.   motor1.run(BACKWARD);
  587.   motor2.run(FORWARD);
  588.   delay(1500);
  589.   motor1.run(RELEASE);
  590.   motor2.run(RELEASE);
  591.   headTurner.write(forward);
  592.   analogWrite(rightAntennaeLED, defaultBrightness);
  593.  
  594.   // repeat the second loop (head and body turns)
  595.   // do the same as above, but also turn the bot's body along with the head movements
  596.   for (int n = 0; n < 2; n++) {
  597.     headTurner.write(left);
  598.     analogWrite(rightAntennaeLED, 0);
  599.     motor1.run(BACKWARD);
  600.     motor2.run(FORWARD);
  601.     delay(400);
  602.     motor1.run(RELEASE);
  603.     motor2.run(RELEASE);
  604.     headTurner.write(forward);
  605.     analogWrite(rightAntennaeLED, defaultBrightness);
  606.     motor1.run(FORWARD);
  607.     motor2.run(BACKWARD);
  608.     delay(400);
  609.     motor1.run(RELEASE);
  610.     motor2.run(RELEASE);
  611.   }
  612.   for (int n = 0; n < 2; n++) {
  613.     headTurner.write(right);
  614.     analogWrite(leftAntennaeLED, 0);
  615.     motor1.run(FORWARD);
  616.     motor2.run(BACKWARD);
  617.     delay(400);
  618.     motor1.run(RELEASE);
  619.     motor2.run(RELEASE);
  620.     headTurner.write(forward);
  621.     analogWrite(leftAntennaeLED, defaultBrightness);
  622.     motor1.run(BACKWARD);
  623.     motor2.run(FORWARD);
  624.     delay(400);
  625.     motor1.run(RELEASE);
  626.     motor2.run(RELEASE);
  627.   }
  628.  
  629.   // spin back around the other direction
  630.   headTurner.write(right);
  631.   analogWrite(leftAntennaeLED, 0);
  632.   motor1.run(FORWARD);
  633.   motor2.run(BACKWARD);
  634.   delay(1500);
  635.   motor1.run(RELEASE);
  636.   motor2.run(RELEASE);
  637.   headTurner.write(forward);
  638.   analogWrite(leftAntennaeLED, defaultBrightness);
  639.  
  640.   // pause, then blink, then pause slightly before function ends
  641.   delay(1000);
  642.   blinkLEDs(2);
  643.   delay(500);
  644. }
  645.  
  646.  
  647. long readPingSensor() {
  648.   // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  649.   // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  650.   pinMode(pingSensorPin, OUTPUT);
  651.   digitalWrite(pingSensorPin, LOW);
  652.   delayMicroseconds(2);
  653.   digitalWrite(pingSensorPin, HIGH);
  654.   delayMicroseconds(5);
  655.   digitalWrite(pingSensorPin, LOW);
  656.  
  657.   // The same pin is used to read the signal from the PING))): a HIGH
  658.   // pulse whose duration is the time (in microseconds) from the sending
  659.   // of the ping to the reception of its echo off of an object.
  660.   pinMode(pingSensorPin, INPUT);
  661.   pingSensorReading = pulseIn(pingSensorPin, HIGH);
  662.  
  663.   return pingSensorReading;
  664. }
  665.  
  666.  
  667. void alternatingLEDs(int numFlashes) {
  668.   Serial.println("flashing my antennae lights");
  669.   for (int i = 0; i < numFlashes; i++) {
  670.     for(int fadeValue = 5; fadeValue <= 255; fadeValue +=5) {  // left brightening, right dimming
  671.       analogWrite(leftAntennaeLED, fadeValue);
  672.       analogWrite(rightAntennaeLED, 260 - fadeValue);
  673.       delay(10);
  674.     }
  675.     for(int fadeValue = 5; fadeValue <= 255; fadeValue +=5) {  // left dimming, right brightening
  676.       analogWrite(leftAntennaeLED, 260 - fadeValue);
  677.       analogWrite(rightAntennaeLED, fadeValue);
  678.       delay(10);
  679.     }
  680.   }
  681.   digitalWrite(leftAntennaeLED, LOW);
  682.   digitalWrite(rightAntennaeLED, LOW);
  683.   delay(200);
  684.   analogWrite(leftAntennaeLED, defaultBrightness);
  685.   analogWrite(rightAntennaeLED, defaultBrightness);
  686. }
  687.  
  688.  
  689. void snoreLEDs(int numSnores) {  // "sleep-breathe" the LEDs like a mac
  690.   for (int i = 0; i < numSnores; i++) {
  691.     for(int fadeValue = 0 ; fadeValue <= 15; fadeValue +=1) {  // on
  692.       analogWrite(leftAntennaeLED, fadeValue);
  693.       analogWrite(rightAntennaeLED, fadeValue);
  694.       delay(75);
  695.     }
  696.     for(int fadeValue = 15 ; fadeValue >= 0; fadeValue -=1) {  // off
  697.       analogWrite(leftAntennaeLED, fadeValue);
  698.       analogWrite(rightAntennaeLED, fadeValue);
  699.       delay(75);
  700.     }
  701.     delay(1500);
  702.   }
  703. }
  704.  
  705.  
  706. void blinkLEDs(int numBlinks) {
  707.   Serial.println("blinking");
  708.   for (int i = 0; i < numBlinks; i++) {
  709.     analogWrite(leftAntennaeLED, 0);
  710.     analogWrite(rightAntennaeLED, 0);
  711.     delay(100);
  712.     analogWrite(leftAntennaeLED, defaultBrightness);
  713.     analogWrite(rightAntennaeLED, defaultBrightness);
  714.     delay(100);
  715.   }
  716. }
  717.  
  718.  
  719. void goForward() {
  720.   Serial.println("driving forward");
  721.   motor1.run(FORWARD);
  722.   motor2.run(FORWARD);
  723. }
  724.  
  725.  
  726. void goReverse(int backUpDuration) {
  727.   Serial.println("backing up a little bit");
  728.   motor1.run(BACKWARD);
  729.   motor2.run(BACKWARD);
  730.   delay(backUpDuration);
  731.   motor1.run(RELEASE);
  732.   motor2.run(RELEASE);
  733.   delay(500);
  734. }
  735.  
  736.  
  737. void turnLeft(int turnDuration) {
  738.   headTurner.write(left);   // look left
  739.   delay(300);               // give servo (head) time to turn before beginning turning the bot's body
  740.   Serial.println("turning left");
  741.   // turn left
  742.   motor1.run(BACKWARD);
  743.   motor2.run(FORWARD);
  744.   delay(turnDuration);
  745.   motor1.run(RELEASE);
  746.   motor2.run(RELEASE);
  747.   delay(100);
  748. }
  749.  
  750.  
  751. void turnRight(int turnDuration) {
  752.   headTurner.write(right);   // look right
  753.   delay(300);                // give servo (head) time to turn before beginning turning the bot's body
  754.   Serial.println("turning right");
  755.   // turn right
  756.   motor1.run(FORWARD);
  757.   motor2.run(BACKWARD);
  758.   delay(turnDuration);
  759.   motor1.run(RELEASE);
  760.   motor2.run(RELEASE);
  761.   delay(100);
  762. }
  763.  
  764.  
  765. void allStop() {
  766.   Serial.println("ALL STOP!");  
  767.   motor1.run(RELEASE);
  768.   motor2.run(RELEASE);
  769.   delay(200);
  770. }
  771.  
Advertisement
Add Comment
Please, Sign In to add comment