Энкодеры для точных поворотов робота

Итак, я недавно купил:

Колесные кодировщики DFRobot

DFRobot 3PA и полноприводные вездеходы (2 шт.)

Контроллер Romeo V2 Arduino

Я провел небольшое исследование в Интернете и пытаюсь понять, как использовать энкодеры для управления ШИМ, применяемым к двигателям, которые будут совершать точные повороты. Это похоже на популярный метод для использования. Вот часть моего кода. У меня пока нет ничего для энкодеров. У меня есть только датчики, работающие на ШИМ-управление двигателями. Все, что делает мой код, это останавливает двигатели, когда передний датчик обнаруживает стену. Мой следующий шаг — внедрить энкодеры, чтобы робот мог поворачиваться на 90 градусов. У кого-нибудь есть пример кода или советы о том, как это сделать? Заранее спасибо!

  void stop(void)                      
    {
      digitalWrite(5,LOW);   
      digitalWrite(6,LOW);


    }   
    void forward(char a,char b)
    {
      analogWrite(5,a);
      digitalWrite(4,HIGH);    
      analogWrite(6,b);    
      digitalWrite(7,HIGH);

    }  
    void back(char a,char b)
    {
      analogWrite(5,a);
      digitalWrite(4,LOW);   
      analogWrite(6,b);    
      digitalWrite(7,LOW);


    }
    void Left(char a,char b)
    {
      analogWrite (5,a);
      digitalWrite(4,LOW);    
      analogWrite (6,b);    
      digitalWrite(7,HIGH);



    }
    void Right(char a,char b) 
    {
      analogWrite (5,a);
      digitalWrite(4,HIGH);    
      analogWrite (6,b);    
      digitalWrite(7,LOW);

    }
    void setup(void) 
    { 

      pinMode(buttonPin2, INPUT);
      pinMode(buttonPin3, INPUT);
      for(int i =4;i<=7;i++)
        pinMode(i, OUTPUT);  
      pinMode(LED_BUILTIN, OUTPUT);
     forward(100,100);


      Serial.begin(9600);


    }
void GetSensor()
{

  Sen_Val_B = SenAvg(Sensor_Back);
  Sen_Val_F = SenAvg(Sensor_Front);
  Sen_Val_R = SenAvg(Sensor_Right);
  Sen_Val_L = SenAvg(Sensor_Left);

}

int SenAvg(int SensorNumber)
{

  Arr[100]= 0;
  avg = 0;

  for(int i = 0; i<100; i++)
  {
    Arr[i] = analogRead(SensorNumber);
    avg = avg + Arr[i];
  }
    avg = avg/100;
    return avg;
} 
void loop(void) 
{

   GetSensor();
  if(Sen_Val_F > 200)
  {
   stop();
  }

}

, 👍1


2 ответа


0

Все, что делает мой код, это останавливает двигатели, когда передний датчик обнаруживает стену. Мой следующий шаг — внедрить энкодеры, чтобы робот мог поворачиваться на 90 градусов.

это сработает?

  if (wall_sensed()) turn_90right(); //если обнаружена стена, повернуть на 90 градусов вправо

Вы также можете рассмотреть возможность внесения изменений

  digitalWrite(5,LOW);   
  digitalWrite(6,LOW);

к:

  digitalWrite(MOTOR_LF,STOP);   //остановить левый передний мотор
  digitalWrite(MOTOR_LR,STOP);   //остановить левый правый мотор

чтобы

  1. намного читабельнее; и
  2. если вы хотите изменить назначение выводов, это делается последовательно во всем коде.
,

Я могу заставить робота поворачиваться, но я пытаюсь добиться точных поворотов на 90 градусов. Я использовал подход грубой силы, но просто использовал задержку. Но этот метод кажется несостоятельным., @user367640

Хм, при повороте колеса могут пробуксовывать. Вы можете проверить точность на датчике компаса. Потому что, если вы повернетесь несколько раз, вы постепенно получите смещение из-за неточностей. С компасом вы получаете абсолютный курс вместо того, чтобы накапливать все повороты (которые накапливают ошибку)., @Paul


1

Энкодеры дают вам синхронизированную обратную связь о вращении двигателя, которую вы можете подсчитать, чтобы получить представление о положении и скорости. Таким образом, чтобы повернуться на указанную величину, вам нужно знать, насколько ваше колесо должно повернуться на заданный угол. Затем вы можете точно повернуть колесо, разделив длину окружности колеса на максимальное число тактов энкодера за один оборот.

Скажем, мы делаем 600 тиков за один оборот, а окружность нашего колеса составляет 10 см. Затем мы поворачивали колесо на 100 мм / 600 = 0,16 мм за один такт энкодера!

Можно даже написать функцию, учитывающую больше параметров (диаметр робота/расстояние между колесами), которая вычисляет эти значения. Более быстрый/более эмпирический подход, чем сбор всех этих значений, заключается в том, чтобы просто управлять роботом на x (т.е. 100) тактов и измерять угол, который он прошел, чтобы получить прямую зависимость между тактами энкодера и углом робота.

Другим, гораздо более точным решением было бы использовать компас или гироскоп для измерения ориентации робота и полагаться на них, а не на энкодеры.

,