Угловая скорость двигателя постоянного тока, управляемая потенциометром

Я создал установку, в которой потенциометр управляет двигателем постоянного тока, а ток через двигатель постоянного тока контролируется Н-мостом. Принцип следующий: Когда циферблат потенциометра установлен в среднее положение, двигатель выключен. Вращение потенциометра по часовой стрелке приведет к вращению двигателя в одном направлении со скоростью, определяемой смещением потенциометра от средней точки: чем больше смещение от средней точки, тем больше скорость вращения двигателя. Если потенциометр вращать против часовой стрелки, в направлении от средней точки, двигатель будет вращаться в направлении, противоположном предыдущему; опять же, со скоростью, определяемой степенью смещения потенциометра от средней точки.

Цикл имеет три функции: HB_12EN — для включения драйверов, HB_1A — первый вход драйвера, а HB_2A — второй вход драйвера (контакты H-моста 1, 2 и 7 соответственно) согласно этой таблице данных: http://www.ti.com/lit/ds/symlink/sn754410.pdf< /п>

Подводя итог их функциям: HB_12EN позволяет подавать напряжение на устройство, управляемое H-мостом (в данном случае двигатель), и модулируется импульсной волной. HB_1A и HB_2A управляют потоком тока через двигатель, устанавливая его угловую скорость. HB_1A, установленный HIGH, и HB_2A, установленный LOW, направляют ток через двигатель в одну сторону, а HB1A, установленный LOW, и HB_2A, установленный HIGH, направляют ток через двигатель в другую сторону.

Цикл:

//ВЫХОДЫ
int const HB_12EN = 9; //вывод ШИМ
int const HB_1A = 2;
int const HB_2A = 3;

//ВХОДЫ
int const POT_MOT = 0; //A0, аналог 0

//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
unsigned int pot_val = 0; //Значение АЦП от потенциометра
unsigned int grp_num = 1;

pot_val = analogRead(POT_MOT);
grp_num = setMotSwitch(HB_12EN, HB_1A, HB_2A, pot_val, grp_num);
setMotSpeed(HB_12EN, pot_val, grp_num);

Две (небиблиотечные) функции:

unsigned int setMotSwitch(int const motor_reg, int const first_motor, int const sec_motor, unsigned int pot_value, unsigned int group_num) //grp 0: 0-383; грп 1: 384-639; группа 2: 640-1023
{
  if (pot_value >= 0 && pot_value < 384)
  {
    if (group_num != 0)
    {
       digitalWrite(motor_reg, LOW);
       digitalWrite(first_motor, HIGH);
       digitalWrite(sec_motor, LOW);
       group_num = 0;
    }
  }
  else if (pot_value > 383 && pot_value < 640)
  {
    if (group_num != 1)
    {
      digitalWrite(motor_reg, LOW);
      digitalWrite(first_motor, LOW);
      digitalWrite(sec_motor, LOW);
      group_num = 1;
    }
  }
  else if (pot_value > 639 && pot_value <= 1023)
  {
    if (group_num != 2)
    {
      digitalWrite(motor_reg, LOW);
      digitalWrite(first_motor, LOW);
      digitalWrite(sec_motor, HIGH);
      group_num = 2;
    }
  }
  else
  {
      digitalWrite(motor_reg, LOW);
      digitalWrite(first_motor, LOW);
      digitalWrite(sec_motor, LOW);
      group_num = 0;
  }
  return group_num;
}

void setMotSpeed(int const motor_reg, unsigned int pot_value, unsigned int group_num)
{
  unsigned int mot_speed = 0;
  if (group_num == 0)
  {
    mot_speed = map(pot_value, 0, 383, 255, 0);
    mot_speed = constrain(mot_speed, 0, 255);
    analogWrite(motor_reg, mot_speed);
  }
  else if (group_num == 1)
  {
    if (pot_value > 500 && pot_value < 523)
    {
      digitalWrite(motor_reg, HIGH); //торможение
    }
    else
    {
      digitalWrite(motor_reg, LOW);
    }
  }
  else if (group_num == 2)
  {
    mot_speed = map(pot_value, 640, 1023, 0, 255);
    mot_speed = constrain(mot_speed, 0, 255);
    analogWrite(motor_reg, mot_speed);
  }
}

Я попробовал поступить следующим образом: Поскольку потенциометр будет генерировать входной сигнал АЦП с 1024 состояниями, я разделил эти 1024 состояния на 8 групп, первые три группы, охватывающие первые 384 состояния (0–383), соответствуют направлению двигателя постоянного тока (скажем, против часовой стрелки), что представляет собой разные скорости вращения (игнорируя проблемы сопоставления «многие к одному»). Средние 2 группы, 256 состояний (384-639), соответствуют стационарному двигателю. Последние три группы, 384 состояния (640-1023), соответствуют вращению двигателя в другую сторону (в данном примере по часовой стрелке). Входы АЦП должны быть преобразованы в аналоговые выходы с 256 возможными состояниями (0–255), поэтому я отображаю каждый диапазон соответствующим образом; для 0-383 отображение должно быть обратным, поэтому ввод 383 соответствует вводу 0. Средний диапазон (384-639) является стационарным, но я попытался сделать небольшой «поддиапазон» в середине. «Диапазон торможения», я полагал, что это достигается путем установки обоих входов H-моста на НИЗКИЙ уровень. Сопоставление диапазона 640–1023 – от 640 до 0 и от 1023 до 255.

Надеюсь, это имеет смысл. Кажется, это работает, проблема, с которой я столкнулся, заключается в том, что двигатель, кажется, достигает большей скорости в одном направлении по сравнению с другим: максимальная скорость вращения, создаваемая двигателем, больше, когда потенциометр находится на максимуме в одном направлении по сравнению с другой. Я почти уверен, что приведенный выше код дает «четное» отображение потенциометра на двигатель в обоих направлениях. Значит, это как-то связано с аппаратным обеспечением? И следует ли этого ожидать в такого рода установках?

Любая помощь будет оценена по достоинству. Если у кого-нибудь есть какие-либо советы о том, как лучше всего объединить вход потенциометра или аналогичный вход с выходом двигателя, дайте мне знать. Функция «торможения» также немного сбивает с толку.

, 👍1

Обсуждение

Я ценю все отзывы на данный момент. Хотелось бы добавить, что сам код является продуктом ряда факторов. Частично это ограничено учебником: я пытаюсь ограничить код тем, что описано в учебнике, над которым я работаю. Другие факторы включают в себя: I) я хотел использовать ряд функций и II) я хотел написать программу, которая бы обходила настройку контактов H-Bridge на каждой итерации. Моя основная мотивация для публикации заключается в том, что я хотел бы знать, является ли проблема, с которой я столкнулся со скоростью двигателя, проблемой кодирования или, возможно, проблемой оборудования., @Jay Lin