Двигатель не работает в определенном случае при программировании с помощью драйвера двигателя L293D.

Я попытался создать машину, которая движется с помощью клавиатуры 4x4. Нажатие «12» разблокирует машину и заставит моторы двигаться вперед. После этого, если я нажму 4, скорость левого мотора уменьшится наполовину, позволяя двигателю повернуться влево, и наоборот для правого колеса, когда нажата клавиша 6.

Вот код:

#include <Key.h>
#include <Keypad.h>

char* startCar = "12";
int position = 0, state = 0;

/*
 * state 0: off
 * state 1: forward
 * state 2: backward
 * 
 */

const byte rows = 3; 
const byte cols = 3; 
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'}
};

byte rowPins[rows] = {2,3,4}; 
byte colPins[cols] = {PD7, PD6, PD5}; 
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

int a=12,b=11,c=10,d=9;
void setup()                    
{
  pinMode(a,OUTPUT);
  pinMode(b,OUTPUT);
  pinMode(c,OUTPUT);
  pinMode(d,OUTPUT);
  Serial.begin(9600);
  setLocked(true);
}

void loop()                    
{
  char key = keypad.getKey();
  Serial.print(key);
  if (key == '9')
  {
    position = 0;
    setLocked(true);
  }
  if (key == startCar[position])
  {
    position ++;
  }
  if (position == 2)
  {
    setLocked(false);
  }
  if(state)
  {
    if(key=='2')
     {
      //Двигаться вперед
        state = 1;
        runmotors(255,0,0,255);
     }
     if(key=='8')
     {
      //Двигаться назад
        state = 2;
        runmotors(0,255,255,0);
     }
    if(key == '4')
    {
      if(state == 1)
      {
        runmotors(127.5,0,0,255);
      }
        
      else if(state==2)
        runmotors(0,127.5,255,0);
    }
    if(key == '6')
    {
      if(state == 1)
        runmotors(255,0,0,127.5);
      else if(state==2)
        runmotors(0,255,127.5,0);
      
    }
  }
  delay(100);
}

void setLocked(int locked)
{
  if (locked)
  {
    state = 0;
    runmotors(0,0,0,0);
  }
  else
  {
    state = 1; // Движется вперед
    runmotors(127.5,0,0,255);  
  }
}
void runmotors(int s1,int s2,int s3,int s4)
{
  analogWrite(a,s1);
  analogWrite(b,s2);
  analogWrite(c,s3);
  analogWrite(d,s4);
}

Все работает отлично, за исключением того, что когда состояние 1, т.е. машина едет вперед, и я нажимаю 4, левый мотор полностью останавливается, а не снижается скорость. Светодиод на щитке драйвера двигателя, который показывает, работает двигатель или нет, также гаснет. Это не вина моторного щита или Arduino, так как он работал, когда я тестировал его по отдельности с моторами (т.е. без клавиатуры и т. д.).

Вот фото щита: Щит драйвера двигателя Arduino

Хотя моя проблема в этом не совсем видна, но вот видео машины: https://www. youtube.com/watch?v=bq19gNOL8Pg

, 👍1

Обсуждение

Если поднять машину с земли, моторы крутятся? По моему опыту, вы не можете контролировать скорость двигателей постоянного тока до нуля. В какой-то момент вы достигаете точки, когда вы даете мощность двигателю, но этого недостаточно для вращения. На моем роботе-танке ШИМ 127 обычно вызывает только гул и отсутствие движения. Иногда, если я поднимаю его, чтобы было меньше сопротивления качению, мотор немного крутится. Попробуйте вместо этого использовать 200 или около того и посмотрите, работает ли это так. Это, по крайней мере, скажет вам, что код работает., @Delta_G

Также обратите внимание, что AnalogWrite принимает только целочисленные значения. Отправка 127.5 в этом случае аналогична 127., @Delta_G

@Delta_G, светодиод на моторном щите показывает, получает ли двигатель питание или нет. Сам этот светодиод гаснет. Я думаю, что конкретный контакт (контакт 12) L293D неисправен и подает только цифровое питание, либо полное, либо 0., @Raghav Arora

Какая плата? На UNO контакт 12 не является контактом PWM. Он даст полную мощность для всего, что выше 127, и ничего для 127 и ниже. Это действительно цифровой пин., @Delta_G

Да, плата Arduino Uno с драйвером двигателя L293D. https://www.robomart.com/l293d-motor-driver-shield-for-arduino-raspberry-Pi-robotics?search=l293d&dsearch=l293d. По документации пины для подключения роботов 9,10,11,12. Все остальные контакты работают отлично, кроме контакта 12., @Raghav Arora

На UNO контакт 12 не является контактом PWM. Контакт 12 может быть только высоким или низким. Если вы попытаетесь использовать AnalogWrite на контакте, который не поддерживает ШИМ, тогда он даст вам ВЫСОКИЙ уровень для любого значения больше 127 и выдаст НИЗКИЙ уровень для значений 127 и ниже. Он вообще не будет производить ШИМ., @Delta_G

Да, это кажется правильным. Я новичок в этом, поэтому просто подтвердите, когда я говорю о выводе 12 в своем коде, это один и тот же вывод, независимо от того, подключен ли я к шилду или нет, верно? Это имеет смысл. Если вы добавите это как ответ, я отмечу его как правильный. Спасибо., @Raghav Arora

Да, номера контактов в коде — это номера контактов на самой плате Arduino, независимо от того, что к ним подключено., @Delta_G


1 ответ


Лучший ответ:

1

На UNO только определенные контакты поддерживают ШИМ. Контакт 12 не является одним из них. Когда вы пытаетесь вызвать AnalogWrite с контактом 12, он распознает это и просто вызовет digitalRead для вас с HIGH или LOW в зависимости от того, превышает ли ваш ввод значение 127.

С большинством контроллеров двигателей вы можете использовать один контакт в качестве контакта направления, а другой — в качестве контакта ШИМ. Таким образом, чтобы двигаться в одном направлении, вы устанавливаете контакт 12 HIGH и выполняете инвертированный ШИМ на 11 (если они действительно относятся к одному и тому же двигателю, я не смотрел на ваш щит). Чтобы пойти в другом направлении, вы пишете LOW на 12 и PWM на 11.

Двигатель вращается, когда на одном контакте ВЫСОКИЙ уровень, а на другом НИЗКИЙ уровень. Когда вы устанавливаете высокий уровень на контакт 12, а затем на контакт 11 ШИМ, всякий раз, когда 11 имеет НИЗКИЙ уровень в цикле ШИМ, он включает двигатель, а когда он ВЫСОКИЙ, он выключает его. Поэтому, чтобы заставить его работать, вам может потребоваться PWM 0 для запуска и 255 для остановки. Иногда ваш ШИМ находится на линии включения, и тогда вы все еще используете 255 для запуска и 0 для остановки. Это просто зависит от того, как все устроено.

Когда контакт 12 установлен на НИЗКИЙ уровень, двигатель включается, когда 11 находится в верхней части цикла ШИМ, и выключается, когда он низкий, поэтому вы используете 255 для запуска и 0 для остановки. Но все время контакт 12 не должен меняться.

Теперь я не уверен на 100%, что это так с вашим конкретным контроллером двигателя, я больше кодер, чем специалист по аппаратному обеспечению. Но я написал достаточно кода для контроллеров двигателей, чтобы понять, что обычно вам нужны либо две линии направления и одна линия ШИМ, либо одно направление и одна линия ШИМ. Если это не так, мы можем позволить кому-то другому разобраться, почему.

,