Arduino mega + motor shield

elranon
Offline
Зарегистрирован: 28.05.2012

Всем привет!

Простите чайника за такой вопрос, наверно покажется глупым, так как все банально)

У меня есть arduino mega 2650, платформа http://www.dfrobot.com/index.php?route=product/product&path=37_111&product_id=97 и мотор шилд http://ladyada.net/make/mshield/

Я не обладаю особыми познаниями в электронике, и все делаю методом проб и ошибок)

Я установил этот шилд аккурат на Ардуину, сверху, подключил батарейный блок с 6 батареями к контактам шилда, и воткнул в разьем М1 два проводка от мотора, и запустил простейший скетч чтобы проверить работоспособность:

#include <AFMotor.h>

AF_DCMotor motor(1, MOTOR12_64KHZ); // create motor #2, 64KHz pwm

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  
  motor.setSpeed(200);     // set the speed to 200/255
}

void loop() {
  Serial.print("tick");
  
  motor.run(FORWARD);      // turn it on going forward
  delay(1000);

  Serial.print("tock");
  motor.run(BACKWARD);     // the other way
  delay(1000);
  
  Serial.print("tack");
  motor.run(RELEASE);      // stopped
  delay(1000);
}

Я пробовал разные скетчи из примеров этой библиотеки, и ничего.
Потом подключил каждый мотор напрямую к батарейному блоку с 6 аккумуляторами, чтобы проверить их работоспособность - все работает.
Обьясните, что я делаю не так? Может ардуина как то не так работает, сгорела, и тд, или у меня просто руки кривые?) 

Вот пара фоток конструкции

 

 

maksim
Offline
Зарегистрирован: 12.02.2012
elranon
Offline
Зарегистрирован: 28.05.2012

Не нашел кнопки редактирования поста, поэтому кину сюда

 

maksim
Offline
Зарегистрирован: 12.02.2012

От таких фото толку ровно ноль. Сфотайте по нормальному, что бы было видно как и куда подключен двигатель и питание. Так же отключите крону от меги и подключите мегу к компу.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Да уж, провода в EXT_PWR стремно подключены. Это не причина, но меня это сразу "закоротило".

elranon
Offline
Зарегистрирован: 28.05.2012

а код программы правильный? если один мотор я подключаю к M1 на плате, то должен работать этот код?

Более качественные фото выложу вечером

elranon
Offline
Зарегистрирован: 28.05.2012

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

На мотор шилде перемычка убрана, дабы питание шло именно от батарейного отсека. Вот фото подключения:

maksim
Offline
Зарегистрирован: 12.02.2012

1. Проверьте напряжение на аккумуляторах - не разряжены ли они.
2. Так попробуите:

#include <AFMotor.h>

AF_DCMotor motor(1, MOTOR12_64KHZ); // create motor #2, 64KHz pwm

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!"); 
  motor.setSpeed(200);     // set the speed to 200/255
}

void loop() {
  Serial.print("tick");
  
  motor.run(FORWARD);      // turn it on going forward
  delay(10000);

  Serial.print("tock");
  motor.run(BACKWARD);     // the other way
  delay(10000);
  
  Serial.print("tack");
  motor.run(RELEASE);      // stopped
  delay(1000);
}

3. У двигателей какое номинальное напряжение питания? может 6 вольт ему маловато.

elranon
Offline
Зарегистрирован: 28.05.2012

1. аккумуляторы свежие - только поставил из коробки, и если подключить к ним двигатель напрямую, то он крутиться очень бодро и быстро.

2. попробовал этот код - та же фигня, чуть пытается провернуться, и все, и потом назад.

3. 4WD Mobile platform Motors: 3-12V DC. 6 вольт должно хватать слихвой... вот нашел еще данные по этим моторам: The 6V, 180rpm. вот он http://www.dfrobot.com/index.php?route=product/product&path=47_110&product_id=100#.UUIv8ld42ls

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

maksim
Offline
Зарегистрирован: 12.02.2012

Вы на всех выходах М1, М2, М3 и М4 пробовали?

elranon
Offline
Зарегистрирован: 28.05.2012

Да, пробовал на всех выходах, везде аналогичная ситуация. Как быть? может вольтметром замерить выходное напряжение на выходах М1 и прочих? Но понятное дело что наверно оно будет невелико, раз моторчик не крутится...

maksim
Offline
Зарегистрирован: 12.02.2012

А уберите-ка из 3 строки MOTOR12_64KHZ

AF_DCMotor motor(1); // create motor #2

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Проверяйте все поэтапно. 

Сначала проверьте шилд.

Выдерните его из меги и припаяйте провода напрямую к его пинам. Плюс/минус питания, инаблы и инпуты.

Подключите моторы и подавайте 5в на соответствующие инаблы (их там должно быть 8). 

Если все моторы вращабтся в различных комбинациях инаблов , значит модуль рабочий (переходим к прозвонке меги).

elranon
Offline
Зарегистрирован: 28.05.2012

Сегодня весь вечер ковырялся с ардуино и шилдом. Мне даже удалось один раз заставить моторчик работать нормально. Парадокс в том что я не сделал для этого ничего необычного, все делал так же как и раньше... Разьве что убрал из кода MOTOR12_64KHZ

Но потом все вернулось на круги своя... Я купил вольтметр и проверил. На пинах питания шилда примерно 8 вольт...

На разьеме М1 для подключения мотора 6 вольт, если туда ничего не подключено. Но если к разьему подключить мотор - то ток падает до 0. Иногда ток подскакивает до 0,3-0,4в, и тогда мотор пытаеться прокрутиться - то, о чем я писал... Вот так вот.  От чего может падать напряжение при подключении нагрузки?

Я не очень понимаю что такое инаблы и инпуты, и где посмотреть, какие пины шилда - инаблы и инпуты? Сорри за такой вопрос...)

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Но если к разьему подключить мотор - то ток падает до 0<<

Ток или напряжение ?

Если ток "падает до нуля " , то это значит что сопротивление нагрузки стремится к бесконечности.

Если же падает напряжение , это значит что сопротивление стремитсяк нулю.

Это огромная разница.

>>Я не очень понимаю что такое инаблы и инпуты, и где посмотреть, какие пины шилда - инаблы и инпуты? Сорри за такой вопрос...)<<

На модуле не указаны пины ?

Найдите схему. Или прозвоните их по распиновке микросхемL293D.

 

Но для начала попробуйте программно порулить моторами напрямую, без этой библиотеки.

 

elranon
Offline
Зарегистрирован: 28.05.2012

падает напряжение...конечно напряжение. без нагрузки на разьемх м1, м2, м3, м4 6 вольт. стоит подключить мотор - 0 вольт, с редкими скачками до 0,3в.  а как програмно порулить ими? можно привести простенький пример кода? насколько я понял из фака по шилду, это невозможно. надо подключать библиотеку...

elranon
Offline
Зарегистрирован: 28.05.2012

Нет ли других идей, кроме прозвонки микросхемы?

maksim
Offline
Зарегистрирован: 12.02.2012

Конечно же есть. Данная библиотека не работает с  ATmega2560.
Поэтому открываете файл: 
\arduino-0022\libraries\AFMotor\AFMotor.cpp и ко ВСЕМ строкам: defined(__AVR_ATmega1280__) добавляете  || defined(__AVR_ATmega2560__) что бы получилась вот такая строка:

  #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

после чего сохраняете файл, запускаете IDE и радуетесь.

Можете копировать содержимое файла AFMotor.cpp:

// Adafruit Motor shield library
// copyright Adafruit Industries LLC, 2009
// this code is public domain, enjoy!


#include <avr/io.h>
#include "WProgram.h"
#include "AFMotor.h"

static uint8_t latch_state;

#define MICROSTEPS 16  // 8, 16 & 32 are popular

//#define MOTORDEBUG 1

AFMotorController::AFMotorController(void) {
}

void AFMotorController::enable(void) {
  // setup the latch
  /*
  LATCH_DDR |= _BV(LATCH);
  ENABLE_DDR |= _BV(ENABLE);
  CLK_DDR |= _BV(CLK);
  SER_DDR |= _BV(SER);
  */
  pinMode(MOTORLATCH, OUTPUT);
  pinMode(MOTORENABLE, OUTPUT);
  pinMode(MOTORDATA, OUTPUT);
  pinMode(MOTORCLK, OUTPUT);

  latch_state = 0;

  latch_tx();  // "reset"

  //ENABLE_PORT &= ~_BV(ENABLE); // enable the chip outputs!
  digitalWrite(MOTORENABLE, LOW);
}


void AFMotorController::latch_tx(void) {
  uint8_t i;

  //LATCH_PORT &= ~_BV(LATCH);
  digitalWrite(MOTORLATCH, LOW);

  //SER_PORT &= ~_BV(SER);
  digitalWrite(MOTORDATA, LOW);

  for (i=0; i<8; i++) {
    //CLK_PORT &= ~_BV(CLK);
    digitalWrite(MOTORCLK, LOW);

    if (latch_state & _BV(7-i)) {
      //SER_PORT |= _BV(SER);
      digitalWrite(MOTORDATA, HIGH);
    } else {
      //SER_PORT &= ~_BV(SER);
      digitalWrite(MOTORDATA, LOW);
    }
    //CLK_PORT |= _BV(CLK);
    digitalWrite(MOTORCLK, HIGH);
  }
  //LATCH_PORT |= _BV(LATCH);
  digitalWrite(MOTORLATCH, HIGH);
}

static AFMotorController MC;


/******************************************
               MOTORS
******************************************/
inline void initPWM1(uint8_t freq) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer2A on PB3 (Arduino pin #11)
    TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
    TCCR2B = freq & 0x7;
    OCR2A = 0;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    // on arduino mega, pin 11 is now PB5 (OC1A)
    TCCR1A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc1a
    TCCR1B = (freq & 0x7) | _BV(WGM12);
    OCR1A = 0;
#endif
    pinMode(11, OUTPUT);
}

inline void setPWM1(uint8_t s) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer2A on PB3 (Arduino pin #11)
    OCR2A = s;
#elif defined(__AVR_ATmega1280__) 
    // on arduino mega, pin 11 is now PB5 (OC1A)
    OCR1A = s;
#endif
}

inline void initPWM2(uint8_t freq) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer2B (pin 3)
    TCCR2A |= _BV(COM2B1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2b
    TCCR2B = freq & 0x7;
    OCR2B = 0;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    // on arduino mega, pin 3 is now PE5 (OC3C)
    TCCR3A |= _BV(COM1C1) | _BV(WGM10); // fast PWM, turn on oc3c
    TCCR3B = (freq & 0x7) | _BV(WGM12);
    OCR3C = 0;
#endif
    pinMode(3, OUTPUT);
}

inline void setPWM2(uint8_t s) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer2A on PB3 (Arduino pin #11)
    OCR2B = s;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    // on arduino mega, pin 11 is now PB5 (OC1A)
    OCR3C = s;
#endif
}

inline void initPWM3(uint8_t freq) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer0A / PD6 (pin 6)
    TCCR0A |= _BV(COM0A1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on OC0A
    //TCCR0B = freq & 0x7;
    OCR0A = 0;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    // on arduino mega, pin 6 is now PH3 (OC4A)
    TCCR4A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc4a
    TCCR4B = (freq & 0x7) | _BV(WGM12);
    //TCCR4B = 1 | _BV(WGM12);
    OCR4A = 0;
#endif
    pinMode(6, OUTPUT);
}

inline void setPWM3(uint8_t s) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer0A on PB3 (Arduino pin #6)
    OCR0A = s;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    // on arduino mega, pin 6 is now PH3 (OC4A)
    OCR4A = s;
#endif
}



inline void initPWM4(uint8_t freq) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer0B / PD5 (pin 5)
    TCCR0A |= _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on oc0a
    //TCCR0B = freq & 0x7;
    OCR0B = 0;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    // on arduino mega, pin 5 is now PE3 (OC3A)
    TCCR3A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc3a
    TCCR3B = (freq & 0x7) | _BV(WGM12);
    //TCCR4B = 1 | _BV(WGM12);
    OCR3A = 0;
#endif
    pinMode(5, OUTPUT);
}

inline void setPWM4(uint8_t s) {
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    // use PWM from timer0A on PB3 (Arduino pin #6)
    OCR0B = s;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    // on arduino mega, pin 6 is now PH3 (OC4A)
    OCR3A = s;
#endif
}

AF_DCMotor::AF_DCMotor(uint8_t num, uint8_t freq) {
  motornum = num;
  pwmfreq = freq;

  MC.enable();

  switch (num) {
  case 1:
    latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B); // set both motor pins to 0
    MC.latch_tx();
    initPWM1(freq);
    break;
  case 2:
    latch_state &= ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // set both motor pins to 0
    MC.latch_tx();
    initPWM2(freq);
    break;
  case 3:
    latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B); // set both motor pins to 0
    MC.latch_tx();
    initPWM3(freq);
    break;
  case 4:
    latch_state &= ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // set both motor pins to 0
    MC.latch_tx();
    initPWM4(freq);
    break;
  }
}

void AF_DCMotor::run(uint8_t cmd) {
  uint8_t a, b;
  switch (motornum) {
  case 1:
    a = MOTOR1_A; b = MOTOR1_B; break;
  case 2:
    a = MOTOR2_A; b = MOTOR2_B; break;
  case 3:
    a = MOTOR3_A; b = MOTOR3_B; break;
  case 4:
    a = MOTOR4_A; b = MOTOR4_B; break;
  default:
    return;
  }
  
  switch (cmd) {
  case FORWARD:
    latch_state |= _BV(a);
    latch_state &= ~_BV(b); 
    MC.latch_tx();
    break;
  case BACKWARD:
    latch_state &= ~_BV(a);
    latch_state |= _BV(b); 
    MC.latch_tx();
    break;
  case RELEASE:
    latch_state &= ~_BV(a);
    latch_state &= ~_BV(b); 
    MC.latch_tx();
    break;
  }
}

void AF_DCMotor::setSpeed(uint8_t speed) {
  switch (motornum) {
  case 1:
    setPWM1(speed); break;
  case 2:
    setPWM2(speed); break;
  case 3:
    setPWM3(speed); break;
  case 4:
    setPWM4(speed); break;
  }
}

/******************************************
               STEPPERS
******************************************/

AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) {
  MC.enable();

  revsteps = steps;
  steppernum = num;

  if (steppernum == 1) {
    latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
      ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
    MC.latch_tx();
    
    // enable both H bridges
    pinMode(11, OUTPUT);
    pinMode(3, OUTPUT);
    digitalWrite(11, HIGH);
    digitalWrite(3, HIGH);

#ifdef MICROSTEPPING
    // use PWM for microstepping support
    initPWM1(MOTOR12_64KHZ);
    initPWM2(MOTOR12_64KHZ);
    setPWM1(255);
    setPWM2(255);
#endif

  } else if (steppernum == 2) {
    latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
      ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
    MC.latch_tx();

    // enable both H bridges
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);

#ifdef MICROSTEPPING    
    // use PWM for microstepping support
    // use PWM for microstepping support
    initPWM3(1);
    initPWM4(1);
    setPWM3(255);
    setPWM4(255);
#endif
  }
}

void AF_Stepper::setSpeed(uint16_t rpm) {
  usperstep = 60000000 / (revsteps * rpm);
  steppingcounter = 0;
}

void AF_Stepper::release(void) {
  if (steppernum == 1) {
    latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
      ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
    MC.latch_tx();
  } else if (steppernum == 2) {
    latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
      ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
    MC.latch_tx();
  }
}

void AF_Stepper::step(uint16_t steps, uint8_t dir,  uint8_t style) {
  uint32_t uspers = usperstep;
  uint8_t ret = 0;

  if (style == INTERLEAVE) {
    uspers /= 2;
  }
#ifdef MICROSTEPPING
 else if (style == MICROSTEP) {
    uspers /= MICROSTEPS;
    steps *= MICROSTEPS;
#ifdef MOTORDEBUG
    Serial.print("steps = "); Serial.println(steps, DEC);
#endif
  }
#endif

  while (steps--) {
    ret = onestep(dir, style);
    delay(uspers/1000); // in ms
    steppingcounter += (uspers % 1000);
    if (steppingcounter >= 1000) {
      delay(1);
      steppingcounter -= 1000;
    }
  }
#ifdef MICROSTEPPING
  if (style == MICROSTEP) {
    //Serial.print("last ret = "); Serial.println(ret, DEC);
    while ((ret != 0) && (ret != MICROSTEPS)) {
      ret = onestep(dir, style);
      delay(uspers/1000); // in ms
      steppingcounter += (uspers % 1000);
      if (steppingcounter >= 1000) {
	delay(1);
	steppingcounter -= 1000;
      } 
    }
  }
#endif

}

uint8_t AF_Stepper::onestep(uint8_t dir, uint8_t style) {
  uint8_t a, b, c, d;
  uint8_t step;
  uint8_t mstep = 0;
#ifdef MICROSTEPPING
  uint8_t ocrb, ocra;
#endif
  if (steppernum == 1) {
    a = _BV(MOTOR1_A);
    b = _BV(MOTOR2_A);
    c = _BV(MOTOR1_B);
    d = _BV(MOTOR2_B);

#ifdef MICROSTEPPING
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    ocra = OCR2A;
    ocrb = OCR2B;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    ocra = OCR1A;
    ocrb = OCR3C;
#endif

    if (style == MICROSTEP) {
      //TCCR2B = _BV(CS21);
    }
#endif
  } else if (steppernum == 2) {
    a = _BV(MOTOR3_A);
    b = _BV(MOTOR4_A);
    c = _BV(MOTOR3_B);
    d = _BV(MOTOR4_B);

#ifdef MICROSTEPPING
#if defined(__AVR_ATmega8__) || \
    defined(__AVR_ATmega48__) || \
    defined(__AVR_ATmega88__) || \
    defined(__AVR_ATmega168__) || \
    defined(__AVR_ATmega328P__)
    ocra = OCR0A;
    ocrb = OCR0B;
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 
    ocra = OCR4A;
    ocrb = OCR3A;
#endif

    if (style == MICROSTEP) {
      //TCCR0B = _BV(CS00);
    }   
#endif

  } else {
    return 0;
  }

#ifdef MOTORDEBUG
  Serial.print("a = "); Serial.print(ocra, DEC);
  Serial.print(" b = "); Serial.print(ocrb, DEC);
  Serial.print("\t");
#endif

  // OK next determine what step we are at 
  if ((latch_state & (a | b)) == (a | b))
    step = 1 * MICROSTEPS; 
  else if ((latch_state & (b | c)) == (b | c))
    step = 3 * MICROSTEPS; 
  else if ((latch_state & (c | d)) == (c | d))
    step = 5 * MICROSTEPS;
  else if ((latch_state & (d | a)) == (d | a))
    step = 7 * MICROSTEPS;
  else if (latch_state & a)
    step = 0;
  else if (latch_state & b)
    step = 2 * MICROSTEPS;
  else if (latch_state & c)
    step = 4 * MICROSTEPS;
  else
    step = 6 * MICROSTEPS;

  //Serial.print("step "); Serial.print(step, DEC); Serial.print("\t");
  // next determine what sort of stepping procedure we're up to
  if (style == SINGLE) {
    if ((step/MICROSTEPS) % 2) { // we're at an odd step, weird
      if (dir == FORWARD)
	step = (step + MICROSTEPS) % (8*MICROSTEPS);
      else
	step = (step + 7*MICROSTEPS) % (8*MICROSTEPS);
    } else {           // go to the next even step
      if (dir == FORWARD)
	step = (step + 2*MICROSTEPS) % (8*MICROSTEPS);
      else
	step = (step + 6*MICROSTEPS) % (8*MICROSTEPS);  

    }
#ifdef MICROSTEPPING
    ocra = 255;
    ocrb = 255;
#endif

  } else if (style == DOUBLE) {
    if (! (step/MICROSTEPS % 2)) { // we're at an even step, weird
      if (dir == FORWARD)
	step = (step + MICROSTEPS) % (8*MICROSTEPS);
      else
	step = (step + 7*MICROSTEPS) % (8*MICROSTEPS);
    } else {           // go to the next odd step
      if (dir == FORWARD)
	step = (step + 2*MICROSTEPS) % (8*MICROSTEPS);
      else
	step = (step + 6*MICROSTEPS) % (8*MICROSTEPS);
    }
#ifdef MICROSTEPPING
    ocra = 255;
    ocrb = 255;
#endif
  } else if (style == INTERLEAVE) {
     if (dir == FORWARD)
       step = (step + 1*MICROSTEPS) % (8*MICROSTEPS);
     else
       step = (step + 7*MICROSTEPS) % (8*MICROSTEPS);
#ifdef MICROSTEPPING
    ocra = 255;
    ocrb = 255;
#endif
  } 
#ifdef MICROSTEPPING
  else if (style == MICROSTEP) {

    //Serial.print("Step #"); Serial.print(step/MICROSTEPS, DEC); Serial.print("\t");
    if (dir == FORWARD) {

      // if at even step, make sure its 'odd'
      if (! (step/MICROSTEPS) % 2) {
	step = (step + MICROSTEPS) % (8*MICROSTEPS);
      }

      // fix hiccups from changing direction
      if (((ocra == 255) && ((step/MICROSTEPS)%4 == 3)) ||
	  ((ocrb == 255) && ((step/MICROSTEPS)%4 == 1))) {
	step += 2*MICROSTEPS;
	step %= 8*MICROSTEPS;
      }

      if ((step == MICROSTEPS) || (step == 5*MICROSTEPS)) {
	// get the current microstep
	if (ocrb == 255)
	  mstep = MICROSTEPS;
	else
	  mstep = ocrb / (256UL / MICROSTEPS);
#ifdef MOTORDEBUG
	Serial.print("uStep = "); Serial.print(mstep, DEC);
#endif
	// ok now go to next step
	mstep++;
	mstep %= (MICROSTEPS+1);
	if (mstep == MICROSTEPS)
	  ocrb = 255;
	else 
	  ocrb = mstep * (256UL / MICROSTEPS);
	ocra = 255 - ocrb;
#ifdef MOTORDEBUG
	Serial.print(" -> "); Serial.println(mstep, DEC);
#endif
	if (mstep == MICROSTEPS)
	  step = (step + 2*MICROSTEPS) % (8*MICROSTEPS);
      } else {
	// get the current microstep
	if (ocrb == 255)
	  mstep = MICROSTEPS;
	else
	  mstep = ocrb / (256UL / MICROSTEPS);
#ifdef MOTORDEBUG
	Serial.print("uStep = "); Serial.print(mstep, DEC);
#endif
	// ok now go to next step
	mstep += MICROSTEPS;
	mstep %= (MICROSTEPS+1);
	if (mstep == MICROSTEPS)
	  ocrb = 255;
	else 
	  ocrb = mstep * (256UL / MICROSTEPS);
	ocra = 255 - ocrb;
#ifdef MOTORDEBUG
	Serial.print(" +> "); Serial.println(mstep, DEC);
#endif
	if (mstep == 0)
	  step = (step + 2*MICROSTEPS) % (8*MICROSTEPS);
      }
    } else {

      // fix hiccups from changing direction
      if (((ocra == 255) && ((step/MICROSTEPS)%4 == 1)) ||
	  ((ocrb == 255) && ((step/MICROSTEPS)%4 == 3))) {
	step = (step + 6*MICROSTEPS);
	step %= (8*MICROSTEPS);
      }

      // if at even step, make sure its 'odd'
      if (! (step/MICROSTEPS % 2)) {
	step = (step + 7*MICROSTEPS) % (8*MICROSTEPS);
      }
      if ((step == MICROSTEPS) || (step == 5*MICROSTEPS)) {
	// get the current microstep
	if (ocrb == 255)
	  mstep = MICROSTEPS;
	else
	  mstep = ocrb / (256UL / MICROSTEPS);
#ifdef MOTORDEBUG
	Serial.print(" uStep = "); Serial.print(mstep, DEC);
#endif
	// ok now go to next step
	mstep += MICROSTEPS;
	mstep %= (MICROSTEPS+1);
	if (mstep == MICROSTEPS)
	  ocrb = 255;
	else
	  ocrb = mstep * (256UL / MICROSTEPS);
	ocra = 255 - ocrb;
#ifdef MOTORDEBUG
	Serial.print(" !> "); Serial.println(mstep, DEC);
#endif
	if (mstep == 0)
	  step = (step + 6*MICROSTEPS) % (8*MICROSTEPS);
      } else {
	// get the current microstep
	if (ocrb == 255)
	  mstep = MICROSTEPS;
	else
	  mstep = ocrb / (256UL / MICROSTEPS);
#ifdef MOTORDEBUG
	Serial.print("uStep = "); Serial.print(mstep, DEC);
#endif
	// ok now go to next step
	mstep++;
	mstep %= (MICROSTEPS + 1);
	if (mstep == MICROSTEPS)
	  ocrb = 255;
	else 
	  ocrb = mstep * (256UL / MICROSTEPS);
	ocra = 255 - ocrb;
#ifdef MOTORDEBUG
	Serial.print(" *> "); Serial.println(mstep, DEC);
#endif
	if (mstep == MICROSTEPS)
	  step = (step + 6*MICROSTEPS) % (8*MICROSTEPS);
      }
    }
  }


  //Serial.print(" -> step = "); Serial.print(step/MICROSTEPS, DEC); Serial.print("\t");

  if (steppernum == 1) {
    setPWM1(ocra);
     setPWM2(ocrb);
  } else if (steppernum == 2) {
    setPWM3(ocra);
    setPWM4(ocrb);
  }

#endif  // microstepping

  // release all
  latch_state &= ~a & ~b & ~c & ~d; // all motor pins to 0

  //Serial.println(step, DEC);

  switch (step/MICROSTEPS) {
  case 0:
    latch_state |= a; // energize coil 1 only
    break;
  case 1:
    latch_state |= a | b; // energize coil 1+2
    break;
  case 2:
    latch_state |= b; // energize coil 2 only
    break;
  case 3:
    latch_state |= b | c; // energize coil 2+3
    break;
  case 4:
    latch_state |= c; // energize coil 3 only
    break; 
  case 5:
    latch_state |= c | d; // energize coil 3+4
    break;
  case 6:
    latch_state |= d; // energize coil 4 only
    break;
  case 7:
    latch_state |= d | a; // energize coil 1+4
    break;
  }
  MC.latch_tx();
  return mstep;
}

 

elranon
Offline
Зарегистрирован: 28.05.2012

Я проверил библиотеку, там есть такие строки:

#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

но тем не менее я переписал ее содержание, все разобрал и заново подключил, все 4 мотора, загрузил вот этот скетч

#include <AFMotor.h>

AF_DCMotor motor1(1); // create motor #2, 64KHz pwm
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  
  motor1.setSpeed(200);     // set the speed to 200/255
  motor2.setSpeed(200);     // set the speed to 200/255
  motor3.setSpeed(200);     // set the speed to 200/255
  motor4.setSpeed(200);     // set the speed to 200/255
}

void loop() {
  Serial.print("tick");
  
  motor1.run(FORWARD);      // turn it on going forward
  delay(10000);

  Serial.print("tock");
  motor1.run(BACKWARD);     // the other way
  delay(10000);
  
  Serial.print("tack");
  motor1.run(RELEASE);      // stopped
  delay(10000);
  
  motor2.run(FORWARD);      // turn it on going forward
  delay(10000);

  Serial.print("tock");
  motor2.run(BACKWARD);     // the other way
  delay(10000);
  
  Serial.print("tack");
  motor2.run(RELEASE);      // stopped
  delay(10000);

  motor3.run(FORWARD);      // turn it on going forward
  delay(10000);

  Serial.print("tock");
  motor3.run(BACKWARD);     // the other way
  delay(10000);
  
  Serial.print("tack");
  motor3.run(RELEASE);      // stopped
  delay(10000);

  motor4.run(FORWARD);      // turn it on going forward
  delay(10000);

  Serial.print("tock");
  motor4.run(BACKWARD);     // the other way
  delay(10000);
  
  Serial.print("tack");
  motor4.run(RELEASE);      // stopped
  delay(10000);

}

И результат вообще сбил меня с толку.

Я подключил все 4 мотора, и вся схема вела себя странно... М1 и М2 крутились, правда не 10 секунд а 1 секунд, и при этом только в одну сторону, то есть не было реверса... М3 вообще не крутился, М4 крутился 10секунд, и тоже без реверса.

Я снял микросхемы L293D с шилда, и напрямую проверил их, согластно распиновке. Если на инейбл и инпут подавать сигнал через Ардуиновские контакты 3,4,9 - то реакции никакой. Если просто подключить инейбл и инпут 1 к 5V а к инпут 2 землю с ардуины - то мотор крутится. Проверил так 2 микросхемы, в каждой оба канала, все ок.

Вобщем запутался я( Не понимаю, что это. Может ардуина как то не так работает, или контакты выгорели какие то? Как бы проверить их?

При прозвонке через пины ардуины пользовался вот этим кодом:

const int motor1Pin = 3; // H-bridge leg 1 (pin 2, 1A)
const int motor2Pin = 4; // H-bridge leg 2 (pin 7, 2A)
const int enablePin = 9; // H-bridge enable pin
void setup()
{ // set all the other pins you're using as outputs:
pinMode(motor1Pin, OUTPUT);
pinMode(motor2Pin, OUTPUT);
pinMode(enablePin, OUTPUT); // set enablePin high so that motor can turn on:
digitalWrite(enablePin, HIGH);
}

void loop()
{ // Вращаем мотор в одну сторону
digitalWrite(motor1Pin, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor2Pin, HIGH); // set leg 2 of the H-bridge high delay(1000); // А через секунду в другую digitalWrite(motor1Pin, HIGH); // set leg 1 of the H-bridge high
digitalWrite(motor2Pin, LOW); // set leg 2 of the H-bridge low delay(1000);
// А теперь всё сначала
}

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Если на инейбл и инпут подавать сигнал через Ардуиновские контакты 3,4,9 - то реакции никакой.<<

Питание МС тоже нужно подключить. При том там два питания - питание моторов и логики.

>>Если просто подключить инейбл и инпут 1 к 5V а к инпут 2 землю с ардуины - то мотор крутится.<<

Скорее всего это l293dne. Надежней будет поджимать инпуты к земле резистором 10К.

elranon
Offline
Зарегистрирован: 28.05.2012

Вобщем я постарался снова прозвонить микросхему.

1. подключал инейбл и инпут через пины ардуины, подавал High и Low соответственно. Результат: моторы крутятся, но медленно, очень. вот фото

2. Подключал напрямую инейбл и инпут к +5В ардуины и земле. Результат: моторы крутятся шустро.

Что это может быть?

На микросхеме написано именно L293D

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Вы питание на моторы и логику даете ?

 >>Подключал напрямую инейбл и инпут к +5В ардуины и земле<<

Не понял. То что вы описали называтся КЗ.

Что вы подключаете к земле ?

 

Для начала прицепите инабл к +5в , инпуты к пинам МК. Инпут1 - HIGH, инпут2 -LOW  или наоборот. Подключите питание логики 

к +5в, питание моторов к +Vаккум.

 

elranon
Offline
Зарегистрирован: 28.05.2012

>> Вы питание на моторы и логику даете ?

Конечно. Схема питания:

Arduino Mega 2560 - крона

Логика L293D - 5В, они идут от Ардуины на 16 пин микросхемы(Vss)

Моторы - батарейный блок на 5хАА батареек, подключается красным проводом к Vs микросхемы(8 пин), а черным к GND.

>> Не понял. То что вы описали называтся КЗ.

>> Что вы подключаете к земле ?

Не очень подробно описал. Я подключаю один Инейбл и Инпут 1 к 5В, а Инпут 2 к земле. Собственно так как и должно быть, чтобы мотор работал.

И он крутится, быстро и хорошо.

А если я подключаю так:

Инейбл - 9 пин - ставлю HIGH

Инпут 1 - пин 4 - Ставлю HIGH

Инпут 2 - пин 3 - ставлю LOW

мотор крутиться, но оооооочень медленно, будто не хватает ему напряжения. Но почему так, непонятно. Ведь питание подключено правильно - питание моторов отдельно, 5 батареек АА, а питание логики от Ардуино, 5В

Завтра попробую так как вы сказали- Инейбл к 5В, а инпуты к пинам МК и отпишу о результате

elranon
Offline
Зарегистрирован: 28.05.2012

Вообще просто интерестно, как влияет подключение МК на питание моторов? Оно же должно идти от отельного источника питания через L293D, и с МК по идее не связано.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Завтра попробую так как вы сказали- Инейбл к 5В, а инпуты к пинам МК и отпишу о результате<<

Разницы нет. +5в будет и там и там.

>>Оно же должно идти от отельного источника питания через L293D, и с МК по идее не связано.<<

А может собака зарыта именно здесь ?

Может вы земли питаний , МК и драйвера не соеденили ? 

elranon
Offline
Зарегистрирован: 28.05.2012

Вы будете смеяться...

Сегодня приобрел Arduino Uno, поставил шилд, подключил мотор, и все заработало как надо...

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

elranon
Offline
Зарегистрирован: 28.05.2012

Я понимаю что может со своей проблеммой всем тут уже надоел, но снова такая же проблема повторяется, но на новой arduino uno...  значит косяк не в ней. Я заметил, что порт м1 работает. На нем все как надо. На осальных портах для подключения мотора те же симптомы: пытается покрутиться, звук издает... что это всетки за проблема?

 

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Купите лучше нормальный драйвер. Пусть и не подходящий по пинам дуины (распаяете проводами или вытравите переходник).

Я пользуюсь вот такими http://robototehnika.ru/e-store/catalog/203/880/

 

elranon
Offline
Зарегистрирован: 28.05.2012

nestandart пишет:

Купите лучше нормальный драйвер. Пусть и не подходящий по пинам дуины (распаяете проводами или вытравите переходник).

Я пользуюсь вот такими http://robototehnika.ru/e-store/catalog/203/880/

 

Спасибо! Заказал себе такой

Но пока он едет, всетки хотелось бы попробовать понять, что не так с этим шилдом. Что мы имеем:

1. Ардуино - рабочая, потому что у меня их две, одна новая, и на обоих одинаковые симптомы

2. Микросхемы L293D рабочие, я проверил каждую, каждый канал, все ок.

Работает только на порту М2, и все(в прошлом посте написал что работает на порте М1, опечатка это).

На всех остальных портах М1, М3, М4 не работает, хотя в коде я менял значения, подставляя 1,3,4, все равно.

В чем может быть проблема? Может что-то, связанное с PWM? Что еще я могу проверить, чтобы понять где косяк? Хочеться очень разобраться в проблеме.

elranon
Offline
Зарегистрирован: 28.05.2012

TB6612FNG Dual Motor Driver Carrier а можно к такому драйверу подключить 4 мотора, паралельно?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Параллельно ? Хоть десять, если ток не превышают. А зачем ?

Или вы опять не правильно выразились ? 

Если вам интересно может ли этот драйвер полноценно рулить четырьмя моторами одновременно , то нет. Не может.

Это классический двухканальный драйвер.

source
source аватар
Offline
Зарегистрирован: 20.05.2012
VilenSIPKDM
Offline
Зарегистрирован: 19.09.2018

Здравствуйте! Вопрос по питанию. На Motor Shield приходит 7 В, а на разъемах M1-M4 такое ощущение, что нет напряжения - на тестере (самодельный, 2 провода и 3-х позиционный дисплей) еле-еле мерцают нули. Двигатели постоянного тока, соответственно, не работают - только какое-то щелканье на тестовом примере из библиотеки AFMotor. Куда копать? У Arduino Mega и Motor Shield питание раздельное, джампер снят, конечно же.

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

Ну, для начала - измерить напряжение на моторах.

VilenSIPKDM
Offline
Зарегистрирован: 19.09.2018

Ничего нет:(

Если просто подаю питание с батареек - двигатели крутятся! Серво так же - только небольшие постукивания, и больше ничего. А напрямую от Arduino серво Tiwer Pro MG 966 крутится.

Zontgom
Offline
Зарегистрирован: 08.09.2018

Серво питаются от ардуино 5в. Они и так напрямую работают, нет соединения с pwr.