Interactive Workshop for Artists & Designers 연세대학교디지털아트학과, 2016 Earl Park
스테퍼모터 Stepper Motor 스테퍼모터는일반 DC 모터의장점인연속회전과서보모터의장점인정확한위치조정, 즉정밀제어가가능한모터이다. 스테퍼모터는 360도를일정한각도의스텝단계로나누어지정한스텝만큼회전하도록되어있으며, 예를들어한스텝이 1.8 인스테퍼모터는 200스텝을회전해야 360 를회전하게된다. 모터의스텝을빠르게올리면연속회전하며스텝을제어함으로써정방향, 역방향의회전, 정지가가능하다. 스테퍼모터의축을스텝단위로계속회전시키려면 4~8개의선으로펄스를제어해야하므로 DC 모터나 RC서보모터들보다는제어하기가훨씬복잡하다. 다른 DC 모터보다짜리몽땅하게생겼으며의외로토크도약한편이다. 그러나속도와위치제어가필요한프로젝트에는적합한모터이며, 실생활에서는정확한위치제어가필요한 NC공작기계나프린터, 팩스, 시계등에많이사용된다. Interactive Workshop 1
스테퍼모터의스펙 스텝각도 (Step Angle) 한스텝을제어했을때회전하는각도를뜻하며, 스텝각도가작은모터일수록정밀한위치제어가가능하다. 보통 2상모터는 1.8, 5상모터는 0.72 이다. 상 (Phase) 모터를동작시키는구동방식을말하며, 이상의종류에따라제어가달라지게된다. 보통은 2상은바이폴라, 4상은유니폴라모터로사용된다. 정격전압 (Rated Voltage) 정격전압은스테퍼모터가설계된전압으로이보다높은전압을공급하면모터가탈수도있고, 낮은전압을공급하면움직이지않을수있다. 정지토크 (Holding Toque) 아래는우리가사용할 'SM-42BYG011-25' 의데이터시트이다. 이모터는 2상바이폴라모터로 12볼트에서동작해최대 0.33A를소모하며, 정지토크는 0.23N m 로약 2.3kg cm이다. 한스텝을제어할때마다 1.8 가회전하며모터축의직경은 ø5이다. 모터를고정할때 4.5mm깊이 M3 나사 4개를사용해야한다는것도알수있다. 오른쪽배선도를보면빨간색전선과초록색전선이모터의한상을제어하고, 노란색과파란색전선이나머지한상을제어한다는것을알수있다. 더자세한사항은아래사이트에서확인할수있다. https://www.sparkfun.com/products/9238 모터에전원을공급해서한스텝의위치를유지하고있을때의토크이다. 모터의정격토크보다높은토크가필요한물체를움직이려면모터가미끄러질 ( 탈조할 ) 수있으며정확하게위치을조정하는스테퍼모터의장점을잃을수있다. 스테퍼모터는자신의위치가어디인지절대적으로알지못하며회전명령의스텝수만큼회전하고있을뿐이다. 만약정지토크를넘어서서모터가미끄러지면이모든장점이사라진다. 스테퍼모터의특징중눈여겨볼만한것은멈춤토크 (Detent Toque) 와동적토크 (Dynamic Toque) 이다. 멈춤토크는한스텝씩움직일때의토크로, 축이두개의정지위치사이에있기때문에정지토크 (Holding Toque) 보다낮다. 동적토크는멈춤토크와정지토크의평균인데, 대략정지토크의 65% 이상되는힘을기대해서는안된다. Interactive Workshop 2
스테퍼모터의구동방식 스테퍼모터는보통 2 개의 DC 모터를붙여놓았다고할수있는내부구조를가지고있 으며크게는유니폴라 (Unipolar, 단극성 ) 와바이폴라 (Bipolar, 양극성 ) 로나뉜다. 두가지방식은서로의특성이있으므로사용해야할목적에따라선택하면되며구 조에따라제어해야하는회로가달라진다. 보통바이폴라는선이 4 개, 유니폴라는선 이 5~8 개이며선의연결에따라유니폴라모터를바이폴라모터로사용할수도있다. 1 2 + - - + + - 3 4 + - 바이폴라 (Bioplar) 방식 양극성 (Bipolar) 구동방식은쌍극성이라고도하고이는전류의방향이양쪽으로모두 흐른다는의미이다. 위의그림에서양극성방식의경우는전류의방향을 1-2-3-4 의 순서로바꾸어구동하게되며쌍극성에사용할수있는모터는 4 가닥의외부전선을 갖는다. 유니폴라구동과비교해서각도의정밀도가좋고, 저속에서토크가좋으며모 1 2 3 4 5 6 < 바이폴라스테퍼모터 > < 유니폴라스테퍼모터 > 터의구동중코일에저장된에너지가다시전원으로돌아가게되므로에너지효율도유니폴라방법보다좋다. 반면회로가복잡하고고속에서토크가떨어지는결점이있다. 바이폴라의기본회로는하나의권선코일에전류의방향을바꿀수있다. 바이폴라구동방식은각도의정밀도와저속에서토크가좋기때문에로봇의제어에많이쓰이며, 대표적인드라이버 IC로는 L297, L298을들수있다. L297은스테퍼모터를정전류구동하기위한모든회로가포함된컨트롤러이며, L298은바이폴라구동을위한두개의 H-Bridge Driver를포함하고있다. 유니폴라 (Unipolar) 방식코일의중간탭 (2, 5) 을내어이곳으로계속전류를한쪽방향으로흘리는방식이다. 5~8가닥의외부전선중중간탭에연결된두선을사용하지않거나코일을직렬, 병렬연결함으로써바이폴라 (Bipolar) 구동방식으로사용할수도있다. 유니폴라구동방식은저속영역에서큰토크를기대할수없다. 또한모터는코일과같은성질을가지고있는데그래서모터가회전할때순간적으로모터에저장되는에너지를그라운드로흘려버리게되므로에너지효율이나빠지게된다. 그러나모터회로가간단하고전류의출입이정확하여고속에서탈조될위험이적어고속회전에용이하다는장점이있다. 유니폴라방법은에너지효율이나쁘다는단점이있음에도불구하고순간적으로빠른속도를필요로하는마이크로로봇등에많이쓰인다. 대표적인드라이버 IC로는 SLA7024M, L297을들수있다. Interactive Workshop 3
H-Bridge 회로 (Bipolar Motor 제어 ) 바이폴라모터의구동을위해서는 DC 모터와마찬가지로외부에 H-Bridge 회로를 구성해야한다. 2 개의 H-Bridge 의회로를열고닫음으로써모터의권선에흐르는전 류의방향을조절할수있게된다. 바이폴라스테퍼모터는스텝을조절하는펄스의수에따라속도가변하므로 DC 모 터와는달리 Enable 핀은 High, 즉 +5V 로연결한다. SN754410 에서아두이노로연결된로직핀에아래와같은신호를연속해서보내주면 한 Step씩계속해서연속회전을하게되며만약연속되는 4가지값을넣어주지못하면모터가부르르떨거나멈추게된다. 또한신호펄스가너무빠를경우에도모터안의코일이연속해서동작할타이밍을맞추지못하므로같은현상이나타날수있다. 모터를동작시키기위한논리회로및다이어그램은아래와같다. 바이폴라모터이므로 H-bridge회로가필요하다. 저번시간에사용했던 SN754410은 2개의 H-bridge 회로가내장되어있는칩으로 1암페어의스테퍼모터 1개를제어할수있다. SN754410 대신 L293B칩도사용가능하며, L293D는모터파워로 600mA까지사용가능하다. 만약모터에그이상의전류가필요하다면 L297, L298를생각해보자. step 1A 2A 3A 4A 동작 0 H L L H 시계방향 1스텝회전 1 H L H L 시계방향 1스텝회전 2 L H H L 시계방향 1스텝회전 3 L H L H 시계방향 1스텝회전.................. 위의 4 step 반복 위의 Step을계속반복하면시계방향으로회전한다. step 1A 2A 3A 4A 동작 0 L H L H 반시계방향 1스텝회전 1 L H H L 반시계방향 1스텝회전 2 H L H L 반시계방향 1스텝회전 3 H L L H 반시계방향 1스텝회전.................. 위의 4 step 반복 위의 Step을계속반복하면반시계방향으로회전한다. Interactive Workshop 4
스테퍼모터회전하기 스테퍼모터를회전시키고싶다. SN754410는 2개의 H-bridge 회로가내장된칩으로, 한개의바이폴라스테퍼모터를제어할수있다. 앞장에서보여준전류방향대로제어하면한스텝씩회전한다. SN754410 에연결된각핀을순서대로제어해보자. 딜레이명령에 spd의값을넣어줌으로써속도를조절할수있으며 500마이크로세컨드마다 1스텝, 1초에총 2스텝을회전하므로 100초에 1바퀴가회전하게된다. 만약여기서모터가계속해서한스텝씩같은방향으로회전하지않는다면모터핀이나마이크로컨트롤러에연결된핀이이상이있으니확인해야한다. byte data[]={b00001001,b00000101,b00000110,b00001010; int spd=500; void setup() { for (int i=8; i<=11; i++){ pinmode(i,output); void loop() { for (int i=0; i<4; i++){ digitalwrite(8,bitread(data[i],0)); digitalwrite(9,bitread(data[i],1)); digitalwrite(10,bitread(data[i],2)); digitalwrite(11,bitread(data[i],3)); delay(spd); 10~100uF Interactive Workshop 5
스위치로스테퍼모터의방향바꾸기 스테퍼모터의방향을제어하고싶다. 예를들어, 반시계방향으로회전하고있는모터를스위치를누르면시계방향으로회전시키고싶다. SN754410는 2개의 H-bridge 회로가내장된칩으로, 한개의바이폴라스테퍼모터를정방향, 역방향으로움직일수있다. PORT* 명령은아두이노핀을동시에제어할수있는명령어로 PORTD는 digital pin 0~7번핀을, PORTB는 digital pin 8~13번핀을제어할수있다. 앞장에서보여준전류방향대로제어하면한스텝씩회전한다. data[] 에제어할핀을저장해두고 PORTB 명령을통해한꺼번에제어한다. 딜레이명령에 spd의값을넣어줌으로써속도를조절할수있으며 5마이크로세컨드마다 1스텝, 1초에총 200스텝을회전하므로 1초에 1바퀴가회전하게된다. byte data[]={b00001001,b00000101,b00000110,b00001010; int spd=5; int switchpin=2; void setup() { pinmode(switchpin,input); for (int i=8; i<=11; i++){ pinmode(i,output); void loop() { if (digitalread(2)==high){ for (int i=0; i<4; i++){ PORTB=data[i]; delay(spd); else{ for (int i=3; i>=0; i--){ PORTB=data[i]; delay(spd); 10~100uF Interactive Workshop 6
스위치로스테퍼모터방향변경, 포텐시오미터로속도조절 스테퍼모터의방향뿐만아니라속도를제어하고싶다. 예를들어, 포텐시오미터를돌리는값에따라모터의속도에변화를주고싶다. 포텐시오미터로받아들인 0~1023의값을 map 함수를통해 0~500까지의값으로변화시키고딜레이명령에 spd의값을넣어줌으로써속도를조절할수있으며 1초에총 500스텝 ~2스텝까지변화를줌으로써 1초에 2.5~0.01바퀴가회전하게된다. byte data[]={b00001001,b00000101,b00000110,b00001010; int spd=500; int switchpin=2; void setup() { pinmode(switchpin,input); for (int i=8; i<=11; i++){ pinmode(i,output); void loop() { spd=map(analogread(5),0,1023,2,500); if (digitalread(2)==high){ for (int i=0; i<4; i++){ PORTB=data[i]; delay(spd); else{ for (int i=3; i>=0; i--){ PORTB=data[i]; delay(spd); 10~100uF Interactive Workshop 7
한스텝씩회전하기 ( 라이브러리 ) #include <Stepper.h> Stepper.h 라이브러리는스테퍼모터를좀더쉽게제어할수있도록아두이노에내장된라이브러리이다. (https://www.arduino.cc/en/reference/stepper) StepsPerRevolution은 1바퀴회전하는데필요한스텝수를나타내며 1.8인스테퍼모터는 200스텝이움직여야모터가 1바퀴회전하게된다. 사용하는모터의스텝각도에따라조절하자. mystepper.step(); 으로회전할스텝수를설정할수있다. -일경우는반대로회전한다. 시리얼모니터창을통해모터가몇스텝회전했는지확인할수있다. const int stepsperrevolution = 200; // change this to fit the number of steps per revolution // for your motor // initialize the stepper library on pins 8 through 11: Stepper mystepper(stepsperrevolution, 8, 9, 10, 11); int stepcount = 0; // number of steps the motor has taken void setup() { // initialize the serial port: Serial.begin(9600); void loop() { // step one step: mystepper.step(1); Serial.print("steps:"); Serial.println(stepCount); stepcount++; delay(500); 10~100uF Interactive Workshop 8
회전속도조절하기 ( 라이브러리 ) #include <Stepper.h> 라이브러리를사용하여모터의속도를조절해보려한다. sensorreading변수로센서값을읽어들여모터의 RPM을 0~150까지조절하게된다. setspeed 함수로모터가회전하는최대 RPM을설정할수있으며우리가사용하는모터는최대 150RPM으로 1초에 2.5바퀴정도회전이가능하다. 포텐시오미터의값에따라모터는 2step씩속도를더내며움직일수있다. const int stepsperrevolution = 200; // change this to fit the number of steps per revolution // for your motor // initialize the stepper library on pins 8 through 11: Stepper mystepper(stepsperrevolution, 8, 9, 10, 11); int stepcount = 0; // number of steps the motor has taken void setup() { // nothing to do inside the setup void loop() { // read the sensor value: int sensorreading = analogread(5); // map it to a range from 0 to 150: int motorspeed = map(sensorreading, 0, 1023, 0, 150); // set the motor speed: if (motorspeed > 0) { mystepper.setspeed(motorspeed); // step 1/100 of a revolution: mystepper.step(stepsperrevolution / 100); 10~100uF Interactive Workshop 9
정방향, 역방향으로순차적으로회전하기 ( 라이브러리 ) #include <Stepper.h> 라이브러리를사용하여스테퍼모터의방향, 속도를둘다제어하고싶다. mystepper.setspeed() 와 mystepper.step() 의조합으로스테퍼모터의회전속도와회전스텝을조절할수있다. mystepper.step() 에서 -값을넣으면역방향으로회전한다. 예를들어오른쪽의프로그래밍은 60RPM의속도로정방향으로 1바퀴회전한뒤 0.5초멈추고, 역방향으로 1바퀴회전한뒤 0.5초멈추기를계속반복한다. 만약 1초에 120RPM의속도 (1초에 2바퀴회전하는속도 ) 로 2바퀴씩정방향, 역방향으로회전을반복하게하고싶다면, mystepper.setspeed(120); 으로설정하고 mystepper.step(400); 으로설정하면된다. 단, 모터의물리적한계보다더빠르게회전할수는없다. const int stepsperrevolution = 200; // change this to fit the number of steps per revolution // for your motor // initialize the stepper library on pins 8 through 11: Stepper mystepper(stepsperrevolution, 8, 9, 10, 11); void setup() { // set the speed at 60 rpm: mystepper.setspeed(60); // initialize the serial port: Serial.begin(9600); void loop() { // step one revolution in one direction: Serial.println("clockwise"); mystepper.step(stepsperrevolution); delay(500); // step one revolution in the other direction: Serial.println("counterclockwise"); mystepper.step(-stepsperrevolution); delay(500); 10~100uF Interactive Workshop 10
DRV8825 칩을이용해모터회전하기 DRV8825는 8.2~45V의입력전압으로각상당 2.5A의전류까지입력할수있는고성능스테퍼모터드라이버이다. 프로그램은모터를 200Step 각각정방향으로, 역방향으로다른속도로돌리는예제이다. STEP핀으로는스탭을 Dir핀으로는정방향, 역방향을조절가능하다. int pinenable = 13; // Activation the driver int pinstep = 8; // Step int pindir = 9; // Direction void setup(){ Serial.begin(9600); Serial.println("Test DRV8825"); pinmode( pinenable, OUTPUT ); pinmode( pindir, OUTPUT ); pinmode( pinstep, OUTPUT ); void loop(){ digitalwrite(pindir, HIGH); // Direction event digitalwrite(pinstep, LOW); // Initialisation the step // 200 step for(int i=0; i<200; i++){ Serial.println( i ); digitalwrite(pinstep, HIGH); delay(10); digitalwrite(pinstep, LOW); delay(10); // Change the direction digitalwrite(pindir, LOW); // Direction event // reverse 200 step for(int i=0; i<200; i++){ Serial.println( i ); digitalwrite(pinstep, HIGH); delay(1); digitalwrite(pinstep, LOW); delay(1); 100uF Interactive Workshop 11
트랜지스터회로 (Unipolar Motor) 유니폴라모터의구동을위해서는각각의코일에흐르는전류를제어해주어야한 다. 그러기위해서는 4 개의트랜지스터를번갈아가며모터의권선을제어하는회로 가필요하다. 유니폴라모터권선의가운데에위치한 common 은모터의파워에알맞는전압, 예 를들면 +5V 나 +12V 에연결한다. 또한유니폴라모터전선색깔은제품마다모두다 르므로데이터시트를참고해야한다. 모터를동작시키기위한논리회로및다이어그램은바이폴라와같다 (Full Step). step 1A 2A 3A 4A 동작 0 H L L H 시계방향 1스텝회전 1 H L H L 시계방향 1스텝회전 2 L H H L 시계방향 1스텝회전 3 L H L H 시계방향 1스텝회전.................. 위의 4 step 반복 위의 Step을계속반복하면시계방향으로회전한다. 유니폴라모터는 500mA 정도의전류이하의모터라면트랜지스터어레이인 ULN2003 이나 ULN2004 를사용하고, 더높은전류 (1.5~3A) 가필요하다면유니폴라 전용드라이버인 SLA7024M 혹은 SLA7026M 등을사용하도록한다. step 1A 2A 3A 4A 동작 0 L H L H 반시계방향 1스텝회전 1 L H H L 반시계방향 1스텝회전 2 H L H L 반시계방향 1스텝회전 3 H L L H 반시계방향 1스텝회전.................. 위의 4 step 반복 위의 Step 을계속반복하면반시계방향으로회전한다. 앞에서해보았던 stepper.h 라이브러리를사용하는코드는유니폴라모터에똑같이 사용가능하다. Interactive Workshop 12
시리얼명령으로방향, 회전속도조절 ( 라이브러리 ) #include <Stepper.h> 라이브러리를사용하여스테퍼모터의방향, 속도를둘다제어하고싶다. 예를들어, 시리얼포트의명령을통해모터를어느한방향으로움직임과동시에속도를제어하고싶다. 시리얼포트명령어로숫자값과그뒤의 + 와 -에따라모터의스텝회전수와방향이결정된다. 예를들어 200step의모터의경우 "200+" 는모터가시계방향으로한바퀴가완전히회전한다는것을의미하며, "100-" 는모터가반시계방향으로반바퀴회전한다는것을의미한다. const int stepsperrevolution = 200; // change this to fit the number of steps per revolution // for your motor // initialize the stepper library on pins 8 through 11: Stepper mystepper(stepsperrevolution, 8, 9, 10, 11); int steps=0; void setup() { // initialize the serial port: Serial.begin(9600); mystepper.setspeed(30); void loop() { if( Serial.available()) { char ch = Serial.read(); if (isdigit (ch)){ // if ch is a number... steps = steps*10+ch-'0'; else if(ch == '+'){ mystepper.step(steps); steps=0; else if(ch == '-'){ mystepper.step(steps*-1); steps=0; Interactive Workshop 13