Непонятки в управлении ШД

Rom327
Offline
Зарегистрирован: 25.04.2015

Уважаемые Гуру! Помогите разобраться с программой. У меня MEGA 2560, остальное все как на картинках в первоисточнике. Библиотеку скачал. Первоисточник: http://forum.hobbycomponents.com/viewtopic.php?f=76&t=1371 Запустил, двигатель вращается в обе стороны, скорость меняется в зависимости от положения ротора резистора. Все вроде правильно, но при вращении в одну сторону частота "Step-Clk" 993Гц, а в другую 763Гц. Это первое, а второе как увеличить эту самую частоту? Заранее благодарен.

/* Include the library */
#include "HCMotor.h"

/* Pins used to drive the motors */
#define DIR_PIN 8 //Connect to drive modules 'direction' input.
#define CLK_PIN 9 //Connect to drive modules 'step' or 'CLK' input.

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0

/* Set a dead area at the centre of the pot where it crosses from forward to reverse */
#define DEADZONE 20 

/* The analogue pin will return values between 0 and 1024 so divide this up between 
   forward and reverse */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1024


/* Create an instance of the library */
HCMotor HCMotor;



void setup() 
{
  //Serial.begin(9600);
  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the 
     motor number, the second is the motor type, and the third and forth are the 
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, CLK_PIN, DIR_PIN);

  /* Set the number of steps to continuous so the the motor is always turning whilst 
     not int he dead zone*/
  HCMotor.Steps(0,CONTINUOUS);
}


void loop() 
{
  int Speed, Pot;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot = analogRead(POT_PIN);

  /* Is the pot in the reverse position ? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 10, 1024);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 1024, 10);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(0, Speed);

}

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

А как вы измеряли эту частоту?

Судя по скетчу - скорость должна быть одна и та-же. Какое сопротивление у резистора?

Rom327
Offline
Зарегистрирован: 25.04.2015

Спасибо!

Сопротивление 10К, пробовал менять местами + и - изменений нет. А измерял осциллографом со встроенным мультиметром на входах платы CLK+ и CLK-. Сам не пойму в чем дело, вроде все правильно и скорость должна быть равной... А самое главное как ускорить работу моторов: если на TB6560 выставить шаг 1/16, то совсем медленно получается, хотя сама микросхема должна держать до 15КГц.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

В режиме бреда попробуйте

#define DEADZONE 0

 

Rom327
Offline
Зарегистрирован: 25.04.2015

Так это "мертвая зона", при которой мотор должен стоять!

Rom327
Offline
Зарегистрирован: 25.04.2015

И еще вопрос к знающим людям: как переписать скетч, чтобы 3-мя резисторами управлять 3-мя ШД? С подключением, я надеюсь, трудностей не возникнет...

Rom327
Offline
Зарегистрирован: 25.04.2015
 HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

Изменил часть кода и все заработало, хотя непонятно... Теперь частота около 5КГц в любую сторону. Как подключить в программе еще 2 мотора?

 

Rom327
Offline
Зарегистрирован: 25.04.2015
/* Include the library */
#include "HCMotor.h"

/* Pins used to drive the motors */
#define DIR_PIN 8 //Connect to drive modules1 'direction' input.
#define CLK_PIN 9 //Connect to drive modules1 'step' or 'CLK' input.
#define DIR_PIN1 10 //Connect to drive modules2 'direction' input.
#define CLK_PIN1 11 //Connect to drive modules2 'step' or 'CLK' input.
#define DIR_PIN2 12 //Connect to drive modules3 'direction' input.
#define CLK_PIN2 13 //Connect to drive modules3 'step' or 'CLK' input.

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0
#define POT_PIN1 A1
#define POT_PIN2 A2

/* Set a dead area at the centre of the pot where it crosses from forward to reverse */
#define DEADZONE 20 

/* The analogue pin will return values between 0 and 1024 so divide this up between 
   forward and reverse */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1024

/* Create an instance of the library */
HCMotor HCMotor;

void setup() 
{
  //Serial.begin(9600);
  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the 
     motor number, the second is the motor type, and the third and forth are the 
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, CLK_PIN, DIR_PIN);
  HCMotor.attach(1, STEPPER, CLK_PIN1, DIR_PIN1);
  HCMotor.attach(2, STEPPER, CLK_PIN2, DIR_PIN2);
  
  /* Set the number of steps to continuous so the the motor is always turning whilst 
     not int he dead zone*/
  HCMotor.Steps(0,CONTINUOUS);
  HCMotor.Steps(1,CONTINUOUS);
  HCMotor.Steps(2,CONTINUOUS);
}

void loop() 
{
  int Speed, Pot, Pot1, Pot2;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot = analogRead(POT_PIN);
  Pot1 = analogRead(POT_PIN1);
  Pot2 = analogRead(POT_PIN2);

  /* Is the pot in the reverse position ? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }
  /* Is the pot in the reverse position ? */
  if (Pot1 >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(1, REVERSE);
    Speed = map(Pot1, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot1 >= POT_FWD_MIN && Pot1 <= POT_FWD_MAX)
  {
    HCMotor.Direction(1, FORWARD);
    Speed = map(Pot1, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }
  /* Is the pot in the reverse position ? */
  if (Pot2 >= POT_REV_MIN && Pot2 <= POT_REV_MAX)
  {
    HCMotor.Direction(2, REVERSE);
    Speed = map(Pot2, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot2 >= POT_FWD_MIN && Pot2 <= POT_FWD_MAX)
  {
    HCMotor.Direction(2, FORWARD);
    Speed = map(Pot2, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(0, Speed);
  HCMotor.DutyCycle(1, Speed);
  HCMotor.DutyCycle(2, Speed);
}

Здравствуйте! Снова нужно помощь... Переписал скетч на 3 мотора и 3 потенциометра. Собрал схему и выяснилось следующее: моторы работают параллельно от любого из потенциометров. То есть один потенциометр управляется сразу 3-мя моторами. Если подключить второй потенциометр, то он тоже будет упралять тремя моторами и конфликтовать с первым. Как назначить на один потенциометр - один мотор? Спасибо!

 

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Вам нужно несколько экземпляров класса

HCMotor

Странно, что все три работают, а не только последний объявленный. Хотя...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ваша строка 28 заводит переменную типа "мотор". И эта переменная у Вас одна - значит и мотор логически один! Перепишите её в таком виде:

HCMotor HCMotor1, HCMotor2, HCMotor3;

и везде в программе. где речь идёт о первом моторе, используйте HCMotor1, где о втором - HCMotor2, и т.д.

Только аккуратно везде всё поменяйте.

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

ну три мотора, а speed осталась одна.

заведи speed1. speed2, speed3

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vvadim пишет:

ну три мотора, а speed осталась одна.

заведи speed1. speed2, speed3

Тоже верно.

Rom327
Offline
Зарегистрирован: 25.04.2015
/* Include the library */
#include "HCMotor.h"

/* Pins used to drive the motors */
#define DIR_PIN 8 //Connect to drive modules1 'direction' input.
#define CLK_PIN 9 //Connect to drive modules1 'step' or 'CLK' input.
#define DIR_PIN1 10 //Connect to drive modules2 'direction' input.
#define CLK_PIN1 11 //Connect to drive modules2 'step' or 'CLK' input.
#define DIR_PIN2 12 //Connect to drive modules3 'direction' input.
#define CLK_PIN2 13 //Connect to drive modules3 'step' or 'CLK' input.

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0
#define POT_PIN1 A1
#define POT_PIN2 A2

/* Set a dead area at the centre of the pot where it crosses from forward to reverse */
#define DEADZONE 20 

/* The analogue pin will return values between 0 and 1024 so divide this up between 
   forward and reverse */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1024

/* Create an instance of the library */
HCMotor HCMotor;

void setup() 
{
  //Serial.begin(9600);
  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the 
     motor number, the second is the motor type, and the third and forth are the 
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, CLK_PIN, DIR_PIN);
  HCMotor.attach(1, STEPPER, CLK_PIN1, DIR_PIN1);
  HCMotor.attach(2, STEPPER, CLK_PIN2, DIR_PIN2);
  
  /* Set the number of steps to continuous so the the motor is always turning whilst 
     not int he dead zone*/
  HCMotor.Steps(0,CONTINUOUS);
  HCMotor.Steps(1,CONTINUOUS);
  HCMotor.Steps(2,CONTINUOUS);
}

void loop() 
{
        int Speed, Pot;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot = analogRead(POT_PIN);

  /* Is the pot in the reverse position ? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }
  /* Is the pot in the reverse position ? */
  
  
         int Speed1, Pot1;

         /* Read the analogue pin to determine the position of the pot. */ 
  Pot1 = analogRead(POT_PIN1);

  /* Is the pot in the reverse position ? */
  if (Pot1 >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed1 = map(Pot1, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot1 >= POT_FWD_MIN && Pot1 <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot1, POT_FWD_MIN, POT_FWD_MAX, 10, 1);
  /* Is the pot in the dead zone ? */
  }
  /* Is the pot in the reverse position ? */
  
  
      int Speed2, Pot2;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot2 = analogRead(POT_PIN2);

  /* Is the pot in the reverse position ? */
  if (Pot2 >= POT_REV_MIN && Pot2 <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed2 = map(Pot2, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot2 >= POT_FWD_MIN && Pot2 <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed2 = map(Pot2, POT_FWD_MIN, POT_FWD_MAX, 10, 1);
    
  /* Is the pot in the dead zone ? */
  }else
  {
    Speed = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(0, Speed);
  HCMotor.DutyCycle(1, Speed);
  HCMotor.DutyCycle(2, Speed);
  

}

Исправил, но еще не проверял.. Двигаюсь в правильном направлении?

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

  HCMotor.DutyCycle(0, Speed1);
  HCMotor.DutyCycle(1, Speed2);
  HCMotor.DutyCycle(2, Speed3);
vvadim
Offline
Зарегистрирован: 23.05.2012
else
  {
    Speed = 0;
  }

else
  {
    Speed1 = 0;
  }

else
  {
    Speed2 = 0;
  }

 

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

vvadim пишет:

else
  {
    Speed = 0;
  }

else
  {
    Speed1 = 0;
  }

else
  {
    Speed2 = 0;
  }

 

 

и подкорректируйте все спиды, у вас с ними полная каша стр 83 и 89

Rom327
Offline
Зарегистрирован: 25.04.2015

Vvadim, при вашем написании кода ругается: "else" without previous "if"

Rom327
Offline
Зарегистрирован: 25.04.2015

/* Include the library */
#include "HCMotor.h"

/* Pins used to drive the motors */
#define DIR_PIN 8 //Connect to drive modules1 'direction' input.
#define CLK_PIN 9 //Connect to drive modules1 'step' or 'CLK' input.
#define DIR_PIN1 10 //Connect to drive modules2 'direction' input.
#define CLK_PIN1 11 //Connect to drive modules2 'step' or 'CLK' input.
#define DIR_PIN2 12 //Connect to drive modules3 'direction' input.
#define CLK_PIN2 13 //Connect to drive modules3 'step' or 'CLK' input.

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0
#define POT_PIN1 A1
#define POT_PIN2 A2

/* Set a dead area at the centre of the pot where it crosses from forward to reverse */
#define DEADZONE 20 

/* The analogue pin will return values between 0 and 1024 so divide this up between 
   forward and reverse */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1024


/* Create an instance of the library */
HCMotor HCMotor;

void setup() 
{
  //Serial.begin(9600);
  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the 
     motor number, the second is the motor type, and the third and forth are the 
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, CLK_PIN, DIR_PIN);
  HCMotor.attach(1, STEPPER, CLK_PIN1, DIR_PIN1);
  HCMotor.attach(2, STEPPER, CLK_PIN2, DIR_PIN2);
  
  /* Set the number of steps to continuous so the the motor is always turning whilst 
     not int he dead zone*/
  HCMotor.Steps(0,CONTINUOUS);
  HCMotor.Steps(1,CONTINUOUS);
  HCMotor.Steps(2,CONTINUOUS);
}

void loop() 
{
  int Speed, Pot;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot = analogRead(POT_PIN);

  /* Is the pot in the reverse position ? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(0, Speed);
  

  int Speed1, Pot1;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot1 = analogRead(POT_PIN1);

  /* Is the pot in the reverse position ? */
  if (Pot1 >= POT_REV_MIN && Pot1 <= POT_REV_MAX)
  {
    HCMotor.Direction(1, REVERSE);
    Speed1 = map(Pot1, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot1 >= POT_FWD_MIN && Pot1 <= POT_FWD_MAX)
  {
    HCMotor.Direction(1, FORWARD);
    Speed1 = map(Pot1, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed1 = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(1, Speed1);


  int Speed2, Pot2;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot2 = analogRead(POT_PIN2);

  /* Is the pot in the reverse position ? */
  if (Pot2 >= POT_REV_MIN && Pot2 <= POT_REV_MAX)
  {
    HCMotor.Direction(2, REVERSE);
    Speed2 = map(Pot2, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot2 >= POT_FWD_MIN && Pot2 <= POT_FWD_MAX)
  {
    HCMotor.Direction(2, FORWARD);
    Speed2 = map(Pot2, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed2 = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(2, Speed2);

}

Все спасибо за помощь! Все заработало! Кому интересно выкладываю скетч на 3 мотора (есть еще на 2).

Теперь следующая задача: Надо, чтобы ШД следил за резистором: повернули резистор на х градусов и мотор провернулся на Х градусов.

И еще, надо запитать с платы Ардуино 3 электромагнита от 3 кнопок.

 

Rom327
Offline
Зарегистрирован: 25.04.2015

Еще раз всем спасибо за помощь!

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

я как пример для размышлений привёл

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

с этой не знаю, я с ней не ковырялся.
в acellstepper такой пример есть

Rom327
Offline
Зарегистрирован: 25.04.2015

Спасибо! Многие ссылаются на примеры из acellstepper. Не могли бы растолковать что и почем? Я скачал папку, там куча примеров, но нет ни схем соединений ни описаний. Как быть?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Неужели ни одной схемы подключения нет?

https://www.pjrc.com/teensy/td_libs_AccelStepper.html

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

в accelstepper пример Proportional Control

там вроде всё понятно

Rom327
Offline
Зарегистрирован: 25.04.2015

vvadim пишет:

в accelstepper пример Proportional Control

там вроде всё понятно

Может вам и понятно, а я 3-й день за рулем...

1. В примере испоьзуется 4-х проводное подключение ШД, у меня драйвер ТВ6560 и надо подключать 2 провода: напраление и шаг. Как исправить?

2. Как дополнить мой, уже существующий скетч на 3 мотора новым, использующим эту библиотеку и дописать скетч?

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

AccelStepper stepper(1, 9, 8);

9 - step,   8 - dir

изучиете библиотеку, там всё расписано по полочкам

вы написали код для двух моторов и он у вас работает. по аналогии добавьте третий мотор

Rom327
Offline
Зарегистрирован: 25.04.2015
#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(1,6,7);
AccelStepper stepper1(1,8,9);
AccelStepper stepper2(1,10,11);
// This defines the analog input pin for reading the control voltage
// Tested with a 10k linear pot between 5v and GND
#define ANALOG_IN A0
#define ANALOG_IN1 A1
#define ANALOG_IN2 A2
void setup()
{  
  stepper.setMaxSpeed(1000);
  stepper1.setMaxSpeed(1000);
  stepper2.setMaxSpeed(1000);
}

void loop()
{
    
  // Read new position
  int analog_in = analogRead(ANALOG_IN);
  stepper.moveTo(analog_in);
  stepper.setSpeed(1000);
  stepper.runSpeedToPosition();
  
  // Read new position
  int analog_in1 = analogRead(ANALOG_IN1);
  stepper1.moveTo(analog_in1);
  stepper1.setSpeed(1000);
  stepper1.runSpeedToPosition();
  
  // Read new position
  int analog_in2 = analogRead(ANALOG_IN2);
  stepper2.moveTo(analog_in2);
  stepper2.setSpeed(1000);
  stepper2.runSpeedToPosition();
}

Спасибо, почти разобрался! Написал скетч на 3 мотора. Все работает, но присутствует джиттер - дрожание мотора. http://arduino.ru/forum/programmirovanie/biblioteka-accelstepper  здесь описывается похожий случай с использованием гистерезиса, но никак не пойму, как его вклеить в мой скетч... Подскажите, плз, кусок кода...

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

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

в этой теме пост #27

я так сделал - всё гуд.

Rom327
Offline
Зарегистрирован: 25.04.2015
#include <AccelStepper.h> 

AccelStepper stepper(1, 6, 7);  
AccelStepper stepper1(1, 8, 9);  
AccelStepper stepper2(1, 10, 11);  

#define pot A0
#define pot1 A1
#define pot2 A2
#define GISTEREZIS 5
void setup() 
{   
  stepper.setMaxSpeed(1000); 
  stepper.setAcceleration(200); 
  stepper1.setMaxSpeed(1000); 
  stepper1.setAcceleration(200);
  stepper2.setMaxSpeed(1000); 
  stepper2.setAcceleration(200);} 

void loop() 
{ 
  int val = analogRead(pot);   
if (abs(val-stepper.currentPosition()) > GISTEREZIS) 
 
  stepper.moveTo(val); 
  stepper.setSpeed(1000); 
  while (stepper.runSpeedToPosition());
  
int val1 = analogRead(pot1);   
if (abs(val1-stepper1.currentPosition()) > GISTEREZIS) 
 
  stepper1.moveTo(val1); 
  stepper1.setSpeed(1000); 
  while (stepper1.runSpeedToPosition());
  
int val2 = analogRead(pot2);   
if (abs(val2-stepper2.currentPosition()) > GISTEREZIS) 
 
  stepper2.moveTo(val2); 
  stepper2.setSpeed(1000); 
  while (stepper2.runSpeedToPosition());  
} 

Спасибо! Джиттер возникал из-за наводок на потенциометре! Видимо надо экранировать. Еще такой вопрос при включении системы двигатели поворачаваются на угол, определенный потнциометром. Как от этого избавится? Это очень важно, так как механика не должна дергаться без команды.

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

а зачем два раза moveTo()

// Read new position
int analog_in = analogRead(ANALOG_IN);
if (abs(analog_in - stepper2.currentPosition()) > GISTEREZIS) 
{
  stepper.moveTo(analog_in);
  stepper.setSpeed(1000);
  stepper.runSpeedToPosition();
}

 

Rom327
Offline
Зарегистрирован: 25.04.2015

Если бы я знал... я же не программер... Я изменил #28... переписал по  образу и подобию в другой теме. Вроде заработало... и причина джиттера оказалась совсем не програмной. Теперь надо все наработки собрать воедино: 2 мотора с изменяемой скоростью от резистора + 3 мотора со слежением + 3 нопки для электромагнитов. Еще раз спасибо за помощь!

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

a зачем while?

я же вам написал как сделать

экспериментируете))))

Rom327
Offline
Зарегистрирован: 25.04.2015

Так тоже самое и вышло, хотя я совсем не знаю что такое "While" а уж зачем ... я ваще в тупике... То есть из поста #28 While можно убрать?

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

while блокирующая функция

http://arduino.ru/Reference/While

сделайте как я вам написал.
проверено.
работает.

Rom327
Offline
Зарегистрирован: 25.04.2015

Да, работает! Спасибо! Как сделать, чтобы двигатели не вращались при включении?

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

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

Rom327
Offline
Зарегистрирован: 25.04.2015

Как бы не так! При включении питания на плату Mega 2560 моторы крутятся ровно на половину пути, при условии, что потенциометры стоят в среднем положении. Причем крутятся в 2 этапа примерно на 15% и потом еще на 35% от полного хода. Если на момент включения потенциометр установлен в "0" мотор стоит, если установлен в +5 делает полный путь опять же в 2 приема 30%+70%. Как бы на момент включения заблокировать мотор в среднем положении и дать понять контроллеру, что он уже в среднем положении? Видимо надо что-то дописать в коде. Планирую использовать джойстик, а он возвращается в среднее положение пружинами.

Может где встречали код под такую функцию: энкодер управляет шд? Типа как тут: http://www.youtube.com/watch?v=dSpo88jKfFo

Rom327
Offline
Зарегистрирован: 25.04.2015

vvadim, можно ли запретить прохождение сигналов на выходы "steep" на время, скажем 30 секунд, пока не пройдут переходные процессы в контроллере? Или же добавть лишний провод En на каждый мотор и на нем запретить работу двигателей на некоторое время?

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

step у вас увязаны с потенциометром.

можно в сетапе дать задержку для enable.
если не нужно удержание, то можно подавать enable при изменении значений пот-ра.

Rom327
Offline
Зарегистрирован: 25.04.2015

vvadim пишет:

step у вас увязаны с потенциометром.

можно в сетапе дать задержку для enable.
если не нужно удержание, то можно подавать enable при изменении значений пот-ра.

По "enable" только на время включения, так как при работе не желательно: мотор останется без удержания и механика может сдвинуться. Или задержку на выходы steep. Как прописать задержку? Вроде бы надо использовать sleep?

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

в режиме sleep удержания тоже нет.

написали бы что ваяете, может меньше непоняток было бы)))

Rom327
Offline
Зарегистрирован: 25.04.2015

Станок для установки SMD по типу китайского TM 220A. http://www.youtube.com/watch?v=yRxcYO0nuD8 http://www.youtube.com/watch?v=Q5p7SXM7x1U Народ подобные строит и управляет через MACH3. Ардуина нужна, чтобы погонять механику...

Rom327
Offline
Зарегистрирован: 25.04.2015

Опять нужна помощь: хочу подать на вход Enable запрет на время переходных процессов.  Пробую вставить кусок кода из урока №1 о моргающем диоде. Там используется Delay. Диод то моргает, но и вся програма работает с задержками. Как быть?

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

Используем millis()

Rom327
Offline
Зарегистрирован: 25.04.2015
int EN = 3;
 
void setup() {
  pinMode(EN, OUTPUT);
  digitalWrite(EN, HIGH);
}
 
void loop() {
  if (millis()>5000) digitalWrite(EN, LOW);
}

Спасибо!

На другом форуме мне немного растолковали о millis(). Наивно полагая, что все получится, был написан код для сигнала Enable в контроллере на TB6560. На момент включения на вход Enable подается HIGH (на 5 секунд) и двигатель не вращается. Но когда на вход Enable подается LOW, двигатель делает +1 шаг. 10 включений =+10 шагов.... Надо как то запрещать выход Steep на момент включения...

 

 

Rom327
Offline
Зарегистрирован: 25.04.2015
/* Include the library */
#include "HCMotor.h"
#include <AccelStepper.h> 

/* Pins used to drive the motors */
#define DIR_PIN 10 //Connect to MotorX 'dir' input.
#define CLK_PIN 11 //Connect to MotorX 'step' or 'CLK' input.
#define DIR_PIN1 12 //Connect to MotorY 'dir' input.
#define CLK_PIN1 13 //Connect to MotorY 'step' or 'CLK' input.
AccelStepper stepper2(1, 5, 4); //Connect to MotorZ 'step' , 'dir' input 
AccelStepper stepper3(1, 7, 6); //Connect to MotorA 'step' , 'dir' input   
AccelStepper stepper4(1, 9, 8); //Connect to MotorB 'step' , 'dir' input   

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0 //Подключение потенциометра Х dir-10 step-11
#define POT_PIN1 A1 //Подключение потенциометра У dir-12 step-13
#define POT_PIN2 A2 //Подключение потенциометра Z dir-4 step-5 (пропорциональное управление)
#define POT_PIN3 A3 //Подключение потенциометра A Вращение компонента dir-6 step-7 (пропорциональное управление)
#define POT_PIN4 A4 //Подключение потенциометра B Подача компонентов dir-8 step-9 (пропорциональное управление)
#define GISTEREZIS 10

/* DEADZONE Мертвая зона потенциометров Х У */
#define DEADZONE 10 

/* Аналог PIN-код будет возвращать значения от 0 до 1024, чтобы разделить это между 
вперед и обратного */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1024


/* Create an instance of the library Создать экземпляр в библиотеке*/
HCMotor HCMotor;

void setup() 
{
  //Serial.begin(9600);
  /* Initialise the library Инициализация библиотеки */
  HCMotor.Init();

  HCMotor.attach(0, STEPPER, CLK_PIN, DIR_PIN);
  HCMotor.attach(1, STEPPER, CLK_PIN1, DIR_PIN1);
  
  HCMotor.Steps(0,CONTINUOUS);
  HCMotor.Steps(1,CONTINUOUS);
  
  stepper2.setMaxSpeed(1000); 
  stepper2.setAcceleration(200); 
  stepper3.setMaxSpeed(1000); 
  stepper3.setAcceleration(200);
  stepper4.setMaxSpeed(1000); 
  stepper4.setAcceleration(200);} 


void loop() 
  {
int Speed, Pot;

  /* Read the analogue pin to determine the position of the pot. Прочитайте аналог PIN-кода для определения позиции потенциометра. */ 
  Pot = analogRead(POT_PIN);

  /* Is the pot in the reverse position ? Это потенциометр в перевернутом положении? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? Это потенциометр в переднее положение? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? Это потенциометр в мертвой зоне? */
  }else
  {
    Speed = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments Установить скважность тактового сигнала шагом в 100uS */
  HCMotor.DutyCycle(0, Speed);
  
int Speed1, Pot1;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot1 = analogRead(POT_PIN1);

  /* Is the pot in the reverse position ? */
  if (Pot1 >= POT_REV_MIN && Pot1 <= POT_REV_MAX)
  {
    HCMotor.Direction(1, REVERSE);
    Speed1 = map(Pot1, POT_REV_MIN, POT_REV_MAX, 2, 10);

  /* Is the pot in the forward position ? */
  }else if (Pot1 >= POT_FWD_MIN && Pot1 <= POT_FWD_MAX)
  {
    HCMotor.Direction(1, FORWARD);
    Speed1 = map(Pot1, POT_FWD_MIN, POT_FWD_MAX, 10, 1);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed1 = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(1, Speed1);
  
int val = analogRead(POT_PIN2);   
if (abs(val-stepper2.currentPosition()) > GISTEREZIS) 
 
  stepper2.moveTo(val); 
  stepper2.setSpeed(1000); 
  stepper2.runSpeedToPosition();
  
int val1 = analogRead(POT_PIN3);   
if (abs(val1-stepper3.currentPosition()) > GISTEREZIS) 
 
  stepper3.moveTo(val1); 
  stepper3.setSpeed(1000); 
  stepper3.runSpeedToPosition();
  
int val2 = analogRead(POT_PIN4);   
if (abs(val2-stepper4.currentPosition()) > GISTEREZIS) 
 
  stepper4.moveTo(val2); 
  stepper4.setSpeed(1000); 
  stepper4.runSpeedToPosition();

  }

Два мотора Х и У работают, меняя скорость. Моторы Z, A, B работают пропорционально. Вот их и надо заставить не крутиться на момент включения ~ 1,5-2 секунды.