Подключение monster moto shield

Тема в разделе "Arduino & Shields", создана пользователем Torresok, 17 мар 2015.

  1. Torresok

    Torresok Нуб

    Привет, дорогие форумчане. Я в этом деле новичок, поэтому прошу помощи: имеется monster moto shield (фото ниже). Как его подключить к ардуино? Я так понимаю библиотека для него не нужна? Нашел в гугле пример кода http://arduino-ua.com/docs/MonsterMoto_Shield_Example.pde, там без подключения библиотеки. jbKrEJHECx4.jpg

    Вообще задача такая: есть джойстик от ps2, его я подключаю через приемник к ардуино, а она через мотор шилд должна крутить 2 мотора. Код подключения джойстика здесь: http://robocontroller.ru/news/besprovodnoj_dzhojstik_ot_playstation_arduino/2013-10-19-32

    Очень надеюсь на помощь, так как всю голову сломал.(
     
  2. Unixon

    Unixon Оракул Модератор

    https://www.sparkfun.com/products/10182

    Шилд управляется напрямую через пины 0~9.
    См. код http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Dev/Arduino/Shields/MonsterMoto_Shield_Example.pde
    Код (Text):

    int inApin[2] = {7, 4};  // INA: Clockwise input
    int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
    int pwmpin[2] = {5, 6}; // PWM input
    int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
    int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
     
     
    Torresok нравится это.
  3. Torresok

    Torresok Нуб

    Unixon, подскажите, пожалуйста, а как управлять то им? В мониторе порта пишет, что двигатель заблокирован. Как мне его разблокировать?
     
  4. Unixon

    Unixon Оракул Модератор

    В скетче такого нет. Кто и что туда пишет?
     
  5. Unixon

    Unixon Оракул Модератор

    С помощью управляющих сигналов на указанных пинах. Вы понимаете, что написано в комментариях к коду?

    Код (Text):

    int inApin[2] = {7, 4};  // INA: Clockwise input
    int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
    int pwmpin[2] = {5, 6}; // PWM input
    int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
    int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
     
     
  6. Torresok

    Torresok Нуб

    Конечно понимаю. Но при загрузке данного скетча, мотор не работает. Порылся в гугле, нашел вот что: http://garagelab.com/profiles/blogs/tutorial-how-to-use-the-monster-moto-shield , взял скетч оттуда. Та же проблема. Шилд просто одеваваю сверху на ардуино.
     
  7. Unixon

    Unixon Оракул Модератор

    А что происходит на пинах CS и EN? Драйвер реагирует на команды?
     
  8. Torresok

    Torresok Нуб

    Так, видимо я все таки что то не понял, как мне понять, что он реагирует, и что на этих аналоговых пинах должно происходить. Я понимаю, что написано в скетче, но видимо не понимаю значения их тут.
     
  9. Unixon

    Unixon Оракул Модератор

    EN должен падать в "0" при включении соответствующего плеча драйвера, а на CS должно появляться напряжение, пропорциональное потребляемому мотором току.
     
  10. Torresok

    Torresok Нуб

    Я чет не очень понимаю как скетч должен работать? После его заливки в ардуино, моторы должны просто сами по себе работать - останавливаться - и т.д., или мне надо как то еще ими управлять?
     
  11. Хреновые скетчи в образцах по этому шилду. Посидел, поразбирался. Ниже подправленный простой скетч. Моторы работают, не шалят. На основе него можно дальше колдовать.
    Код (Text):
    /*  MonsterMoto Shield

    */

    // Определение направлений движения моторов
    #define BRAKEVCC 0
    #define CW  1
    #define CCW  2
    #define BRAKEGND 3
    #define CS_THRESHOLD 100 // предел показания по току (предел аварийной остановки). (хрен знает какой параметр выставлять) Предполагаю, что 1023 - 30А. В этом скетче

    /*  VNH2SP30 pin definitions
    xxx[0] controls '1' outputs
    xxx[1] controls '2' outputs */
    int inApin[2] = {7, 4};  // INA: по часовой стрелке. А на деле ток пойдет по проводу А
    int inBpin[2] = {8, 9}; // INB: против часовой стрелки. А на деле ток пойдет по проводу В
    int pwmpin[2] = {5, 6}; // PWM: Шим
    int cspin[2] = {A2, A3}; // CS: Показания с датчика тока на моторах          Уточнил параметр приставкой А
    int enpin[2] = {A0, A1}; // EN: Показания хз какие, типа вольтметр.  Уточнил параметр приставкой А (не используется)

    int statpin = 13; // светодиод остановки двигателя. Не реализован на платах. Надо самому его делать.

    void setup()
    {
      Serial.begin(9600);
     
      pinMode(statpin, OUTPUT);

      // Установка параметров пинов. Сделано слишком умно, что бы меньше писать.
      for (int i=0; i<2; i++)
      {
        pinMode(inApin[i], OUTPUT);
        pinMode(inBpin[i], OUTPUT);
        pinMode(pwmpin[i], OUTPUT);
      }

      // Первоначальная установка двигателей в положение СТОП по GND
      for (int i=0; i<2; i++)
      {
        digitalWrite(inApin[i], LOW);
        digitalWrite(inBpin[i], LOW);
      }
    }

    void loop()
    {
      motorGo(0, CW, 255); //  тут было 1023, но это чушь. диапазон ШИМ 0-255
      motorGo(1, CCW, 255);
      delay(500);

      motorGo(0, CCW, 255);
      motorGo(1, CW, 255);
      delay(500);
     
    //.................проверка и анализ показаний датчиков тока
    int cur1=analogRead(cspin[0]); // снятие показаний с первого мотора
    int cur2=analogRead(cspin[1]); // снятие показаний со второго мотора
    Serial.print("Motor 1: "); Serial.print(cur1); Serial.print("    "); Serial.print("Motor 2: "); Serial.println(cur2);

    // Проверка показаний по току, если да, то загорится наш светодиод. Сюда Надо вставить функцию остановки двигателя. Причем обоих, если сработает  хотя бы один из датчиков, иначе наш робот крутанётся. Можно конечно помудрить с алгоритмом и придумать ABS :)
      if ((analogRead(cspin[0]) > CS_THRESHOLD) && (analogRead(cspin[1]) > CS_THRESHOLD)) // уточнить оператор. Тут И, а мне кажется нужен ИЛИ (||)
                                                                                    // и знак должен быть > В обычной работе cspin меньше порога аварийной остановки.
          digitalWrite(statpin, HIGH); // одно действие, {} не требуется.
    }

    /* функция принимает номер мотора и вырубает его питание и обнуляет скорость.
    */
    void motorOff(int motor)
    {
        digitalWrite(inApin[motor], LOW); // отключаем питание по ноге А конкретного мотора
        digitalWrite(inBpin[motor], LOW); // отключаем питание по ноге В конкретного мотора
        analogWrite(pwmpin[motor], 0);    // принудительно подаем 0 на шим конкретного мотора, только зачем? Мотор и так остановится...
    }

    /* motorGo()
    Решил сделать int переменные, а не uint8_t. Хотя для некоторых параметров int жирновато.
    */
    void motorGo(int motor, int direct, int pwm)
    {
      if ((motor <= 1) && (direct <=3))  // предохранитель, только мотор 0 или 1, а направление 0,1,2,3.
      {
          // Set inA[motor]
          if (direct <=1)
            digitalWrite(inApin[motor], HIGH);
          else
            digitalWrite(inApin[motor], LOW);

          // Set inB[motor]
          if ((direct==0)||(direct==2))
            digitalWrite(inBpin[motor], HIGH);
          else
            digitalWrite(inBpin[motor], LOW);

          analogWrite(pwmpin[motor], pwm);
      }
    }
     
    Ниже мониторинг COM по загадочному cspin. Моторы взял "china noname" с танка Heng Long, батарейка Turnigy 4000 7.4V :
    Код (Text):
    Motor 1: 26    Motor 2: 12
    Motor 1: 24    Motor 2: 12
    Motor 1: 24    Motor 2: 11
    Motor 1: 28    Motor 2: 13
    Motor 1: 27    Motor 2: 11
    Motor 1: 24    Motor 2: 12
    Motor 1: 24    Motor 2: 10
    Motor 1: 25    Motor 2: 14
    Motor 1: 25    Motor 2: 15
    Motor 1: 26    Motor 2: 13
    Motor 1: 26    Motor 2: 14
    Motor 1: 27    Motor 2: 11
    Motor 1: 24    Motor 2: 12
    Motor 1: 20    Motor 2: 13
    Motor 1: 26    Motor 2: 11
    Motor 1: 25    Motor 2: 15
    Motor 1: 27    Motor 2: 14
    Motor 1: 25    Motor 2: 14
    Motor 1: 27    Motor 2: 11
    Motor 1: 23    Motor 2: 13
    Motor 1: 25    Motor 2: 11
    Motor 1: 25    Motor 2: 13
     
  12. Argishti

    Argishti Нуб

    неплохо но могло быть и получше



     
  13. Argishti

    Argishti Нуб

    ловите профи вариант, сам написал и тестировал, более безопасно и стабильно, а самое главное не перегревается

    //created by Argishti Avetikyan, argishtiavetikyan@yandex.ru


    #define motor1 0
    #define motor2 1
    #define cw 1
    #define ccw 2
    #define brake 0
    #define maxCurrent 100

    int dirA[2] = {7, 4}; // direction A
    int dirB[2] = {8, 9}; // direction B
    int PWMpin[2] = {5, 6}; // PWM (motor speed)
    int cspin[2] = {2, 3}; // Electric current
    int enpin[2] = {0, 1}; // Status of switches output
    int LedPin=13;
    float AA=analogRead(cspin[0]);
    float BB=analogRead(cspin[1]);

    void setup()
    {
    pinMode(LedPin, OUTPUT);

    for (int i=0; i<2; i++)
    {
    pinMode(dirA, OUTPUT);
    pinMode(dirB, OUTPUT);
    pinMode(PWMpin, OUTPUT);
    }

    for (int i=0; i<2; i++)
    {
    digitalWrite(dirA, LOW);
    digitalWrite(dirB, LOW);
    analogWrite(PWMpin, 0);
    }
    }

    void loop()
    {
    motorGo(motor1, cw ,255);
    delay (500);
    Serial.print(AA);
    motorGo(motor1, brake ,255);
    delay (500);
    motorGo(motor1, ccw ,255);
    delay (500);
    motorOff(motor1);
    delay (500);

    motorGo(motor2, cw ,255);
    delay (500);
    motorGo(motor2, brake ,255);
    delay (500);
    motorGo(motor2, ccw ,255);
    delay (500);
    motorOff(motor2);
    delay (500);


    }
    void motorOff(int motor)
    {
    digitalWrite(dirB[motor], LOW);
    digitalWrite(dirA[motor], LOW);
    analogWrite(PWMpin[motor], 0);
    }
    void motorGo(int motor, int dir, int pwm)
    {
    if ((motor <= 1) && (dir <=3))
    {
    if ((dir == 1) && (AA < maxCurrent))
    {
    digitalWrite(dirB[motor], LOW);
    delay (5);
    digitalWrite(dirA[motor], HIGH);
    delay (5);
    }
    else if (dir==2 && (BB < maxCurrent))
    {
    digitalWrite(dirA[motor], LOW);
    delay (5);
    digitalWrite(dirB[motor], HIGH);
    delay (5);
    }
    else
    {
    digitalWrite(dirB[motor], LOW);
    digitalWrite(dirA[motor], LOW);
    delay (5);
    }
    analogWrite(PWMpin[motor], pwm);
    }
    }
     
  14. Большое спасибо! Интересные поправки. Приму к сведению.
    У меня, как у дилетанта, есть несколько вопросов:
    1)
    Код (Text):
    int cspin[2] = {2, 3};
    int enpin[2] = {0, 1};
    Не будут ли путаться обычные пины с аналоговыми? Они же одинаковые номера имеют.
    2) Как я понял, перегрев имелся ввиду - торможение током, когда dirA и dirB = HIGH. Насколько это вредно для техники? Я хотел использовать это торможение, что бы фиксировать робота, например, на подъеме в горку. А обычный motorOff вырубит питание моторов и робот просто скатится вниз.
    3)
    Код (Text):
     motorGo(motor2, brake ,255)
    На сколько актуален тут показатель ШИМ? В чем разница с motorOff?
    Собственно отсюда вытекает, что функция motorOff лишняя. Она равна motorGo(motor, brake , 0);
    4)Я не знаток C++, только учусь. Этот код поставил меня в тупик. Он правда работает?
    Код (Text):
    for (int i=0; i<2; i++)
    {
    pinMode(dirA, OUTPUT);
    pinMode(dirB, OUTPUT);
    pinMode(PWMpin, OUTPUT);
    }

    for (int i=0; i<2; i++)
    {
    digitalWrite(dirA, LOW);
    digitalWrite(dirB, LOW);
    analogWrite(PWMpin, 0);
    }
    тут же в операторах не указано куда подставлять i. Неужели система сама определяет что при i=0 dirA[0]=7?
     
  15. DrProg

    DrProg Вечный нерд

    Добрался я до монстр шилда наконец. С наскоку напоролся на то, что работает он мягко говоря некорректно. Пока разбираюсь, похоже что родной пример не без ошибок, как и тутошний "профи" вариант.
     
    Последнее редактирование: 10 сен 2015
    ИгорьК нравится это.
  16. DrProg

    DrProg Вечный нерд

    С глюками разобрался. Главная причина в том, что, как выше заметил Андрей Александрович, в фирменном примере был указан диапазон 0-1023, в реальности же он 0-254, стало быть плавный разгон до 1023 невозможен в принципе. В остальном все ок, чипы даже не греются при подключении двухамперных двигателей на каждый канал, а вот сами движки да. )
     
    ИгорьК нравится это.
  17. Unixon

    Unixon Оракул Модератор

    Еще бы они грелись при всего-то 19 мОм на открытом канале, там тепловыделение 3 мВт всего при 2А.
     
  18. Petro

    Petro Нерд

    Всем привет, подскажите по монстру:
    при подаче на моторы напряжения по шим от 0 до 255 начиная с примерно 100 до 200 моторы крутятся рывками, а на малой мощности и на макс все нормально.
    В чем может быть причина?
    Спасибо
     
  19. Petro

    Petro Нерд

    Уже разобрался - колекторный мотор и частота шим совпадала с частотой замыкания ламелей.
    Поднял частоту шим и все ок.
     
  20. Petro

    Petro Нерд

    А кто знает какой макс ток может выдать монстр на каждом канале?
    В описании есть 14а и 30а в пиках, но не понятно - на одном канале или в суме на двоих?