fork download
  1. #include <Adafruit_CircuitPlayground.h>
  2.  
  3. /* B3_09_Servo_SonicV2.ino
  4.  
  5. Drive the TWO-WHEELED Bread Board Bot (BBbot, B^3)
  6. forward. When within 10 inches of something, turn servos to find clearest path
  7. and then go that way.
  8. When a whisker bump sensor on either side hits something,
  9. back up and turn slightly away from that direction and resume
  10. forward path.
  11.  
  12. Stop at a specified distance from an object directly ahead.
  13.  
  14. Arduino: Arduino Mega 256 v3 Clone
  15. Motor Shield: Adafruit assembled Motor Shield for Arduino v2
  16. ----> http://w...content-available-to-author-only...t.com/products/1438
  17.  
  18. Programmer: Dave Eslinger; June 13, 2015
  19. Revisions: Added sonic sensors on servos, June 23, 2016.
  20. */
  21. #include <Wire.h>
  22. #include <Adafruit_MotorShield.h>
  23. #include <math.h>
  24. #include <BreadBoardBot.h>
  25. #include <NewPing.h>
  26. #include <Servo.h>
  27.  
  28. // Create the motor shield object with the default I2C address
  29. Adafruit_MotorShield AFMS = Adafruit_MotorShield();
  30.  
  31. // Define Servos
  32. Servo panServo;
  33. Servo tiltServo;
  34.  
  35. /* Define Constants */
  36.  
  37. // IO Pins used
  38. const byte LEFT_BUMP_PIN = 47; // Define DIGITAL Pins for left
  39. const byte RIGHT_BUMP_PIN = 46; // and right bump sensors
  40. const byte SONIC_TRIGGER_PIN = 51;
  41. const byte SONIC_ECHO_PIN = 50;
  42.  
  43. // Parameters controlling program behavior
  44. // Bump behavior
  45. const byte FORWARD_SPEED = 100; // Define normal speeds
  46. const byte BACKWARD_SPEED = 60; // and backup/turn speed
  47. const int TURN_DURATION = 600; // Turn length in milliseconds
  48.  
  49. // Sonic sensor
  50. const float TARGET_DISTANCE_INCHES = 10;
  51. const int MAX_SONIC_DISTANCE = 500; // cm, optional, 500 cm is default
  52.  
  53. // Define 'ports' for motors.
  54. const byte LEFT_MOTOR_PORT = 3;
  55. const byte RIGHT_MOTOR_PORT = 1;
  56. // Create pointers to motor control objects
  57. Adafruit_DCMotor *motorLeft = AFMS.getMotor(LEFT_MOTOR_PORT);
  58. Adafruit_DCMotor *motorRight = AFMS.getMotor(RIGHT_MOTOR_PORT);
  59.  
  60. /* Define new untrasonic sensor with trigger & echo pins and
  61. the maximum distance to be sensed. */
  62. NewPing sonic(SONIC_TRIGGER_PIN, SONIC_ECHO_PIN, MAX_SONIC_DISTANCE);
  63.  
  64. /* Define servo pins */
  65. const byte PANSERVOPIN = 10; // Servo 1 on AdaFruit Motor Shield
  66. const byte TILTSERVOPIN = 9; // Servo 2
  67.  
  68. float pingDist; // define variable to use for distance measurements
  69.  
  70.  
  71. void setup(void) {
  72. AFMS.begin(); // create with the default frequency 1.6KHz
  73. // Turn off all motors to start, just a good habit
  74. motorLeft->run(RELEASE);
  75. motorRight->run(RELEASE);
  76.  
  77. panServo.attach(PANSERVOPIN);
  78. tiltServo.attach(TILTSERVOPIN);
  79. panServo.write(90);
  80. tiltServo.write(60);
  81.  
  82. Serial.begin(9600); //Begin serial communcation
  83.  
  84. /*Set up Bump Pins with Arduino internal pullup resistors
  85. This will make them always high unless a bump switch is hit,
  86. which will make a connection to ground and they will read low. */
  87. pinMode(LEFT_BUMP_PIN, INPUT_PULLUP);
  88. pinMode(RIGHT_BUMP_PIN, INPUT_PULLUP);
  89.  
  90. pinMode(SONIC_TRIGGER_PIN, OUTPUT);
  91. pinMode(SONIC_ECHO_PIN, INPUT);
  92. // delay(2000); // Two second delay to get the robot placed
  93. while (digitalRead(RIGHT_BUMP_PIN)) {} // pause until right bump pin hit.
  94. }
  95.  
  96. void loop() {
  97.  
  98. // Test some of the sonic library functions:
  99. Serial.print(sonic.ping_in());
  100. Serial.print(" inches, cm = ");
  101. Serial.print(sonic.ping_cm());
  102. Serial.print(", actual ping time (ms) = ");
  103. int ping_milli = sonic.ping();
  104. Serial.print(ping_milli);
  105. Serial.print(", real inches = ");
  106. Serial.print(Distance_inches(ping_milli));
  107. Serial.print(", real cm = ");
  108. Serial.println(Distance_cm(ping_milli));
  109. // delay(100); // Just to slow things down
  110.  
  111. /* for (int i=0; i<=170; i+=5) {
  112. panServo.write(i);
  113. delay(50);
  114. }
  115. delay(1000);
  116. for (int i=170; i>=0; i-=5) {
  117. panServo.write(i);
  118. delay(50);
  119. }
  120. delay(1000); */
  121. // panServo.write(180);
  122. // delay(1000);
  123. // panServo.write(90);
  124. // delay(1000);
  125. // panServo.write(0);
  126. // delay(1000);
  127. // panServo.write(90);
  128.  
  129. // delay(1000);
  130.  
  131. // Assuming no switches closed initially. Drive forward:
  132. motorLeft->setSpeed(FORWARD_SPEED);
  133. motorRight->setSpeed(FORWARD_SPEED);
  134. pingDist = Distance_inches(sonic.ping());
  135. while (pingDist == 0) {
  136. pingDist = Distance_inches(sonic.ping());
  137. }
  138.  
  139.  
  140. Serial.println("First straight distance = " + String(pingDist));
  141. while (digitalRead(LEFT_BUMP_PIN) && digitalRead(RIGHT_BUMP_PIN)
  142. && pingDist > TARGET_DISTANCE_INCHES) {
  143. motorLeft->run(FORWARD);
  144. motorRight->run(FORWARD);
  145. pingDist = Distance_inches(sonic.ping());
  146. while (pingDist == 0) {
  147. pingDist = Distance_inches(sonic.ping());
  148. }
  149. Serial.println("Straight distance = " + String(pingDist));
  150. // Serial.println(String(pingDist));
  151. }
  152.  
  153. /* If you got here, one of the bump switches was closed or B^3 is too
  154. close to something straight ahead */
  155.  
  156. /* First check the LEFT sensor: */
  157. if (! digitalRead(LEFT_BUMP_PIN)) { // the LEFT side switch was bumped
  158. motorLeft->setSpeed(BACKWARD_SPEED / 3); // Slowly back up and turn to right
  159. motorRight->setSpeed(BACKWARD_SPEED);
  160. motorLeft->run(BACKWARD);
  161. motorRight->run(BACKWARD);
  162. delay(TURN_DURATION); // for specified duration
  163. motorLeft->run(RELEASE); // Then stop power to the motors
  164. motorRight->run(RELEASE); // and move to next section of code
  165. }
  166. /* Then check the right sensor: */
  167. else if (! digitalRead(RIGHT_BUMP_PIN)) { // the RIGHT side switch was bumped
  168. motorLeft->setSpeed(BACKWARD_SPEED); // Slowly back up and turn to left
  169. motorRight->setSpeed(BACKWARD_SPEED / 3);
  170. motorLeft->run(BACKWARD);
  171. motorRight->run(BACKWARD);
  172. delay(TURN_DURATION); // for specified duration
  173. motorLeft->run(RELEASE); // Then stop power to the motors
  174. motorRight->run(RELEASE); // and move to next section of code
  175. }
  176. /* It must have been the sonar sensor */
  177. else {
  178. // /* motorLeft->run(RELEASE); // So stop power to the motors
  179. // motorRight->run(RELEASE); // and move to next section of code */
  180. // motorLeft->run(BACKWARD); // So REVERSE power to the motors
  181. // motorRight->run(BACKWARD); // to BRIEFLY APPLY a brake
  182. // delay(50);
  183. // motorLeft->run(RELEASE); // Then stop power to the motors
  184. // motorRight->run(RELEASE); // and move to next section of code
  185. allStop(FORWARD, motorLeft, motorRight);
  186. float maxDist = -999.;
  187. int newDirection = 0;
  188.  
  189. for (int i = 20; i <= 160; i += 5) {
  190. panServo.write(i);
  191. // pingDist = max(Distance_inches(sonic.ping()),0.1);
  192. pingDist = Distance_inches(sonic.ping());
  193. while (pingDist == 0) {
  194. pingDist = Distance_inches(sonic.ping());
  195. }
  196. if (pingDist > maxDist) {
  197. //newDirection = i - 90;
  198. newDirection = map(i, 0, 180, 90, -90); //*****WHY THIS ORDER?*****
  199. maxDist = pingDist;
  200. String outMsg = String("New maximum distance is " +
  201. String(pingDist) + " at angle " + String(newDirection));
  202. Serial.println(outMsg);
  203. }
  204. delay(50);
  205. }
  206. /* Now turn to the new maximumum direction! */
  207. panServo.write(90);
  208. spin(newDirection, 60, motorLeft, motorRight);
  209. spinStop(newDirection, motorLeft, motorRight);
  210.  
  211. motorLeft->run(RELEASE); // Then stop power to the motors
  212. motorRight->run(RELEASE); // and move to next section of code
  213. String outMsg = String("New direction is " + String(newDirection));
  214. Serial.println(outMsg);
  215. // while (digitalRead(RIGHT_BUMP_PIN)) {} // pause until right bump pin hit.
  216. }
  217. motorLeft->run(RELEASE); // Then stop power to the motors
  218. motorRight->run(RELEASE); // and move to next section of code
  219. panServo.write(90);
  220. /*That is all! Now go back to the beginning of the loop and
  221. drive straight ahead until somehting is bumped. */
  222.  
  223. }
  224.  
  225. //int goodPing(void) {
  226. // int goodPing = 0;
  227. // int minBadPing = 0;
  228. // int maxBadPing = 4.e6 * 2.0 / 13582.67; // uSecs to go and return 4 inches.
  229. // goodPing = sonic.ping();
  230. // while (goodPing >= minBadPing && goodPing <= maxBadPing) {
  231. // goodPing = sonic.ping();
  232. // }
  233. // return goodPing;
  234. //}
  235.  
  236. float Distance_inches(int ping) {
  237. float inches_per_sec = 13582.67; // Equivilent to 345 m/s
  238. return ping * inches_per_sec * 1e-6 * 0.5;
  239. }
  240.  
  241. float Distance_cm(int ping) {
  242. float cm_per_sec = 34500.; // Equivilent to 345 m/s
  243. return ping * cm_per_sec * 1e-6 * 0.5;
  244. }
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
������������������������������������������������