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

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

Цикл имеет три функции: 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


2 ответа


1

Лично я бы не стал заморачиваться с "группами". Просто сделайте простую математику:

int velocity = analogRead(POT_MOT) - 512;

velocity теперь дает вам значение от -512 до +511.

bool dir = (velocity >= 0);

dir теперь имеет значение true для положительного значения (0 считается положительным) или false для отрицательного.

velocity = abs(velocity);

скорость теперь становится положительной, если она отрицательная.

Теперь у вас есть две переменные: dir, которая задает направление, и velocity, которая задает скорость.

Теперь вы можете «компенсировать» это:

velocity = map(velocity, 0, 512, -128, 255);

velocity теперь изменено, чтобы соответствовать диапазону от -128 до 255. Все, что выше 0, является допустимой скоростью, все, что ниже, является «мертвой зоной» и останавливает двигатель.

if (velocity <= 0) {
    // Если отрицательно или ноль, остановитесь
    digitalWrite(motor_reg, LOW);
    digitalWrite(first_motor, LOW);
    digitalWrite(sec_motor, LOW);
} else {
    if (dir) { // Pot был положительным
        analogWrite(motor_reg, velocity);
        digitalWrite(first_motor, LOW);
        digitalWrite(sec_motor, HIGH);
    } else { // Банк был отрицательным
        analogWrite(motor_reg, velocity);
        digitalWrite(first_motor, HIGH);
        digitalWrite(sec_motor, LOW);
    }
}

Отрегулируйте отрицательное значение на карте, чтобы изменить размер «мертвой зоны».

,

0

Я бы разбил это на три или, по крайней мере, на две части:

1) вызов изменения скорости двигателя; 2) призыв считать показания счетчика потенциала; 3) вызов для преобразования настройки измерителя потенциала в скорость двигателя, необязательно.

код будет выглядеть так:

  pot_setting = potsetting_read(); //прочитать настройку горшка
  speed_setting = pot2spd(pot_setting); //преобразуем настройку потенциометра в скорость двигателя
  motor_setspeed(speed_setting); //установить скорость двигателя

Нетрудно разобраться в каждой из трех функций.

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

Основная конструкция заключается в последовательном прохождении набора состояний выводов, где длительность каждого перехода состояния контролируется прерыванием таймера. Изменяя скорость срабатывания прерывания таймера, вы изменяете скорость, с которой выводы меняют свое состояние, а значит, и скорость двигателя.

,