ШИМ L298n и "шум" от двигателей

hacker_007
Offline
Зарегистрирован: 14.04.2015

Здравствуйте. Столкнулся с такой проблемой. Собираю модель. Подключил драйвер L298n к ардуино. В планах использовать ШИМ. 

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

    if(ps2x.Button(PSB_PAD_UP)) {     
      goF();
      Serial.print("Up held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
    }
     else {
      turnS();
    }

Модель управляеся беспроводным джойстиком от PS. В части кода обрабатывается нажатие на джойстике и вызывается функция.

 void goF()
{
  digitalWrite(Motor1Dvig1, LOW);
  digitalWrite(Motor1Dvig2, HIGH);
  digitalWrite(Motor2Dvig1, HIGH);
  digitalWrite(Motor2Dvig2, LOW);
  analogWrite(RegSpeed1, 255);
  analogWrite(RegSpeed2, 255);
}

Двежение вперед выполняется как требуется.

НО. Стоит добавить условие обработки нового действия, допустим назад:

void goB()
{
  digitalWrite(Motor1Dvig1, HIGH);
  digitalWrite(Motor1Dvig2, LOW);
  digitalWrite(Motor2Dvig1, LOW);
  digitalWrite(Motor2Dvig2, HIGH);
 analogWrite(RegSpeed1, 255);
 analogWrite(RegSpeed2, 255);
} 
//------------------------------------------------------------------------------
    if(ps2x.Button(PSB_PAD_DOWN)){
      goB();
      Serial.print("DOWN held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
    }
     else {
      turnS();
    }

Все перестает работать. Сигнал принимается и обрабатывается. Двигатели на команду вперед реагируют но, такое ощущение, что значение ШИМ на одном 30 на другом 50. Т.е. одна сторона пытается немного вращаться а другая только писк двигателем издает.

Движение назад так же ра ботает. НО. С нормальной скоростью вращаестя только одна сторона. А вторая немного пищит.

Возник вопрос: Почему...

В голову приходит 2 вещи. Либо не исправный драйвер, хотя такая проблема была на 2 платах, либо шум двигателей. Получилось так, что из-за конструктивной особенности, плата драйвера стоит прим возле двух движков. Может это играть свою роль? (плата с L298n заказывалась с алика) 

И еще один момент. На время я питаю ардуину от USB. От драйвера двигателя GND идет на GND ардуины. И, после отключения питания по USB ардуина продолжает работать в течении 5 секунд, т.к. вращаются двигатели. 

С подключение проблем быть не должно. Прочитал много постов, статей, в том числе и на Вашем форуме.

P.S. Вот весь код. Возможно кривой) Не ругайтесь)

#include <PS2X_lib.h>  //для v1.6
/******************************************************************
 * пины двигателей
 ******************************************************************/
//int RegSpeed1 = 3;
int Motor2Dvig1 = 4;
int Motor2Dvig2 = 5;

int Motor1Dvig1 = 6;
int Motor1Dvig2 = 7;
//int RegSpeed2 = 9;

int i;

/******************************************************************
 * пины приемника\передатчика
 ******************************************************************/
#define PS2_DAT        10    
#define PS2_CMD        11
#define PS2_SEL        12
#define PS2_CLK        13

#define pressures   true
#define rumble      true


PS2X ps2x; // создание класса для PS2 контроллера

int error = 0;
byte type = 0;
byte vibrate = 0;
int sh = 0;


void setup(){
  
  Serial.begin(57600);
  delay(900);  //добавляем паузу, чтобы дать беспроводному ps2 модулю время для включения
  error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
  type = ps2x.readType(); 
  
  pinMode(Motor1Dvig1, OUTPUT);
  pinMode(Motor1Dvig2, OUTPUT);
  pinMode(Motor2Dvig1, OUTPUT);
  pinMode(Motor2Dvig2, OUTPUT);
  //pinMode(RegSpeed1, OUTPUT);
  //pinMode(RegSpeed2, OUTPUT);
}

//Поворот вправо на месте========
  void turnR()
{
  digitalWrite(Motor1Dvig1, HIGH);
  digitalWrite(Motor1Dvig2, LOW);
  digitalWrite(Motor2Dvig1, HIGH);
  digitalWrite(Motor2Dvig2, LOW);
  //analogWrite(RegSpeed1, 255);
  //analogWrite(RegSpeed2, 255);
}

//Поворот влево на месте========
  void turnL()
{
  digitalWrite(Motor1Dvig1, LOW);
  digitalWrite(Motor1Dvig2, HIGH);
  digitalWrite(Motor2Dvig1, LOW);
  digitalWrite(Motor2Dvig2, HIGH);
  //analogWrite(RegSpeed1, 255);
  //analogWrite(RegSpeed2, 255);
}
//Прямо===========================
 void goF()
{
  digitalWrite(Motor1Dvig1, LOW);
  digitalWrite(Motor1Dvig2, HIGH);
  digitalWrite(Motor2Dvig1, HIGH);
  digitalWrite(Motor2Dvig2, LOW);
  //analogWrite(RegSpeed1, 255);
  //analogWrite(RegSpeed2, 255);
}
//Назад===========================
void goB()
{
  digitalWrite(Motor1Dvig1, HIGH);
  digitalWrite(Motor1Dvig2, LOW);
  digitalWrite(Motor2Dvig1, LOW);
  digitalWrite(Motor2Dvig2, HIGH);
  //analogWrite(RegSpeed1, 255);
  //analogWrite(RegSpeed2, 255);
} 
 //Стоп==========================
void turnS()
{
  //analogWrite(RegSpeed1, 0);
  //analogWrite(RegSpeed2, 0);
  digitalWrite(Motor1Dvig1, LOW);
  digitalWrite(Motor1Dvig2, LOW);
  digitalWrite(Motor2Dvig1, LOW);
  digitalWrite(Motor2Dvig2, LOW);
}

void loop() {

    if(ps2x.Button(PSB_PAD_UP)) {     
      goF();
      Serial.print("Up held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
    }
     else {
      turnS();
    }

    if(ps2x.Button(PSB_PAD_DOWN)){
      goB();
      Serial.print("DOWN held this hard: ");
      Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
    }
     else {
      turnS();
    }
         
       delay(50); 
}

 

hacker_007
Offline
Зарегистрирован: 14.04.2015

На коментированные строки не обращайте внимания.

//analogWrite(RegSpeed1, 255);
 //analogWrite(RegSpeed2, 255);

Пробовал работу без ШИМ.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Цитата:
Двигатели на команду вперед реагируют но, такое ощущение, что значение ШИМ на одном 30 на другом 50. Т.е. одна сторона пытается немного вращаться а другая только писк двигателем издает.

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

Правда, не исклбючены и ошибки как в монтаже, так и в скетче.

Попытайтесь поменять местами двигатели, как изменится поведение тележки?

hacker_007
Offline
Зарегистрирован: 14.04.2015

Так же(

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

На ШИМ 30 или даже 50 далеко не каждый двигатель ваще поедет .. коллекторные движки имеют линейную мех. характеристику от поданного напряжения. Двигатель вкупе с искрогасящим конденсатором = интегратор. То есть ваш ШИМ - это практически управление двиглом через напряжение. Ну и как сказал andriano - не бывает двух одинаковых двигателей, редукторов, трений в осях, шин с дорогой и т.д.

А при невысоком напряжении скорость вращения двигла сильно зависит от требуемой мощности с мотора. Есть схемы, имеющие ПОС по току, которые способны корректировать ШИМ для достижения заданного тока в моторе согласно поданному ШИМ, ибо крутит мотор ток, а не напряжение. В разделе Общий есть тема "Скоростное движение по линии", там была ссылка на такой вариант схемы. Мне сейчес искать некогда.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

P.S. Да, ещё не забывайте что L298N это биполярные Дарлингтоны в управляющем мосту .. на них высаживается от 1 до 1.5 (а то и больше) вольт от питания двигателей .. возможно что оставшегося напряжения питания двиглу банально недостаточно для нормальной работы. Для исправления этого недостатка - смотрите тему в проектах "драйвер мотора робота на мосфетах". Там есть очень простая схема на базе АО4606, которую уже собирал и которая зарекомендовала себя с самой лучшей стороны при правильном управлении в переключении направлений. Сейчас там народ делает "умный драйвер", который можно будет посадить непосредственно на моторчик и работать с мотором по шине I2C, жду когда что-то получится, может закажу себе или тоже займусь сборокой таких драйверов сам.. (смотря что окажется проще/быстрее/дешевле по времени и/или деньгам). :)

hacker_007
Offline
Зарегистрирован: 14.04.2015

Это все понятно. Да черт с ней, со скоростью вращения разной... Интересно, почему вообще все работать перестает...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

hacker_007 пишет:

Так же(

Это принципиально невозможно.

hacker_007
Offline
Зарегистрирован: 14.04.2015

Почему? Поменял местами двигатели, поведение тоже самое, только зеркально.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

"Зеркально" и "то же самое" - взаимоисключающие вещи.

Кроме того, "зеракльно" может быть относительно разных вещей, следовательно, без указания, относительно чего именно "зеркально", ваше сообщение не несет никакой информации.

Novichok64
Offline
Зарегистрирован: 26.11.2016

Здравствуйте. Как я понимаю, дефект переходит вместе с перестановкой моторчиков?

1. Какое напряжени питания драйверов? (попробуйте увеличить в разумных пределах).

2. установлены ли конденсаторы на клеммах моторов?

3. поменять моторы? 

Желаю удачи!

hacker_007
Offline
Зарегистрирован: 14.04.2015

1. 8 вольт. 

2. Да. 2 по 0,001 микрофарад.

3. Альтернативы нет(

Спасибо!

Novichok64
Offline
Зарегистрирован: 26.11.2016

1. Дефект возникает при резкой смене команд? Присутвует ли он, если сделать задержку между ними, чтобы моторы остановились?

2. Нет ли замыкания на моторах, скажем касания ножки конденсатора на корпус? 

vvadim
Offline
Зарегистрирован: 23.05.2012

уберите  else { turnS()}

для этой функции сделайте отдельную команду

 

   

 

hacker_007
Offline
Зарегистрирован: 14.04.2015

Одна нога одного кондера припаяна к контакту, другая нога другого припаяна к другому контакту и обе другие ноги запаяны на корпус. Нет, при нажатии\отпускании реакция на команды адекватная.

hacker_007
Offline
Зарегистрирован: 14.04.2015

Как можно это реализовать?

Novichok64
Offline
Зарегистрирован: 26.11.2016

Как реализовать? Если я правильно понял, то можно сделать:

1. Вложенное условие. /*  если джойстик вверх,{ тогда функция "вперед"}  иначе {если джойстик вниз, {тогда фукнция "назад"} иначе {функция стоп}}   */

2. убрать else совсем, сделав три условия для каждого положения джойстика.