ШИМ L298n и "шум" от двигателей
- Войдите на сайт для отправки комментариев
Здравствуйте. Столкнулся с такой проблемой. Собираю модель. Подключил драйвер 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); }
На коментированные строки не обращайте внимания.
Пробовал работу без ШИМ.
В природе нет двух одинаковых двигателей. Поэтому вполне логично, что при одинаковом управляющем сигнале один двигатель крутится быстрее другого (либо при небольшом сигнале - один уже начал крутиться, а другой - еще стоит).
Правда, не исклбючены и ошибки как в монтаже, так и в скетче.
Попытайтесь поменять местами двигатели, как изменится поведение тележки?
Так же(
На ШИМ 30 или даже 50 далеко не каждый двигатель ваще поедет .. коллекторные движки имеют линейную мех. характеристику от поданного напряжения. Двигатель вкупе с искрогасящим конденсатором = интегратор. То есть ваш ШИМ - это практически управление двиглом через напряжение. Ну и как сказал andriano - не бывает двух одинаковых двигателей, редукторов, трений в осях, шин с дорогой и т.д.
А при невысоком напряжении скорость вращения двигла сильно зависит от требуемой мощности с мотора. Есть схемы, имеющие ПОС по току, которые способны корректировать ШИМ для достижения заданного тока в моторе согласно поданному ШИМ, ибо крутит мотор ток, а не напряжение. В разделе Общий есть тема "Скоростное движение по линии", там была ссылка на такой вариант схемы. Мне сейчес искать некогда.
P.S. Да, ещё не забывайте что L298N это биполярные Дарлингтоны в управляющем мосту .. на них высаживается от 1 до 1.5 (а то и больше) вольт от питания двигателей .. возможно что оставшегося напряжения питания двиглу банально недостаточно для нормальной работы. Для исправления этого недостатка - смотрите тему в проектах "драйвер мотора робота на мосфетах". Там есть очень простая схема на базе АО4606, которую уже собирал и которая зарекомендовала себя с самой лучшей стороны при правильном управлении в переключении направлений. Сейчас там народ делает "умный драйвер", который можно будет посадить непосредственно на моторчик и работать с мотором по шине I2C, жду когда что-то получится, может закажу себе или тоже займусь сборокой таких драйверов сам.. (смотря что окажется проще/быстрее/дешевле по времени и/или деньгам). :)
Это все понятно. Да черт с ней, со скоростью вращения разной... Интересно, почему вообще все работать перестает...
Так же(
Это принципиально невозможно.
Почему? Поменял местами двигатели, поведение тоже самое, только зеркально.
"Зеркально" и "то же самое" - взаимоисключающие вещи.
Кроме того, "зеракльно" может быть относительно разных вещей, следовательно, без указания, относительно чего именно "зеркально", ваше сообщение не несет никакой информации.
Здравствуйте. Как я понимаю, дефект переходит вместе с перестановкой моторчиков?
1. Какое напряжени питания драйверов? (попробуйте увеличить в разумных пределах).
2. установлены ли конденсаторы на клеммах моторов?
3. поменять моторы?
Желаю удачи!
1. 8 вольт.
2. Да. 2 по 0,001 микрофарад.
3. Альтернативы нет(
Спасибо!
1. Дефект возникает при резкой смене команд? Присутвует ли он, если сделать задержку между ними, чтобы моторы остановились?
2. Нет ли замыкания на моторах, скажем касания ножки конденсатора на корпус?
уберите else { turnS()}
для этой функции сделайте отдельную команду
Одна нога одного кондера припаяна к контакту, другая нога другого припаяна к другому контакту и обе другие ноги запаяны на корпус. Нет, при нажатии\отпускании реакция на команды адекватная.
Как можно это реализовать?
Как реализовать? Если я правильно понял, то можно сделать:
1. Вложенное условие. /* если джойстик вверх,{ тогда функция "вперед"} иначе {если джойстик вниз, {тогда фукнция "назад"} иначе {функция стоп}} */
2. убрать else совсем, сделав три условия для каждого положения джойстика.