Управление шаговыми двигателями

Krom
Offline
Зарегистрирован: 04.01.2013

Здравствуйте. Есть необходимость управлять двумя шаговыми двигателями. Алгоритм такой: первый ШД поворачивается на определённый угол, затем второй ШД делает поворот на один угол, первый возвращается в исходное положение, второй делает ещё одно перемещение (он направление не меняет) и т.д. по кругу. Драйвер собрал на двух ULN2003, накидал вот такой скетчик для первого ШД, но поидее это полношаговый режим?!

 





#include <Stepper.h>
#define STEPS 10
Stepper stepper(STEPS, 8, 9, 10, 11);
void setup()
{
 
  stepper.setSpeed(1000);
}

void loop()
{
  //  вперед
  stepper.step(1*STEPS);
  delay(1 );
  //  назад
  stepper.step(-1*STEPS);
  delay(1);

}

Возможно ли его загнать в микрошаг? 

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

Буду очень признателен за помощь!

leshak
Offline
Зарегистрирован: 29.09.2011

Тут не очень ясно что вы понимаете под микрошаг. То есть термин-то такой есть и микрошаги возмножны (но не скаждым движком), но у меня есть сильно подозрение что вы хотите просто шаги.

То что вы написали, по идее, должно крутить степер на один оборот туда, потом на один оборот обратно.

Если вы хотите сделать именно "шаг", ну так сделайте просто  stepper.step(1).

Смотрите, в строке 10-ть вы сказали ему "полный оборот движка у меня состоит из 10-ти шагов". А в строке 13, сказали "повернись на 10-ть шагов" (вот и вышел оборот). Скажите меньше - повернется на меньше.

По поводу "двух степеров". Тут ответ очень сильно зависит от того нужно ли вам крутить их

1. По очереди (самый простой вариант). Вначали полностью простепали один, потом второй.

2. Реально "одновременно"

3. Псевдо одновременно: например нужно повернуть оба  на 20-шаго. Начинаем "шаг первым, шаг вторым, шаг первым, шаг вторым". Если делать быстро - будет иллюзия одновременности.

Ну и delay в микросекунду - малова-то будет. На глаз его заменить паузу между вперед и назад трудно будет.

 

 

Krom
Offline
Зарегистрирован: 04.01.2013

Спасибо, что откликнулись!

Стоит задача максимально плавного поворота зеркала, с минимальной ступенчатостью между перемещениями. Сейчас плохой шаговик использую с углом поворота за один шаг - 7,5 град., потом будет 1,8 град, с такими большими углами, разовые перемещния слишком большие. Я хочу подробить шаг хотябы 1/3, но я так понимаю, что придётся делать сложную стабилизацию тока в фазах для этого. 

Если на ардуино, это будет сделать очень сложно, то можно попробовать полушаг, когда двигатель делает шаг в половину основного. 

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

В программинге  ноль, так что помощь будет очень нужна!!!

leshak
Offline
Зарегистрирован: 29.09.2011

>плохой шаговик использую с углом поворота за один шаг - 7,5 град

Есть сомнение. В том коде что вы привели в стартовом. Вы делаете сразу 10-ть шагов. У вас вот тот код дает 7,5 град? Если да, то на самом деле значит у вас один шаг это 0.75 град. Нужно просто  stepper.step(1) делать, вместо stepper.step(1*STEPS);

Далее, можно взять степер с редуктором. Есть степеры у которых нужно пару сотен шагов сделать что-бы вообще на глаз заметить что он крутится начал. Или сколхозить какой-то редуктор. Вместо прямо вращения зеркала, сделать какой-то ролик на вал степера. Соотношением ролика и того к чему он прижимается подобрать нужную "плавность".

Можно и "полу-шаги". Тут дело не в "ардуина не может". Ей, вообщем-то все равно. Она дает импульсы. Важно их правильно запрограмить. То есть понимать в чем состоит суть полушагов. http://www.youtube.com/watch?v=dmk6zIkj7WM

А дальше руками с помощью digitalWrite степать (включать обмотки как в этом видео).

Либо найти библиотеку где уже кто-то выполнил эту работу.

Например вот, еще в 2009 году подхачили стандартную  либу до поддержки полу-шагов (добавили пятый параметр конструктора "использовать полу-шаги")  http://code.google.com/p/arduino/issues/detail?id=139 но почему-то так и не включили это в "стандартную поставку".

Или вот смотреть на альтернативную библиотеку: http://www.open.com.au/mikem/arduino/AccelStepper/

Она поддерживает и несколько степеров, и одновременно и по очереди. Похоже и полу-шаги.... вообщем по сравнению со стандартной - это мерс против жигулей.

 

Krom
Offline
Зарегистрирован: 04.01.2013

Ну эта программа не делает полный оборот ) Только 10 шагов, в одну сторону, потом в другую.

Я понимаю, что такое полушаг и микрошаг, но я не понимаю, как это кодить ) 

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

Ещё, я нашёл вот такой пример, я так понимаю, что тут как раз меняя значения на пинах, можно сделать полушаг.  Но как его переделать под два шаговых двигателя с тем алгоритмом, что мне надо???

const int motorPin1 =8;
const int motorPin2 =9;
const int motorPin3 =10;
const int motorPin4 =11;
 
 
void setup() {                
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(motorPin1, OUTPUT);    
  pinMode(motorPin2, OUTPUT);    
  pinMode(motorPin3, OUTPUT);    
  pinMode(motorPin4, OUTPUT);     
}
 
void loop() {
 // HALF STEP  
 int motorDelay=5;
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motorDelay);
  
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  delay(motorDelay);  
  
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motorDelay);  
  
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motorDelay); 
  
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motorDelay); 
  
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  delay(motorDelay); 
  
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motorDelay); 
  
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motorDelay); 
}

 

mr.il
Offline
Зарегистрирован: 05.01.2013

Прошу прощения за глупый вопрос. Я совсем начинающий (в программировании нормально, а вот в электронике слабоват).

Самые доступные шаговики для меня, это шд управления каретки с 3.5флопа.

Но я никак не могу найти на них описание. По этому (прошу не ругатся) или пните меня на нужный даташит или подскажите схему включения обмоток и вольтаж.

leshak
Offline
Зарегистрирован: 29.09.2011

>Но я никак не могу найти на них описание.

К сожалению "точного описания" вы врядли  найдете.  Так что тут "метод научного тыка". Гуглить "FDD arduino stepper". Смотреть на примеры/картинки пытатся догадатся "на кого похоже".

Вольтаж, наверное, проще всего начинать пробовать с 5v. Вот если не будет хватать - тогда чего-то и побольше можно.

Сама схема включения - танцевать от базового туториала:

http://arduino.cc/en/Tutorial/MotorKnob

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

http://digital.ni.com/public.nsf/allkb/0AEE7B9AD4B3E04186256ACE005D833B

Вот тут пример как крутить униполярный без библиотеки

http://www.arduino.cc/en/Tutorial/StepperUnipolar

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

 

Krom
Offline
Зарегистрирован: 04.01.2013

ШД с флопов очень плохие, лучше поищите с 5-ти дюймовых флопов, там они посурьёзнее. 

mr.il
Offline
Зарегистрирован: 05.01.2013

Krom, мне побаловаться, для начала.

leshak, пасиба, вот нарыл статью простого управления шд на УЛНке, может кому пригодится

http://elabz.com/driving-a-bipolar-stepper-motor-with-arduino-and-uln280...

leshak
Offline
Зарегистрирован: 29.09.2011

Ну эта статья вообщем-то вариации базового туториала ссылку на который я дал выше. Таких статей можно нарыть сотни :) И нужно ;)

Когда разбираетесь - открываете сразу все. Что-то поняли из одной, что-то из другой :)

Что-бы двигатся дальше вам нужно определится какую проблему вы будете решать в первую очередь: полушаги или "два степпера"?

 

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

Полушаг и до 1/16 шага будете задавать на драйвере.  Посмотрите http://schmalzhaus.com/EasyDriver/

leshak
Offline
Зарегистрирован: 29.09.2011

На выходных как раз прибежал знакомый. С криком "помоги тахометр забубенить". И как раз с шаговиком из FDD.

Разбирательство показало что "он биполярный". "Жрет как не в себя" (500ma на обмотку - легко, иногда до 1000ma :(  )

От идеи рулить через ULN - отказались (не нравится идея греть резюками воздух, тем более на таких токах).

К тому же  он пришел "уже спаянный" на драйвере LB1838.  Сам он вначале на PIC-ке пытался по этой статье http://radiohlam.ru/control/bipolar_step_motor.htm.

Тупо взяли табличку "как дергать выходы" из этой статьи и подергали "digitalWrite-тами" - вроде заработало.

Так что "побырику" накидал упрощенный аналог стандатной stepper для LB1838 рулящей чере 3-проводка (IN1,IN2 - закорочены между собой) плюс умеющую "помнить" в какую позицию у нас степер стал. (можно командовать не только "сделать 5-ть степов", но и "стань в позицию 20", как серве.

Так что, если кто будет на LB1838 собирать - могу поделится кодом.

 

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Микросхемка интересная, главное, на борту есть ограничение тока через обмотку.

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

leshak
Offline
Зарегистрирован: 29.09.2011

AlexFisher пишет:

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

Вы правы. Но тут нужно по по трем проводам. Или 4-рем, но не втой логике как штатная (штатая по очереди ногами дергает), а тут другой порядок (в статье он есть). Плюс мне еще нужна логика "помнить позицию".

Была мысль вначале AccelStepper похачить (и подхачил, пронаследовался от нее), но "больно большая" вышла. В ATMEGA8 кроме нее уже практически ничего не влазило во флешь. А брать более жирный камень - не хотелось (да банально ехать на рынок - лениво) ;)

mr.il
Offline
Зарегистрирован: 05.01.2013

Народ, привет!

Вот нашел статью по объяснению работы драйвера l298. Гуру понятно не удивит, а новичкам думаю полезно будет.

http://www.vri-cnc.ru/modules.php?name=News&file=article&sid=19

ЗЫ: тобишь этот драйвер ценен ещё и тем что может крутить простой (не ШД) двигатель в разных направлениях.

leshak
Offline
Зарегистрирован: 29.09.2011

mr.il пишет:

Народ, привет!

Вот нашел статью по объяснению работы драйвера l298. Гуру понятно не удивит, а новичкам думаю полезно будет.

http://www.vri-cnc.ru/modules.php?name=News&file=article&sid=19

ЗЫ: тобишь этот драйвер ценен ещё и тем что может крутить простой (не ШД) двигатель в разных направлениях.

Подобные ссылки полезны и "гуру". Хотя-бы для того что-бы было куда новичка послать, а не самому объяснять :)

Кстати, если кто-нибудь нароен простую схему (без использования специальных микрух-драйверов) по подлюкчению биполярника в micro (не half) режиме - буду благодарен. Там требуется не просто "включать/выключать" обмотки, но еще и ток на них регулировать. Что-то типа "включить обмотку на 78% мощи".

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Схема будет простой (ничего кроме ключей), если потребляемый ток обмотки как-то завести обратно в контроллер (для уменьшения этого тока, точнее для его ограничения путем уменьшения ширины импульсов (ШИМа). Иначе по-простому только без ограничения тока, а это чревато или перегревом двигателя или уменьшением момента.

Встречал где-то (кажется там же, на vri-cnc, только старый форум) конструкцию на 555ТМ7, там каждая группа обмоток запитана от источника тока на импульсном стабилизаторе. В холостую он дает 36 вольт, что обеспечивает хороший рывок шаговику. Всего получается 6 стабилизаторов, каждый на спец.микросхеме. Обвеса там, конечно, не много... но... вместе получается много :)

NikSan
Offline
Зарегистрирован: 14.02.2013

День добрый, подскажите как можно реализовать управление двумя шаговыми двигателями одновременно, хочу использозвать Arduino для станка чпу. Драйвера для двигателей pololu a4988. Видел много решений, но с этими драйверами не получается совместить

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

Да ну ладно вам, самые что не на есть обычные драйвера. Вам сюда  по подключению и управлению сюда.

NikSan
Offline
Зарегистрирован: 14.02.2013

maksim пишет:

Да ну ладно вам, самые что не на есть обычные драйвера. Вам сюда  по подключению и управлению сюда.

Спасибо за ссылки!

Да, вполне может быть обычные, пробовал применить прошивку ребят tps://github.com/grbl/grbl#readme, но вот как раз из за драйверов не подошло, сказали что H bridge не подходят, ничем помочь не можем (

Может рабочий интерпритатор подскажите? исходники от AlexFisher

не работают, отправляю сигнал на один из двигателей из программы, выставляется +5 на Step и все, все встало.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Я и не говорил, что будет легко :)

У меня работает. Мои исходники лучше брать за основу, а не целиком. Сам G-интерпретатор не мой - я его тоже откуда-то (не помню уже) скачивал.

Скетч не может просто так выставить +5 на степ и зависнуть - разве что нагрузка по этому пину такая, что виснет контроллер. Вот участок кода, который выдает степ:

void do_step(byte step_pin) {
  digitalWrite(step_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(step_pin, LOW);
}

 

NikSan
Offline
Зарегистрирован: 14.02.2013

AlexFisher пишет:

Я и не говорил, что будет легко :)

У меня работает. Мои исходники лучше брать за основу, а не целиком. Сам G-интерпретатор не мой - я его тоже откуда-то (не помню уже) скачивал.

Скетч не может просто так выставить +5 на степ и зависнуть - разве что нагрузка по этому пину такая, что виснет контроллер. Вот участок кода, который выдает степ:

void do_step(byte step_pin) {
  digitalWrite(step_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(step_pin, LOW);
}

 

т.е. вы

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

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

NikSan пишет:

Скорость вращения регулируется delay?

Нет, это просто кусок кода, который доказывает ,что скетч не может просто так выставить +5 на степ и зависнуть. Эта задержка нужна, что бы драйвер успел считать состояние вывода дуины.

NikSan пишет:

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

Ну а если их поменять местами друг с другом местами?

NikSan
Offline
Зарегистрирован: 14.02.2013

maksim пишет:

Нет, это просто кусок кода, который доказывает ,что скетч не может просто так выставить +5 на степ и зависнуть. Эта задержка нужна, что бы драйвер успел считать состояние вывода дуины.

Я перепутал Step и Dir. На Dir по умолчанию +5В. Продолжаю разбираться с предложенной AlexFisher

программой и прошивкой, СПАСИБО, кста за нее! ) Получается что скорость выставляется из приложения в поле F? а по умолчанию работает с максимально возможной рассчитываемой #define FAST_XY_FEEDRATE_INCH?

Получается что для полноценной работы мне нужно выставить параметры своей машины в _init?

maksim пишет:

Ну а если их поменять местами друг с другом местами?

Да, с этим разобрался, проблема действительно в драйвере, видимо резистору голову скрутил, обидно, пару драйверов спалил уже... (

inchin.alexander
Offline
Зарегистрирован: 28.04.2013

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

kairaxy
Offline
Зарегистрирован: 12.08.2013

всем привет,а вы не подскажите как реализовать след.

шаговик с сервой на роторе

шаговик делает поворот на 180(допустим) в конце серва делает шаг на градус и потом шаговик снова идет на 180(без разницы с возвратом или нет)

грубо говоря как бы 2х мерное сканирование 

шаговиком управляет motor shield v5

leshak
Offline
Зарегистрирован: 29.09.2011

inchin.alexander пишет:

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

Нет. Не мог бы... К сожалению человек с мотоциклом (я ему помогал в части кода) нашел новую работу и ему стало "не до того". Так что у меня банально нет в руках железа что-бы "довести проект" (да и зачем... мне тахометр не нужен :). Так что sorry, пока этот проект отложился на неопределенный срок :(

leshak
Offline
Зарегистрирован: 29.09.2011

kairaxy пишет:

шаговик делает поворот на 180(допустим) в конце серва делает шаг на градус и потом шаговик снова идет на 180(без разницы с возвратом или нет)

Так в чем вопрос-то? Конкретизируйте что именно вызывает затруднение?

Если проблема в том что "нужно дождатся пока серва повернется" (у шаговика, по дефолту нет этой проблема), то возможно вам поможет Леший в мире Ардуины: Умная Серва. Часть 1 - результат одного из моих графоманских приступов. Правда опять (в который уж раз) не хватило времени довести до конца все задумки :(

На первый вгляд, вам нужно в коде из статить заменить "светик" на "шаговик" и получится то что вы хотели.

kairaxy
Offline
Зарегистрирован: 12.08.2013

спасиб, уже примерно понял(вкл лазер,пройти линию,сдвинуть на градус,откл лазер,вернуться назад...и по новой) только вот с сервой понятно но как шаговик приручить чтоб после 180линий он останавливался,точнее все останавливалось.у меня пока кроме как прописи каждой позиции идеи нет(

ma1ex
Offline
Зарегистрирован: 11.07.2012

leshak пишет:

Так что, если кто будет на LB1838 собирать - могу поделится кодом.

Привет, сохранилс еще код? Хочу попользоваться драйвером из флопика. Тоже нужно запоминать позицию

art100
Offline
Зарегистрирован: 09.03.2014
 
попинайте код
//art100 to write test stepper motors leds pololulu A4988
// при запуске, мигает свет и мотор несколько раз, после этого крутяться двигатели.
//pins
#define LIGHT_PIN    A3//
#define LASER_PIN    A4//
#define MS_PIN       A5//
#define ENABLE_PIN_0  2//Stepper 1 as labeled on Shield, Turntable
#define STEP_PIN_0    3
#define DIR_PIN_0     4
#define ENABLE_PIN_1  5//Stepper 2, Laser Stepper
#define STEP_PIN_1    6
#define DIR_PIN_1     7
void setup(){ 
  pinMode(LASER_PIN, OUTPUT);
  pinMode(LIGHT_PIN, OUTPUT);
  pinMode(MS_PIN,    OUTPUT);
  digitalWrite(MS_PIN, HIGH);  //HIGH for 16microstepping, LOW for no microstepping
  pinMode(ENABLE_PIN_0, OUTPUT);
  pinMode(DIR_PIN_0,    OUTPUT);
  pinMode(STEP_PIN_0,   OUTPUT);
  pinMode(ENABLE_PIN_1, OUTPUT);
  pinMode(DIR_PIN_1,    OUTPUT);
  pinMode(STEP_PIN_1,   OUTPUT);
  digitalWrite(ENABLE_PIN_0, LOW);  //HIGH to turn off//enable turntable and laser steppers
  digitalWrite(ENABLE_PIN_1, LOW);  //HIGH to turn off
//test on start
  for(int i=0; i<10; i++){//blink all leds, lights ans the laser 10 times
    digitalWrite(ENABLE_PIN_0, HIGH);  //HIGH to turn off
    digitalWrite(ENABLE_PIN_1, HIGH);  //HIGH to turn off
    digitalWrite(LIGHT_PIN, 0); //turn light off
    digitalWrite(LASER_PIN, 0); //turn laser off
    delay(120);
    digitalWrite(ENABLE_PIN_0, LOW);  //HIGH to turn off
    digitalWrite(ENABLE_PIN_1, LOW);  //HIGH to turn off
    digitalWrite(LIGHT_PIN, 1); //turn light on
    digitalWrite(LASER_PIN, 1); //turn laser on
    delay(120);
  }
} 
//loop just steps all four steppers. =================
void loop(){//test allways
  digitalWrite(STEP_PIN_0, HIGH);
  digitalWrite(STEP_PIN_1, HIGH);
  delay(1);
  digitalWrite(STEP_PIN_0, LOW);
  digitalWrite(STEP_PIN_1, LOW);
  delay(1);
} 

типовая схема включения

 
.
кино 2-пару мегабайт
 
FreeWindusis
Offline
Зарегистрирован: 04.02.2016

Здравствуйте. Появился вопрос о правильности написания кода по управлению шаговым двигателем с использованием микрошага, а именно при подаче с компьютера команда foward или back получать поворот на 1 микрошаг в ту или другую сторону. Из техничесокй части, имеется Arduino UNO + драйвер A4988+шаговый двигатель по типу Nema 17 с поворотом за один шаг на 1,8 градуса и CNC шилд для удобства подключения. Просьба посмотреть код на правильность написания. Пусть не удивляет такое большое колличестов портов в дальнейшем код будет модернизироваться для управления по тому же принципу ещё 2 двигателями. Микрошаг устанавливается путем замыкания контактов на шилде.

// Инициализация портов на ардуино (Xs,Ys,Zs выходы для регулировки шага; Xd,Yd,Zd выходы для регулировки направления; En выход для включения двигателей)
int Xs = 2;
int Ys = 3;
int Zs = 4;
int Xd = 5;
int Yd = 6;
int Zd = 7;
int En = 8;
int inSize=0; // Переменная которая будет содержать размер буфера
int delayTime = 20; // Выдержка для регулировки скорости вращения
char str[128]; // Массив символов
void setup() {
  // Настраиваем нужные контакты на выход
  pinMode(Xs, OUTPUT);
  pinMode(Xd, OUTPUT);
  pinMode(En, OUTPUT);
  Serial.begin(9600); // Открываем порт со скоростью передачи в 9600 бод(бит/с) 
}
void foward()
{  
  digitalWrite(Xd, HIGH); // Задаём направление вращения по часовой стрелке
    // Делаем 1 шаг
  for (int i = 0; i < 1; ++i) {
    // Выполнение шага
    digitalWrite(Xs, HIGH);
    delay(delayTime); 
    digitalWrite(Xs, LOW);
    delay(delayTime);
  }

}
void back()
{
  digitalWrite(Xd, LOW); // Задаём направление вращения против часовой стрелки
    // Делаем 1 шаг
  for (int i = 0; i < 1; ++i) {
    // Выполнение шага
    digitalWrite(Xs, HIGH);
    delay(delayTime); 
    digitalWrite(Xs, LOW);
    delay(delayTime);
  }
}
void loop()
{     
  digitalWrite(En, HIGH); // Подаём питание на двигатель
     inSize=0; // Сбрасываем переменную
memset(str, '\0', 128); // Очищаем массив
 if(Serial.available() > 0)
 {
   delay(200); // Ждем, для того, чтобы пришли все данные
   inSize = Serial.available(); // Получаем длину строки и записываем ее в переменную
   for (int a = 0; a < inSize; a++)
   {
     str[a] = Serial.read(); // Читаем каждый символ, и пишем его в массив
   }
  
   // Сравнять массив со строкой
   if (strcmp(str, "foward") == 0) // Если было передано "foward" - вращаем вперед
   {
     Serial.println("roll foward"); // Отправляем сообщение компьютеру
     foward();
  }
  else if (strcmp(str, "back") == 0) // Если было передано "back" - вращаем назад
  {
     Serial.println("roll back");
     back();
  }
    else
  {
     Serial.println("Error command!");
  }
 }
}

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Я бы сказал, что 20мс для импульса степа многовато. Стандарт 8 мс. Можно 10 мс.

В целом нормально, не понимаю только зачем цикл в шагах? Разве что получать с компа количество шагов?

А вот обработка приема неправильная. Посмотрите пример для Serial. Нужно постоянно принимать символы, складывая их в буфер. После приема символа "новая строка" - передавать буфер на анализ и очищать только после обработки команды. Переполнение буфера тоже не забываем контроллировать. А так Вы рискуете принимать куски команд - будут пропуски, если вообще будет работать.

FreeWindusis
Offline
Зарегистрирован: 04.02.2016

Спасибо учту при дольнейшей дороботке.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

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

Вот в этом блоке какой смысл (цикл, выполняемый один раз)? 

  for (int i = 0; i < 1; ++i) 
Если это задел на будущее, тогда уж сразу предусмотреть возможность прямого указания числа шагов:
  for (long i = 0; i < steps; i++) 

Функции foward и back (а в планах еще 4 аналогичных) структурно одинаковые, отличаются только переменными, значит их можно объединить в одну универсальную функцию.

#define FORWARD        HIGH  // направление вращения по часовой стрелке для оси X
#define BACK           LOW   // направление вращения против часовой стрелки для оси X
#define RIGHT          HIGH  // направление вращения по часовой стрелке для оси Y
#define LEFT           LOW   // направление вращения против часовой стрелки для оси Y
#define UP             HIGH  // направление вращения по часовой стрелке для оси Z
#define DOWN           LOW   // направление вращения против часовой стрелки для оси Z
#define CW             HIGH  // направление вращения по часовой стрелке для любой оси
#define CCW            LOW   // направление вращения против часовой стрелки для любой оси

const byte Xs =        2;    // Xs,Ys,Zs - выходы для регулировки шага
const byte Ys =        3;
const byte Zs =        4;
const byte X =         5;    // X,Y,Z - выходы для регулировки направления
const byte Y =         6;
const byte Z =         7;
const byte En =        8;    // выход для включения двигателей
int inSize =           0;    // Переменная которая будет содержать размер буфера
const byte delayTime = 8;    // Выдержка для регулировки скорости вращения
char str[128];               // Массив символов

void setup() 
{
  // Настраиваем нужные порты на выход
  pinMode(Xs, OUTPUT);
  pinMode(X, OUTPUT);
  pinMode(Ys, OUTPUT);
  pinMode(Y, OUTPUT);
  pinMode(Zs, OUTPUT);
  pinMode(Z, OUTPUT);
  pinMode(En, OUTPUT);
  Serial.begin(9600); // Открываем порт со скоростью передачи в 9600 бод(бит/с) 
}

void loop()
{
// Примеры команд для движка:
// rotate(X, BACK, 100);  // крутим движок на оси X в направлении "от себя" на 100 шагов, параметры: BACK/FORWARD/CW/CCW
// rotate(Y, RIGHT, 300); // крутим движок на оси Y в направлении "вправо" на 300 шагов, параметры: EFT/RIGHT/CW/CCW
// rotate(Z, UP, 50);     // крутим движок на оси Z в направлении "вверх" на 50 шагов, параметры: UP/DOWN/CW/CCW
// rotate(Z, CW, 10);     // крутим движок на оси Z по часовой стрелке на 10 шагов

  inSize=0; // Сбрасываем переменную
  memset(str, '\0', 128); // Очищаем массив
  if(Serial.available() > 0)
  {
    delay(200); // Ждем, для того, чтобы пришли все данные
    inSize = Serial.available(); // Получаем длину строки и записываем ее в переменную
    for (int a = 0; a < inSize; a++)
    {
      str[a] = Serial.read(); // Читаем каждый символ, и пишем его в массив
    }

    // Сравнять массив со строкой
    if (strcmp(str, "foward") == 0) // Если было передано "foward" - вращаем вперед
    {
      Serial.print("roll forward... "); // Отправляем сообщение компьютеру
      rotate(X, FORWARD, 1);
      Serial.println("Done.");
    }
    else if (strcmp(str, "back") == 0) // Если было передано "back" - вращаем назад
    {
      Serial.print("roll back... ");
      rotate(X, BACK, 1);
      Serial.println("Done.");
    }
    else
    {
      Serial.println("Error command!");
    }
  }
}



// крутим нужный движок. Входные параметры: <ось>, <направление>, <число шагов>
void rotate(byte axis, boolean direction, unsigned long steps) 
{
  digitalWrite(En, HIGH);                   // Подаём питание на двигатель
  digitalWrite(axis, direction);            // Задаём направление
  for (unsigned long i = 0; i < steps; i++) // Делаем n шагов
  {
    // Выполнение 1 шага
    digitalWrite(axis, HIGH);
    delay(delayTime); 
    digitalWrite(axis, LOW);
    delay(delayTime);
  }
  digitalWrite(En, LOW);                    // Снимаем питание, чтобы не греть обмотки
}