Управляемый робот с автопилотом

Управляемый робот с автопилотом основан на контроллере Arduino UNO и состоит из основной платы, источника питания, двигателей, датчиков линии, датчика расстояния и Bluetooth.

Робот управляется с помощью телефона по беспроводной связи. Телефоном можно переключить его на автопилот и тогда он начинает движение по линии с помощью датчиков. Датчик расстояния, расположенный на передней части робота, позволяет увидеть препятствие перед ним, чтобы избежать столкновений.

Плата робота изготовлена на ЧПУ Roland MDX-15 и содержит в себе драйвер двигателей L293D, разъемы для подключения Arduino, двигателей, датчиков и другой периферии. Изготовление платы описана на странице Изготовление печатной платы в Roland MDX-15. А сама плата на странице Основная плата робота.

Датчики линии работают по принципу описанной на странице Датчик линии.

Ниже представлен код программы для робота:

int dist(int echoPin, int trigPin){//Функция, определяющая расстояние с помощью дальномера 
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  int duration; //Переменное, в которой будет считано расстояние до препятствия
  digitalWrite(trigPin, LOW); //Отправка импульса длительностью в 10 микросекунд
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); //Задержка на 10 микросекунд
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH); //Ожидание импульса и возвращение пройденного времени
  return(duration / 58); //Перевод времени в сантиметры и возврат расстояния}
}
int LineSensor(int analogPort, int digitalPort){//Считывает с датчиков линии
  digitalWrite(digitalPort,0);//Выключение подсветки
  pinMode(digitalPort,1);
  int a1=analogRead(analogPort);//Считывание без подстветки
  digitalWrite(digitalPort,1);//Включение подсветки
  delay(1);
  int a=analogRead(analogPort);//Считывание с подсветкой
  digitalWrite(digitalPort,0);//Выключение подсветки
  return (a-a1);//Возврат разности считанных значений
}
int RightLineSensor(){//Считывание правого датчика линии
  return (LineSensor(A0, A5));
}
int LeftLineSensor(){//Считывание левого датчика линии
  return (LineSensor(A1, A4));
}
void LeftMotor(int skor){//Управление левым двигателем
  pinMode(4,1);
  pinMode(9,1);
  if (skor>255) skor=255;
  if (skor<-255) skor=-255;
  if (skor>=0){
    digitalWrite(4,0);
    analogWrite(9,skor);
  }
  else{
    digitalWrite(4,1);
    analogWrite(9,255+skor);
  }
}
void RightMotor(int skor){//Управление правым двигателем
  pinMode(11,1);
  pinMode(12,1);
  skor=-skor;
  if (skor>255) skor=255;
  if (skor<-255) skor=-255;
  if (skor>=0){
    digitalWrite(12,0);
    analogWrite(11,skor);
  }
  else{
    digitalWrite(12,1);
    analogWrite(11,255+skor);
  }
}
void RemoteControl(){//Функция управления по bluetooth
  while (1)//Запуск бесконечного цикла
    if (Serial.available()){//Если пришла команда
      char cmd=Serial.read();//Считывание команды в переменную
      switch (cmd){//Переключение в зависимости от команды
        case '1': 
          if (dist(8,7)>20) {//Если расстояние больше 20 см
            LeftMotor(255);//То ехать вперед
            RightMotor(255);
            delay(100);
            LeftMotor(0);
            RightMotor(0);
          }
        break;
        case '2'://Ехать назад
          LeftMotor(-255);
          RightMotor(-255);
          delay(100);
          LeftMotor(0);
          RightMotor(0);
        
        break;
        case '3': //Влево
          LeftMotor(0);
          RightMotor(255);
          delay(100);
          LeftMotor(0);
          RightMotor(0);
        
        break;
        case '4': //Вправо
          LeftMotor(255);
          RightMotor(0);
          delay(100);
          LeftMotor(0);
          RightMotor(0);
        
        break;
        case '9':return;// Выйти из управления по bluetooth
        break;
      }  
    }
  }

}
void setup() {
  Serial.begin(9600);//Инициализация порта (bluetooth)
}

void loop() {
  while (!(Serial.available())){
    while (dist(8,7)<20){//Если расстояние до препятствия меньше 20 см
      LeftMotor(0);//то стоп
      RightMotor(0);
      delay(300);
    }
    //релейный алгоритм
    if (LeftLineSensor()>200) LeftMotor(255); else LeftMotor(0);
    if (RightLineSensor()>110) RightMotor(255); else RightMotor(0);
  }
  if (Serial.read()=='9') RemoteControl();//Переключение в ручное управление
}