Advertisement
Guest User

Untitled

a guest
May 24th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.65 KB | None | 0 0
  1. #include <Servo.h>
  2. #include <Ultrasonic.h>
  3. #include <NewPing.h>
  4. Servo servomotor; //сервомотор - отвечает за поворот "головы", на которой стоит сонар
  5. NewPing sonar(2, 4, 50); //собственно сонар, в параметрах вроде распиновка
  6.  
  7. //пины моторчиков на колесах
  8. int leftWheel = 3;
  9. int rightWheel = 6;
  10.  
  11.  
  12. int moveDirectionPin = 8; //пин направления движения. Если на этот пин подан 0,
  13.                           //то колеса будут крутиться вперёд, если 1 - то назад
  14.  
  15. boolean moveDirectionValue = true; //это мы не добавили по сути. Нужно чтобы ехать вперёд-назад, мы недоделали.
  16. const int MS_PER_DEGREE = 6; //сколько миллисекунд нужно чтобы повернуть машинку на 1 градус
  17.  
  18.  
  19. void setup() { //в самом начале настройка
  20.   Serial.begin(9600); //это нужно для вывода значений в консоль, не используется
  21.   servomotor.attach(9); //присоединяем сервомотор на девятый пин
  22.   }
  23.  
  24. void loop() { //основной цикл, выполняется пока мы не выключим машинку
  25.     rotate(findOptimalDirection()); //сначала машинка физически поворачивается туда, куда наиболее выгодно ехать
  26.     servomotor.write(90);  //поворачиваем голову ровно вперёд
  27.     while (getCurrentDistance() > 10 || getCurrentDistance()==0 && moveDirectionValue){ //и до тех пор пока дистанция больше 10
  28.                                                                                          //(в случае если дистанция огромна - возвращается ноль)
  29.       go(150); //собственно едем со скоростью 150 из 255
  30.     }
  31.     go(0); //останавливаемся
  32.     if (getCurrentDistance() == -1) { //если нас занесло слишком близко
  33.       goBack(); //отъезжаем
  34.     }
  35.    
  36. }
  37.  
  38. void goBack() {
  39.   digitalWrite(moveDirectionPin, HIGH); //выставляем на пин 1 => дальше будем ехать назад
  40.   moveDirectionValue = false;
  41.   go(150); //проезжаем со скоростью 150
  42.   delay(1000); / в течение секунды
  43.   go(0); //останавливаемся
  44.   digitalWrite(moveDirectionPin, LOW); //выставляем 0 => дальше будем ехать вперёд
  45.   moveDirectionValue = true;
  46. }
  47.  
  48. int getCurrentDistance() {
  49.   int distance = sonar.ping_cm(); //получаем дистанцию в сантиметра с сонара благодаря библиотеке NewPing
  50.   if (distance < 5 && distance != 0) { //если мы слишком близко - возвращаем код "-1", типа "едь назад"
  51.     return -1;
  52.   }
  53.   else return distance; // иначе просто дистанцию
  54. }
  55.  
  56. void go(int speed) { //поскольку моторы на колесах поддерживают аналоговую запись, можем управлять скоростью от 0 до 255
  57.   analogWrite(leftWheel, speed);
  58.   analogWrite(rightWheel, speed);
  59. }
  60.  
  61.  
  62. void rotate(int absoluteDegree) {
  63.   int relativeDegree = 90 - absoluteDegree; //поскольку сонар умеет поворачиваться от 0 до 180,
  64.                                             //то такие же значения нужно использовать для поворота машинки
  65.                                             //если мы вычитаем из 90 наш угол, то мы получаем настоящий угол поворота относительно
  66.                                             //направления вперёд, но либо с плюсом, либо с минусом
  67.   boolean left;                             //значение плюс или минус влияет на флажок left, означающий "будем ехать влево"
  68.   if (relativeDegree < 0) left = true;      //если значение меньше нуля, то едем влево
  69.   else left = false;                        //иначе вправо
  70.   int rotationTime = abs(relativeDegree) * MS_PER_DEGREE;   //вычисляем сколько нужно поворачиваться - модуль угла * константу 6 мс
  71.   if (left) { //и либо влево поворачиваемся
  72.     analogWrite(rightWheel, 255);
  73.     delay(rotationTime);  //столько сколько надо
  74.     analogWrite(rightWheel, 0);
  75.   } else {    //либо вправо
  76.     analogWrite(leftWheel, 255);
  77.     delay(rotationTime);  //столько сколько надо
  78.     analogWrite(leftWheel, 0);
  79.   }
  80. }
  81.  
  82. int findOptimalDirection(){
  83.   int maxDistance = 0;
  84.   int maxDistanceAngle = 180;
  85.   int currentDistance = 0;
  86.   int minDistance = 999;
  87.  
  88.   for (int i = 30; i <= 150; i=i+10) { //для поиска направления мы вращаемся от 30 до 150 (потому что двигатель барахлит)
  89.     servomotor.write(i);               //поворачиваем голову
  90.     delay(50);
  91.     currentDistance = getCurrentDistance(); //получаем расстояние
  92.     if (currentDistance > maxDistance){     //сравниваем с предыдущим максимумом
  93.       maxDistance = currentDistance;        //и если больше - обновляем максимум
  94.       maxDistanceAngle=i;                   //и запоминаем куда лучше всего ехать
  95.       }
  96.     }
  97.     if (currentDistance < minDistance && currentDistance != 0) {   //так же смотрит минимальную дистанцию
  98.       minDistance = currentDistance;
  99.     }
  100.     servomotor.write(maxDistanceAngle);   //как только закончили наш цикл - поворачиваем голову туда, куда хотим ехать
  101.     delay(1000);                          //зачем это тут? Машинка бы быстрее ехала без этого
  102.     if (minDistance < 2) {                //если минимальная дистанция меньше 2 см, то машинка может застрять колесами об угол
  103.       goBack();                           //поэтому отъезжаем
  104.     }
  105.     return maxDistanceAngle;
  106.   }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement