Stepper в массиве

suvi78
Offline
Зарегистрирован: 27.02.2015

Здравствуйте. Ардуино управляет тремя шд.

Stepper myStepper1(stepsPerRevolution, 2, 3, 4, 5);
Stepper myStepper2(stepsPerRevolution, 6, 7, 8, 9);
Stepper myStepper3(stepsPerRevolution, 10,11,12,13);
 
Есть ли способ их объединить в массив? ( Stepper myStepper[i] )
Так как я в скобках написал - не работает.
X-Dron
Offline
Зарегистрирован: 24.01.2015

Без модификации библиотеки нельзя.
там всего 2 конструктора.

Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2);
Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4);

Если дописать 3-й
Stepper();
и отдельные функции инициализации StepperInit2(int number_of_steps, int motor_pin_1, int motor_pin_2) и StepperInit4(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4), то можно.

 

suvi78
Offline
Зарегистрирован: 27.02.2015

Спасибо, пока оставлю код без изменений. В классах еще не силен. 

X-Dron
Offline
Зарегистрирован: 24.01.2015

Если очень надо, могу сделать. Дело на 10 минут.
Т.к. в IDE библиотеки могут обновляться, а у меня IDE не самой последней версии - выложи свою библиотеку Stepper.
У меня находится по адресу C:\Program Files (x86)\Arduino\libraries\Stepper

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014
Stepper myStepper1(100, 2, 3, 4, 5);
Stepper myStepper2(150, 6, 7, 8, 9);
Stepper myStepper3(200, 10,11,12,13);
Stepper* mySteppers[3];

void setup()
{
  mySteppers[0]=&myStepper1;
  mySteppers[1]=&myStepper2;
  mySteppers[2]=&myStepper3;
  for (byte i=0;i<3;i++) {
     (*mySteppers[i]).setSpeed(30);
  }
}

Где тут проблемма ?

X-Dron
Offline
Зарегистрирован: 24.01.2015

Интересный подход. :)
Работать с объектами через массив указателей, а не через массив объектов.
Теперь главное не запутаться со звездочками. :)

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Это подход истинного программиста микропроцессоров :) А путаться тут не в чем. Если хочется красоты используйте дефайны :) А вот ковырять стандартные библиотеки - моветон. Надеюсь объяснять почему не нужно ?

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

suvi78
Offline
Зарегистрирован: 27.02.2015

Brokly, спасибо. Это то, что нужно.

Datak
Offline
Зарегистрирован: 09.10.2014

Если хочется без звёздочек - могу ещё посоветовать массив ссылок. :)

suvi78
Offline
Зарегистрирован: 27.02.2015

Я переоценил свои возможности в программировании, пока почитаю литературу по передаче указатклей в функции.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Если сложно понимается можно просто объявить массив указателей глобально, как в моем примере, а в функцию передавать просто индекс элемента :)

suvi78
Offline
Зарегистрирован: 27.02.2015

void MoveSM(long x, long y, long z, Stepper* mySteppers)

{

...

(*mySteppers[i]).step(1);

}

void loop(){

...

 MoveSM(c[0],c[1],c[2], mySteppers);

}

так правильно?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014
Stepper myStepper1(100, 2, 3, 4, 5);
Stepper myStepper2(150, 6, 7, 8, 9);
Stepper myStepper3(200, 10,11,12,13);
Stepper* mySteppers[3];

void setup()
{
  mySteppers[0]=&myStepper1;
  mySteppers[1]=&myStepper2;
  mySteppers[2]=&myStepper3;
  for (byte i=0;i<3;i++) {
     (*mySteppers[i]).setSpeed(30);
  }
}

void MoveSM(long x, long y, long z, byte SteprerInd){
   (*mySteppers[SteprerInd]).step(1);
}

void loop()
{
   MoveSM(1,2,3,1); // для моторв с номером 1
   MoveSM(1,2,3,0); // для моторв с номером 0
}

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014
Stepper myStepper1(100, 2, 3, 4, 5);
Stepper myStepper2(150, 6, 7, 8, 9);
Stepper myStepper3(200, 10,11,12,13);
Stepper* mySteppers[3];

void setup()
{
  mySteppers[0]=&myStepper1;
  mySteppers[1]=&myStepper2;
  mySteppers[2]=&myStepper3;
  for (byte i=0;i<3;i++) {
     (*mySteppers[i]).setSpeed(30);
  }
}

void MoveSM(long x, long y, long z, Stepper* goStepper){
   goStepper->step(1);
}

void MoveSM_1(long x, long y, long z, Stepper* goStepper){
   (*goStepper).step(1);
}

void MoveSM_2(long x, long y, long z, Stepper goStepper){
   goStepper.step(1);
}


void loop()
{
   MoveSM(1,2,3,mySteppers[1]); // для мотора с номером 1, не забудьте про нулевой ;)
// ИЛИ
   MoveSM_1(1,2,3,mySteppers[1]); // для мотора с номером 1
// ИЛИ
   MoveSM_2(1,2,3,*(mySteppers[1])); // для мотора с номером 1
}

А еще можно вот так. Выбирайте любой вариант, это ж си... Но предъидущий займет меньше места.

suvi78
Offline
Зарегистрирован: 27.02.2015
В общем, как параметр в функцию указатель передавать было не нужно.
Выкладываю код, может кому пригодится. Программу взял с сайта http://www.ecnc.ru/ 
Двигатели гудели, но не двигались. Разбираться со сдвигами не хотелось, поэтому переделал под стандартную библиотеку stepper.
#include <Stepper.h>

const int stepsPerRevolution = 48;

Stepper myStepper0(stepsPerRevolution, 2, 3, 4, 5);
Stepper myStepper1(stepsPerRevolution, 6, 7, 8, 9);
Stepper myStepper2(stepsPerRevolution, 10,11,12,13);
Stepper* mySteppers[3];
int incomingByte = 0;
int sign=1;

//Процедура настройки прошивки
void setup() {
  mySteppers[0]=&myStepper0;
  mySteppers[1]=&myStepper1;
  mySteppers[2]=&myStepper2;
  
  for (byte i=0;i<3;i++) {
    (*mySteppers[i]).setSpeed(60);
  }
  
  Serial.begin(9600);
}


//Одновременный поворот двигателей 0, 1, 2 на x, y, z шагов соответственно
void MoveSM(long x, long y, long z ) {
  long c[3], c2[3];
  double c1[3], d[3];
  long m, i;
  boolean flg;
  
  c[0] = x;
  c[1] = y;
  c[2] = z;
  
  m = 1;
  for (i=0; i<3; i++) {
    if (m < abs(c[i])) m = abs(c[i]);
  }
  
  for (i=0; i<3; i++) {
    c1[i] = 0;
    d[i] = 1.0 * c[i] / m;
    c2[i] = 0;
  }

  flg = false;
  for (i=0; i<3; i++) {
    if (abs(c1[i]) < abs(c[i])) flg=true;
  }
  while (flg) {
    flg=false;
    for (i=0; i<3; i++) {
      if (abs(c1[i]) < abs(c[i]))
       c1[i] += d[i];
      if (abs(c1[i]) - abs(c2[i]) >= 0.5) {
       if (c[i]>0) {
        c2[i]++;

        (*mySteppers[i]).step(1);
        
       } else {
        c2[i]--;
        
        (*mySteppers[i]).step(-1);
        
       }
      }
      if (abs(c1[i]) < abs(c[i])) flg=true;
    }
  }
}
  
//Основной цикл
void loop() {
 if (Serial.available() > 0) { //Пришла команда
  long c[4]={0,0,0,0};
  int i;
 
  sign=1;
  i=0;
  incomingByte = Serial.read();
  while (incomingByte!=';') { //Читаем входящую строку, признак конца строки знак "точка с запятой"
   if (c[i]==0) {
    if (incomingByte=='-')
     sign=-1;
   }
   if (incomingByte==',') {
    c[i]*=sign;
    sign=1;
    i++;
   } else if (incomingByte>='0' && incomingByte<='9') {
    c[i]=c[i]*10+incomingByte-'0';
   }
   while (Serial.available() == 0) {
    delay(2);
   }
   incomingByte = Serial.read();
  }
  c[i]*=sign;
  
    MoveSM(c[0],c[1],c[2]);

  Serial.println("OK");  //Отправляем компьютеру сообщение "OK", значит можно высылать новую команду
 }
 else
  delay(100); //Если ничего не пришло, ждём 1/10 секуды.
}