Advertisement
sandervspl

Fles Drive v2

Oct 26th, 2015
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.92 KB | None | 0 0
  1. #include <IRremote.h>
  2. #include <Servo.h>
  3.  
  4. #define FILL_BOTTLE    0xa91
  5. #define BOTTLE_FILLED  0xa92
  6.  
  7. // Arduino pins for the shift register
  8. #define MOTORLATCH   12
  9. #define MOTORCLK     4
  10. #define MOTORENABLE  7
  11. #define MOTORDATA    8
  12.  
  13. #define MOTOR1_A  2
  14. #define MOTOR1_B  3
  15. #define MOTOR2_A  1
  16. #define MOTOR2_B  4
  17. #define MOTOR3_A  5
  18. #define MOTOR3_B  7
  19. #define MOTOR4_A  0
  20. #define MOTOR4_B  6
  21.  
  22. // Arduino pins for the PWM signals.
  23. #define MOTOR1_PWM  11
  24. #define MOTOR2_PWM  3
  25. #define MOTOR3_PWM  6
  26. #define MOTOR4_PWM  5
  27. #define SERVO1_PWM  10
  28. #define SERVO2_PWM  9
  29.  
  30. // Codes for the motor function.
  31. #define FORWARD   1
  32. #define BACKWARD  2
  33. #define BRAKE     3
  34. #define RELEASE   4
  35.  
  36. #define scanBlack           500
  37. #define DRIVE_FULL_SPEED    255
  38. #define DRIVE_MEDIUM_SPEED  150
  39. #define DRIVE_SLOW_SPEED    125
  40. #define DRIVE_STOP          0
  41.  
  42.  
  43.  
  44.  
  45. // line scanners
  46. const int scanPinMid   = 3;
  47. const int scanPinLeft  = 5;
  48. const int scanPinRight = 4;
  49.  
  50. // motor aandrijf pin
  51. const int motorPin = 3;
  52.  
  53. // mosture sensor
  54. const int mosturePin = 0;
  55.  
  56. // servo
  57. Servo servo;
  58.  
  59. // infrarood
  60. IRsend ir;
  61.  
  62. // time
  63. unsigned long prevTimeAllFalse = 0;
  64. unsigned long startedFillingBottleTime = 0;
  65. unsigned long prevTimeTurning = 0;
  66.  
  67. bool isAllFalse = false;
  68. bool isBottleEmpty = false;
  69. bool isStopped = false;
  70.  
  71.  
  72. const int STATE_DRIVING_TO_REFILL = 0;
  73. const int STATE_DRIVING_TO_USER   = 1;
  74. const int STATE_HOLDING_AT_USER   = 2;
  75. const int STATE_HOLDING_AT_REFILL = 3;
  76.  
  77. int drivingState = 0;
  78. int prevDrivingState = 0;
  79.  
  80.  
  81.  
  82.  
  83. void setup()
  84. {
  85.   for (int i = 0; i < 5; i++) {
  86.     ir.sendSony(FILL_BOTTLE, 12);
  87.     delay(10);
  88.   }
  89.      
  90.   Serial.begin(9600);
  91.  
  92.   // power supply
  93.   pinMode(scanPinMid, INPUT);
  94.   pinMode(scanPinLeft, INPUT);
  95.   pinMode(scanPinRight, INPUT);
  96.  
  97.   // servo position
  98.   servo.attach(SERVO1_PWM);
  99.  
  100.   // zet recht
  101.   while (servo.read() != 90) {
  102.     servo.write(90);
  103.   }
  104.  
  105.   drivingState = STATE_DRIVING_TO_USER;
  106.   prevDrivingState = drivingState;
  107.  
  108.   // TEST
  109.   // isBottleEmpty = true;
  110.  
  111.   Serial.println("------------------------");
  112.   Serial.println("Starting car.");
  113. }
  114.  
  115.  
  116.  
  117. void drive(int speed, int angle = 90) {
  118.   servo.write(angle);
  119.   delay(100);
  120.   motor(1, FORWARD, speed);
  121. }
  122.  
  123.  
  124.  
  125. void loop()
  126. {
  127.   int scanMid = analogRead(scanPinMid);
  128.   int scanLeft = analogRead(scanPinLeft);
  129.   int scanRight = analogRead(scanPinRight);
  130.  
  131.   int mostureValue = analogRead(mosturePin);
  132.  
  133.   unsigned long curTime = millis();
  134.  
  135.  
  136.  
  137.   if (isStopped) {
  138.  
  139.     // als we bij gebruiker wachten, check fles mosture values
  140.     if (mostureValue > 500) {
  141.       isBottleEmpty = true;
  142.       isStopped = false;
  143.  
  144.       prevDrivingState = drivingState;
  145.       drivingState = STATE_DRIVING_TO_REFILL;
  146.  
  147.       drive(DRIVE_SLOW_SPEED);
  148.     }
  149.  
  150.  
  151.  
  152.     // als fles leeg is, en we staan stil na ons ritje naar fill locatie, stuur signaal om fles te vullen
  153.     if (drivingState == STATE_DRIVING_TO_REFILL) {
  154.       for (int i = 0; i < 5; i++) {
  155.         ir.sendSony(FILL_BOTTLE, 12);
  156.         delay(10);
  157.       }
  158.  
  159.       prevDrivingState = drivingState;
  160.       drivingState = STATE_HOLDING_AT_REFILL;
  161.  
  162.       startedFillingBottleTime = curTime;
  163.     }
  164.  
  165.    
  166.     // fles is gevuld na 5 seconden. Geef dan seintje dat we weer kunnen rijden naar de gebruiker
  167.     if (drivingState == STATE_HOLDING_AT_REFILL && curTime - startedFillingBottleTime > 5000) {
  168.       isStopped = false;
  169.       isBottleEmpty = false;
  170.  
  171.       prevDrivingState = drivingState;
  172.       drivingState = STATE_DRIVING_TO_USER;
  173.  
  174.       drive(DRIVE_SLOW_SPEED);
  175.     }
  176.    
  177.     return;
  178.  
  179.   } /* else {
  180.  
  181.     // houdt de motor aan als onze state dat wil
  182.     if (drivingState == STATE_DRIVING_TO_USER || drivingState == STATE_DRIVING_TO_REFILL) {
  183.       motor(1, FORWARD, DRIVE_SLOW_SPEED);
  184.     }
  185.   } */
  186.  
  187.  
  188.  
  189.   // rijdt vooruit tot we een zwarte lijn zien
  190.   if (drivingState == STATE_DRIVING_TO_USER) {
  191.     if (scanMid >= scanBlack || scanLeft >= scanBlack || scanRight >= scanBlack) {
  192.       isReturningToUser = false;
  193.     }
  194.  
  195.     prevDrivingState = drivingState;
  196.     drivingState = STATE_DRIVING_TO_USER;
  197.  
  198.     motor(1, FORWARD, DRIVE_SLOW_SPEED);
  199.     return;
  200.   }
  201.  
  202.  
  203.  
  204.   // kijk of middelste scanner iets ziet
  205.   if (scanMid >= scanBlack) {
  206.    
  207.     /*
  208.  
  209.       CANCEL TURNING
  210.  
  211.                       */
  212.  
  213.   // zo niet, kijk naar de linker en rechter en draai tot de middelste aanstaat
  214.   } else {
  215.    
  216.     // links en links & rechts
  217.     if (scanLeft >= scanBlack || (scanLeft >= scanBlack && scanRight >= scanBlack)) {
  218.       Serial.println("left");
  219.      
  220.       if (isAllFalse) isAllFalse = false;
  221.  
  222.       int servoAngle = servo.read();
  223.       if (servoAngle > 50) {
  224.         if (curTime - prevTimeTurning > 1) {
  225.           servoAngle--;
  226.           servo.write(servoAngle);
  227.  
  228.           prevTimeTurning = curTime;
  229.  
  230.           Serial.println("turn left " + String(servoAngle));
  231.         }
  232.       }
  233.     }
  234.    
  235.     // alleen rechts
  236.     if (scanRight >= scanBlack && scanLeft < scanBlack) {
  237.       Serial.println("right");
  238.      
  239.       if (isAllFalse) isAllFalse = false;
  240.  
  241.       int servoAngle = servo.read();
  242.       if (servoAngle < 130) {
  243.         if (curTime - prevTimeTurning > 1) {
  244.           servoAngle++;
  245.           servo.write(servoAngle);
  246.  
  247.           prevTimeTurning = curTime;
  248.  
  249.           Serial.println("turn right " + String(servoAngle));
  250.         }      
  251.       }
  252.     }
  253.  
  254.    
  255.     // alle scanners false, zet motor uit na een tijdje
  256.     if (scanRight < scanBlack && scanLeft < scanBlack) {
  257.        if(!isAllFalse) {
  258.          isAllFalse = true;
  259.          prevTimeAllFalse = curTime;
  260.        }
  261.     }
  262.   }
  263.  
  264.  
  265.   // CHECK OUR NEXT STEP
  266.   /////
  267.  
  268.   /*
  269.     STOP AND WAIT AT USER UNTIL BOTTLE IS EMPTY ENOUGH FOR REFILL
  270.                                                                  */  
  271.   if (drivingState == STATE_DRIVING_TO_USER && isAllFalse && (curTime - prevTimeAllFalse) > 250) {
  272.     isStopped = true;
  273.  
  274.     prevDrivingState = drivingState;
  275.     drivingState = STATE_HOLDING_AT_USER;
  276.  
  277.     motor(1, RELEASE, DRIVE_STOP);
  278.   }
  279.  
  280.  
  281.   /*
  282.     STOP AND WAIT FOR REFILL
  283.                             */
  284.   if (drivingState == STATE_DRIVING_TO_REFILL && isAllFalse && (curTime - prevTimeAllFalse) > 250) {
  285.     isStopped = true;
  286.  
  287.     prevDrivingState = drivingState;
  288.     drivingState = STATE_HOLDING_AT_REFILL;
  289.  
  290.     motor(1, RELEASE, DRIVE_STOP);
  291.   }
  292.  
  293.  
  294.   /*
  295.     GET READY TO GO TO REFILL ZONE
  296.                                   */
  297.   // if (drivingState == STATE_HOLDING_AT_USER && isBottleEmpty && isAllFalse && (curTime - prevTimeAllFalse) > 250) {
  298.   //   servo.write(90);
  299.   //   motor(1, RELEASE, DRIVE_STOP);
  300.  
  301.   //   // startedFillingBottleTime = curTime;
  302.   //   isReturningToRefill = true;
  303.   // }
  304. }
  305.  
  306.  
  307.  
  308.  
  309. //////
  310. // ----------------------------
  311. //////
  312.  
  313.  
  314. void motor(int nMotor, int command, int speed)
  315. {
  316.   int motorA, motorB;
  317.  
  318.   if (nMotor >= 1 && nMotor <= 4)
  319.   {  
  320.     switch (nMotor)
  321.     {
  322.     case 1:
  323.       motorA   = MOTOR1_A;
  324.       motorB   = MOTOR1_B;
  325.       break;
  326.     case 2:
  327.       motorA   = MOTOR2_A;
  328.       motorB   = MOTOR2_B;
  329.       break;
  330.     case 3:
  331.       motorA   = MOTOR3_A;
  332.       motorB   = MOTOR3_B;
  333.       break;
  334.     case 4:
  335.       motorA   = MOTOR4_A;
  336.       motorB   = MOTOR4_B;
  337.       break;
  338.     default:
  339.       break;
  340.     }
  341.  
  342.     switch (command)
  343.     {
  344.     case FORWARD:
  345.       motor_output (motorA, HIGH, speed);
  346.       motor_output (motorB, LOW, -1);     // -1: no PWM set
  347.       break;
  348.     case BACKWARD:
  349.       motor_output (motorA, LOW, speed);
  350.       motor_output (motorB, HIGH, -1);    // -1: no PWM set
  351.       break;
  352.     case BRAKE:
  353.       motor_output (motorA, LOW, 255); // 255: fully on.
  354.       motor_output (motorB, LOW, -1);  // -1: no PWM set
  355.       break;
  356.     case RELEASE:
  357.       motor_output (motorA, LOW, 0);  // 0: output floating.
  358.       motor_output (motorB, LOW, -1); // -1: no PWM set
  359.       break;
  360.     default:
  361.       break;
  362.     }
  363.   }
  364. }
  365.  
  366.  
  367. void motor_output (int output, int high_low, int speed)
  368. {
  369.   int motorPWM;
  370.  
  371.   switch (output)
  372.   {
  373.   case MOTOR1_A:
  374.   case MOTOR1_B:
  375.     motorPWM = MOTOR1_PWM;
  376.     break;
  377.   default:
  378.     // Use speed as error flag, -3333 = invalid output.
  379.     speed = -3333;
  380.     break;
  381.   }
  382.  
  383.   if (speed != -3333)
  384.   {
  385.     // Set the direction with the shift register
  386.     // on the MotorShield, even if the speed = -1.
  387.     // In that case the direction will be set, but
  388.     // not the PWM.
  389.     shiftWrite(output, high_low);
  390.  
  391.     // set PWM only if it is valid
  392.     if (speed >= 0 && speed <= 255)    
  393.     {
  394.       analogWrite(motorPWM, speed);
  395.     }
  396.   }
  397. }
  398.  
  399.  
  400. void shiftWrite(int output, int high_low)
  401. {
  402.   static int latch_copy;
  403.   static int shift_register_initialized = false;
  404.  
  405.   // Do the initialization on the fly,
  406.   // at the first time it is used.
  407.   if (!shift_register_initialized)
  408.   {
  409.     // Set pins for shift register to output
  410.     pinMode(MOTORLATCH, OUTPUT);
  411.     pinMode(MOTORENABLE, OUTPUT);
  412.     pinMode(MOTORDATA, OUTPUT);
  413.     pinMode(MOTORCLK, OUTPUT);
  414.  
  415.     // Set pins for shift register to default value (low);
  416.     digitalWrite(MOTORDATA, LOW);
  417.     digitalWrite(MOTORLATCH, LOW);
  418.     digitalWrite(MOTORCLK, LOW);
  419.     // Enable the shift register, set Enable pin Low.
  420.     digitalWrite(MOTORENABLE, LOW);
  421.  
  422.     // start with all outputs (of the shift register) low
  423.     latch_copy = 0;
  424.  
  425.     shift_register_initialized = true;
  426.   }
  427.  
  428.   // The defines HIGH and LOW are 1 and 0.
  429.   // So this is valid.
  430.   bitWrite(latch_copy, output, high_low);
  431.  
  432.   // Use the default Arduino 'shiftOut()' function to
  433.   // shift the bits with the MOTORCLK as clock pulse.
  434.   // The 74HC595 shiftregister wants the MSB first.
  435.   // After that, generate a latch pulse with MOTORLATCH.
  436.   shiftOut(MOTORDATA, MOTORCLK, MSBFIRST, latch_copy);
  437.   delayMicroseconds(5);    // For safety, not really needed.
  438.   digitalWrite(MOTORLATCH, HIGH);
  439.   delayMicroseconds(5);    // For safety, not really needed.
  440.   digitalWrite(MOTORLATCH, LOW);
  441. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement