Управление двумя DC моторами от Джойстика

Тема в разделе "Закажу проект", создана пользователем Шевчук 1966, 29 янв 2016.

  1. Буня

    Буня Нуб

    НАДО! ОЧЕНЬ НАДО!
    Пожалуйста, продолжайте!
    У меня ровно такая же проблема, но не такой категоричный тон.
    Это единственный тред, который полностью соответствует моим двухмесячным запросам в яндексе и гугле и бинге.
    Если ещё есть возможность - молю, продолжайте!
     
  2. GGV

    GGV Нуб

    у меня та же проблема, сделал видеоголову, не могу найти скетч для управления двумя моторами от джойстика, если кто победил данную проблему, поделитесь скетчем, пожалуйста
     
  3. GGV

    GGV Нуб

    скажите, может кто-нить поправить данный код за небольшое вознаграждение?
    в наличии Arduino Uno R3 + L298N + 2DC мотора + Джойстик

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

    схема подключения прилагается
    Заранее огромное СПАСИБО!

    Код (C++):
    int xValue, yValue;
    int ENA = 8;
    int in1 = 9;
    int in2 = 10;
    int ENB = 13;
    int in3 = 11;
    int in4 = 12;
    int xPin = A1;
    int yPin = A0;   // Ось Y подключена к Analog 0
    void setup()
    {
      pinMode(ENA, OUTPUT);
      pinMode(ENB, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      pinMode(in3, OUTPUT);
      pinMode(in4, OUTPUT);
      pinMode(xPin, INPUT);
      pinMode(yPin, INPUT);
      Serial.begin(9600);
    }
    void loop()
    {
    //читаем значения с джойстика и ремапим их от 0 до 252
    xValue = map(analogRead(xPin), 0, 1024, 0, 252);
    yValue = map(analogRead(yPin), 0, 1024, 0, 252);
    Serial.print(xValue); //выводим значение x
    Serial.print("\t"); //отступ
    Serial.print(yValue); //выводим значение y
    Serial.print("\t"); //отступ
    if (xValue <= 100)
    {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    }
    else if (xValue > 101 && xValue <149)
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    }
    if (xValue >= 150)
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    }
    else if (xValue > 101 && xValue <149)
    {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////
    if (yValue <= 100)
    {
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    }
    else if (yValue > 101 && yValue <149)
    {
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    }
    if (yValue >= 150)
    {
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    }
    else if (yValue > 101 && yValue <149)
    {
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);
    }
    }
     

    Вложения:

    • Arduino.jpg
      Arduino.jpg
      Размер файла:
      120,5 КБ
      Просмотров:
      1.204
  4. Allex_1981

    Allex_1981 Нерд

    Код (C++):
    const int Y_PIN = A5;           // Потенциометр оси Y подключен к аналоговому входу 5
    const int X_PIN = A4;           // Потенциометр оси X подключен к аналоговому входу 4

    // Первый двигатель
    int enA = 10;
    int in1 = 9;
    int in2 = 8;
    // второй двигатель
    int enB = 5;
    int in3 = 7;
    int in4 = 6;



    void setup()
    {
    Serial.begin(9600);  // Скорость работы с монитором порта

    pinMode(enA, OUTPUT);
    pinMode(in1, OUTPUT);
    pinMode(in2, OUTPUT);
    pinMode(enB, OUTPUT);
    pinMode(in3, OUTPUT);
    pinMode(in4, OUTPUT);
    }

    void loop()
    {
    int yVal = analogRead(Y_PIN);   // Задаем переменную yVal для считывания показаний аналогового значения
    int xVal = analogRead(X_PIN);

    int xValue = map(xVal, 0, 900, 0, 504);
    int yValue = map(yVal, 0, 900, 0, 504);
    //Управляем первым двигателем
    if (xValue < 235) {
       digitalWrite(in1, HIGH);
       digitalWrite(in2, LOW);
       analogWrite(enA, 235-xValue);
        };


    if (xValue < 255 && xValue > 235) {
     
       analogWrite(enA, 0);
        };


    if (xValue > 255) {
       digitalWrite(in2, HIGH);
       digitalWrite(in1, LOW);
       analogWrite(enA, xValue-255);
        };

    //Управляем вторым двигателем
    if (yValue < 235) {
       digitalWrite(in3, HIGH);
       digitalWrite(in4, LOW);
       analogWrite(enB, 235-yValue);
        };


    if (yValue < 255 && yValue > 235) {
     
       analogWrite(enB, 0);
        };


    if (yValue > 255) {
       digitalWrite(in4, HIGH);
       digitalWrite(in3, LOW);
       analogWrite(enB, yValue-255);
        };



    }

    Если еще актуально, код писал сам, если какие косяки - буду править
     
    6oTuHoK нравится это.
  5. 6oTuHoK

    6oTuHoK Нуб

    Пару косячков есть:
    1) Первый в нейтральном положение джойстика на моторы постоянно идет 1-2в что ни есть гуд. Хорошо было бы сделать их полностью отключенными чтобы не пищали.
    2) Второй в том что в одну сторону джойстик по оси "Х и У" отрабатывает корректно то есть увеличивает скорость от нейтрального положения до крайнего, а вот в другие направления от нейтрального положения меньше половина хода джойстика макс скорость а потом от половины хода до конца сбрасывает обороты.
    Буду признателен если кто исправит и выложит код заново.
     
  6. LGii

    LGii Нуб

    доброй ночи , скажите , кто то может поделится рабочим скетчем ???
     
  7. Onkel

    Onkel Гуру



    Код (C++):


    int xValue, yValue;
    int ENA = 9;
    int in1 = 3;
    int in2 = 4;
    int ENB = 10;
    int in3 = 5;
    int in4 = 6;
    int xPin = A1;
    int yPin = A0;    
    void setup()
    {
      pinMode(ENA, OUTPUT);
      pinMode(ENB, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      pinMode(in3, OUTPUT);
      pinMode(in4, OUTPUT);
      pinMode(xPin, INPUT);
      pinMode(yPin, INPUT);
      Serial.begin(9600);
    }
    void loop()
    {
     
    xValue = map(analogRead(xPin), 0, 1024, 0, 510);
    yValue = map(analogRead(yPin), 0, 1024, 0, 510);
    Serial.print(xValue);  
    Serial.print("\t");  
    Serial.print(yValue);  
    Serial.println("\t");  
    if(xValue>255)
    {
    analogWrite(ENA, xValue-255);  
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    }
    else
    {
    analogWrite(ENA, 255-xValue); //  
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);


    }
    ///////////////////////////////////////////////////////////////////////////////////////////////

    if(yValue>255)
    {
    analogWrite(ENB, yValue-255);  
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    }
    else
    {
    analogWrite(ENB, 255-yValue);
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);


    }









    }

     
     
    Sergante нравится это.
  8. LGii

    LGii Нуб

    огромное спасибо )
     
  9. LGii

    LGii Нуб

     
  10. Onkel

    Onkel Гуру

    Все можно добавить. Но замечу, что аналоговый джойстик (а именно на такой и рассчитан скетч) и так дает возможность плавно регулировать скорость - достаточно плавно рулить джойстиком. Чтобы добавить плавность, нужно на analogWrite () подавать не свежеполученный с ацп сигнал, а, например, экпоненциальное скользящее среднее сигнала с АЦП, тогда у вас реакция на джойстик будет тормознутая.
    но на самом деле наиболее востребованной была бы такая коррекция - расширить диапазон "нулей" по обоим осям, чтобы у вас в определенном диапазоне около нейтрали на моторы шли четко нули, а при конечном отклонении, скажем градусов этак 5-10 , начинался бы пропорциональный рост выходного напряжения. Но это на основе предложенного скетча сделать легко и быстро.
     
  11. LGii

    LGii Нуб

    а можешь показать как и где добавить эти нули , я просто только пытаюсь понять все это. если не сложно.
     
  12. TotCambIKoka

    TotCambIKoka Нерд

    Код (C++):
    pinMode(xPin, INPUT);
    pinMode(yPin, INPUT);
    Аналоговые входы изначально определенны на INPUT их можно опустить..
     
  13. ostrov

    ostrov Гуру

    Обычный аналоговый джойстик, если мы говорим про вот такой, имеет очень небольшой рабочий ход, порядка 1 см шляпки во все стороны. То есть поймать им нужное положение довольно сложно, особенно без тренировки. И обеспечить плавный разгон/торможение тоже. Для того чтобы не напортачить, желательно программно сглаживать работу моторов. Джойстиками устанавливаем желаемую скорость и направление, а моторы плавно стремятся к ним от своих текущих. Делается это через прерывание по таймеру. Таким образом мы обеспечим заданную плавность и избежим резких толчков, особенно при реверсе.
     
  14. Onkel

    Onkel Гуру

    Оккама не забываем. Экпоненциально взвешенная скользящая средняя и дело с концом.
     
  15. LGii

    LGii Нуб

    доброй ночи , а можно то , что сказано на примере написать или нарисовать ??? плиз ))
     
  16. ostrov

    ostrov Гуру

    Я делал так. Есть переменные в которых содержится реальная мощность и направление двигателей, есть в которых содержится желаемые мощность и направление (берется с тех же джойстиков). Настраиваем прерывание по таймеру, я сделал 20 раз в секунду, но можно и меньше, например 5. В прерывании реальное приближается к желаемому на некоторую дельту, в зависимости от частоты прерываний и требуемой скорости реакции. Например, при частоте 20 раз в секунду у меня мощность изменяется на 5, то есть с нуля до полной мощности разгон осуществляется примерно за 1 секунду. Разумеется, можно сделать быстрее или медленнее.

    Пример кода могу привести, но его надо допиливать в зависимости от конкретного МК, движка и механики.
     
  17. Onkel

    Onkel Гуру

    другими словами, вы реализовали п-регулятор. Но можно не останавливаться на достигнутом и реализовать пид регулятор. Вещь! Пригодится в любой системе регулирования чего угодно, причем выбором коэффициентов его всегда можно превратить в п- регулятор. Я пишу сам, но в принципе встречал упоминания о готовых пид - библиотеках. Желающим писать самим рекомендую посмотреть материал о пид у DiHalta в easyelectronics.
     
  18. Sergante

    Sergante Нуб

    Позвольте обеспокоить с уточнениями ..
    Я "чайник" наи-чайниковый.. Только вот научился хотя бы загружать скетчи.
    Этот скетч (от 16авг 2016г) управляет только одним моторчиком.
    Управляется джойстиком - но! - джойстик странно им "рулит" - вправо/вниз - а мотор вперед/назад
    Что надо вписать в этот скетч, чтобы второй моторчик заработал?
    И хорошо бы так, чтобы джойстик ..правильно стал работать.
    Скетч, который в теме ПОСЛЕ этого(что я привел) указан - то есть самый последний - он также позволяет управлять этим же - ОДНИМ моторчиком. разница лишь в том, что моторчик постоянно гудит - будто на него подается крайне слабое питание.. А джойстик управляет иначе - вверх/вниз - мотор вперед, джойстик вправо - мотор назад - может неточно, но я не стал долго перепроверять - гудение моторчика опасения вызвало..
    Пожалуйста, если кому не составит труда - подскажите, пожалуйста - что надо изменить в скетче?
     
  19. vvr

    vvr Инженерище

    указанный вами скетч управляет двумя моторами
    для смены оси джойстика
    int xPin = A1;
    int yPin = A0;
    замените на
    int xPin = A0;
    int yPin = A1;
     
  20. Onkel

    Onkel Гуру

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