BASIC4MCU | 질문게시판 | 답변 : 아두이노 스텝모터 제어에 대하여..
페이지 정보
작성자 master 작성일2020-01-13 22:37 조회21,094회 댓글6건본문
안녕하세요 스텝모터 제어와 관련하여 구글링 하던 도중 이 사이트를 알게 되어 처음 가입했습니다.다름이 아니라 아래 소스코드에서 3가지 질문이 있어서 질문글을 작성합니다.//Arduino Mega를 사용합니다./*작동 방법은 다음과 같습니다.*먼저 arduino의 전원을 on하면 스크류를 이용한 슬라이더의 위치를 정렬합니다.다음으로 up,down 버튼을 눌러 motor2의 회전수를 설정합니다.startbutton을 누르게 되면 설정 값 만큼 회전하기 위해motor2가 작동됨과 동시에 motor1은 motor2가 설정값을만족시킬 때 까지 1000 step 씩 스크류를 이용한 슬라이더를좌,우로 왕복 운동합니다.이후 설정값을 만족 시키게 되면 motor1과 motor2는 모두 정지하고0.5초의 딜레이가 주어진 후 슬라이드를 원 위치로 복귀시키기 위해motor1을+방향으로 회전합니다.슬라이드가 움직여 홈 위치에 있는 reset버튼을 눌러 홈 위치를 인식하게 되면스위치와의 약간의 간격을 두기 위해-100step 정도를 움직입니다.*/#include#define STEPS 200// 1.8 deg/step,360/1.8=200#define rotation 200// limitless rotationStepper motor1(STEPS,8,10,9,11);Stepper motor2(rotation,4,5,6,7);int startbutton=38;int reset=30; //슬라이드를 원 위치로 복귀int up=31; //숫자를 0~9범위에서 1씩 증가 설정int down=32; //숫자를 0~9범위에서 1씩 감소 설정int count=2; //아직 count의 값을 받도록 회로를 구성하지 않았기 때문에 2를 입력.int i;void setup(){pinMode(reset,INPUT);pinMode(startbutton,INPUT);pinMode(up,INPUT);pinMode(down,INPUT);}//void loop(){/*if(digitalRead(up)==HIGH){++count;if(count>9){count=0;}}if(digitalRead(down)==HIGH){--count;if(count<0){count=9;}}*/ //이것은 회로구성 하지 않았습니다.for(;;){ //arduino전원 on시 슬라이더 위치 정렬motor1.setSpeed(60);motor1.step(1);if(digitalRead(reset)==HIGH){motor1.setSpeed(70);motor1.step(-100); //스위치와의 간격 두기break;}}//질문 1.여기서 한 번 실행되고 start버튼이 눌릴 때 까지 가만히 대기 상태를 유지하는 것은 어떻게 코드를 작성해야 할까요?//위 처럼 작성을 하니 무한 반복이 됩니다..if(digitalRead(startbutton)==HIGH){ //startbutton을 누르면 작동 시작for(i=0; i<=count; i++){//motor2.setSpeed(60);motor2.step(200*count); //200step=1rotation//질문2.motor2가 실행된 후 motor1이 순차적으로 실행되는데 이것을 어떻게 동시에 실행시킬 수가 있을까요?(회로도를 참고하여 코드도 써 주시면 감사하겠습니다.)motor1.setSpeed(20);motor1.step(-1000);motor1.step(+1000);//if(i==count){ //설정값 만큼을 움직이면motor2.step(0); //motor2는 정지.for(;;){motor1.setSpeed(50);motor1.step(+1);if(digitalRead(reset)==HIGH){ //슬라이더가 움직여 reset버튼을 눌러 홈 위치를 인식 할 때 까지+1step 씩 회전motor1.setSpeed(70);motor1.step(-100); //스위치와의 간격 두기break; //질문3.여기서도 한 번만 실행되고 멈추는 방법을 모르겠습니다..(여기서 끝나지를 않으니 다시 맨 처음 상태로 돌아가질 않습니다..)}}}}}}//지금까지 코드였고,아래는 코드로 실행시킬 회로도 입니다..첨부파일에 소스코드와 회로도 사진 올려놓았습니다..(보기는 좋지 못하지만 질문드리기 위해 열심히 그렸습니다...ㅠ)회로도와 작동 방식을 참고하시어 코드를 수정해 주시면 정말..정말로 고맙겠습니다..
![]()
for(;;){ //arduino전원 on시 슬라이더 위치 정렬motor1.setSpeed(60); motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70);motor1.step(-100); //스위치와의 간격 두기break;}}이 코드는 루프함수가 아닌 셋업함수 아랫쪽에 두어야지 1회만 실행됩니다.
if(digitalRead(startbutton)==HIGH){ //startbutton을 누르면 작동 시작이 코드도 셋업함수 아랫쪽에 두어야겠군요
while(!digitalRead(startbutton)); //startbutton을 누를 때까지 대기단, 코드를 조금 수정해야합니다.
//
void setup(){pinMode(reset,INPUT); pinMode(startbutton,INPUT); pinMode(up,INPUT); pinMode(down,INPUT);motor1.setSpeed(60);//for(;;){ //arduino전원 on시 슬라이더 위치 정렬motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70); motor1.step(-100); //스위치와의 간격 두기break;}}//while(!digitalRead(startbutton)); //startbutton을 누를 때까지 대기}//------------------------
//질문2.motor2가 실행된 후 motor1이 순차적으로 실행되는데 이것을 어떻게 동시에 실행시킬 수가 있을까요?(회로도를 참고하여 코드도 써 주시면 감사하겠습니다.)motor2.setSpeed(60); motor2.step(200*count); //200step=1rotationmotor1.setSpeed(20); motor1.step(-1000); motor1.step(+1000);모터1도 200스텝 기준으로 변경하면
motor1.setSpeed(20); motor1.step(-200*5); motor1.step(200*5);
이렇게 되겠죠
for(i=0; i<=count; i++){
count는 0~9 범위이므로 모터1의 스텝수가 모터2보다 크군요
//질문2.motor2가 실행된 후 motor1이 순차적으로 실행되는데 이것을 어떻게 동시에 실행시킬 수가 있을까요?(회로도를 참고하여 코드도 써 주시면 감사하겠습니다.)motor1.setSpeed(20); motor2.setSpeed(60);int k=100*count;for(int n=0;n<1000;n++){ motor1.step(-1); if(n<k)motor2.step(1); }for(int n=0;n<1000;n++){ motor1.step( 1); if(n<k)motor2.step(1); }
//----------
// 질문3.여기서도 한 번만 실행되고 멈추는 방법을 모르겠습니다.motor1.setSpeed(50); motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70); motor1.step(-100);break;}완전히 끝내고 스타트 버튼을 대기 하고 싶다는 것이겠죠?
while(!digitalRead(startbutton)); //startbutton을 누를 때까지 대기셋업함수 제일 아래의 코드를 루프 함수 제일 위로 이동해야겠군요break; 대신 return을 사용해야지 이중 for()문을 빠져나갑니다.
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2020-01-13 오후 11:01:20// by Ok-Hyun Park//#include#define STEPS 200 // 1.8 deg/step,360/1.8=200#define rotation 200 // limitless rotation//Stepper motor1(STEPS,8,10,9,11);Stepper motor2(rotation,4,5,6,7);//int startbutton=38;int reset=30; //슬라이드를 원 위치로 복귀int up=31; //숫자를 0~9범위에서 1씩 증가 설정int down=32; //숫자를 0~9범위에서 1씩 감소 설정int count=2; //아직 count의 값을 받도록 회로를 구성하지 않았기 때문에 2를 입력.//int i;//void setup(){pinMode(reset,INPUT); pinMode(startbutton,INPUT); pinMode(up,INPUT); pinMode(down,INPUT);motor1.setSpeed(60);//for(;;){ //arduino전원 on시 슬라이더 위치 정렬motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70); motor1.step(-100); //스위치와의 간격 두기break;}}}//void loop(){while(!digitalRead(startbutton)); //startbutton을 누를 때까지 대기//// if(digitalRead(up )){ if(++count>9)count=0; }// if(digitalRead(down)){ if(--count<0)count=9; } //이것은 회로구성 하지 않았습니다.//for(i=0; i<=count; i++){motor1.setSpeed(20); motor2.setSpeed(60);int k=100*count;for(int n=0;n<1000;n++){ motor1.step(-1); if(n<k)motor2.step(1); }for(int n=0;n<1000;n++){ motor1.step( 1); if(n<k)motor2.step(1); }//if(i==count){motor1.setSpeed(50); motor2.step(0);for(;;){motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70); motor1.step(-100);return;}}}}}헤더파일이 삭제된 것을보니 네이버에 올린글을 복사했나보군요
루프함수 마지막 코드를 조금 수정해드리죠
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2020-01-13 오후 11:03:35// by Ok-Hyun Park//#include#define STEPS 200 // 1.8 deg/step,360/1.8=200#define rotation 200 // limitless rotation//Stepper motor1(STEPS,8,10,9,11);Stepper motor2(rotation,4,5,6,7);//int startbutton=38;int reset=30; //슬라이드를 원 위치로 복귀int up=31; //숫자를 0~9범위에서 1씩 증가 설정int down=32; //숫자를 0~9범위에서 1씩 감소 설정int count=2; //아직 count의 값을 받도록 회로를 구성하지 않았기 때문에 2를 입력.//int i;//void setup(){pinMode(reset,INPUT); pinMode(startbutton,INPUT); pinMode(up,INPUT); pinMode(down,INPUT);motor1.setSpeed(60);//for(;;){ //arduino전원 on시 슬라이더 위치 정렬motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70); motor1.step(-100); //스위치와의 간격 두기break;}}}//void loop(){while(!digitalRead(startbutton)); //startbutton을 누를 때까지 대기//// if(digitalRead(up )){ if(++count>9)count=0; }// if(digitalRead(down)){ if(--count<0)count=9; } //이것은 회로구성 하지 않았습니다.//for(i=0; i<=count; i++){motor1.setSpeed(20); motor2.setSpeed(60);int k=100*count;for(int n=0;n<1000;n++){ motor1.step(-1); if(n<k)motor2.step(1); }for(int n=0;n<1000;n++){ motor1.step( 1); if(n<k)motor2.step(1); }}//motor1.setSpeed(50); motor2.step(0);for(;;){motor1.step(1);if(digitalRead(reset)){motor1.setSpeed(70); motor1.step(-100);return;}}}질문 3에서 이중 for()문이 아니므로 return 을 사용하든 break를 사용하든 상관없습니다.
댓글 6
조회수 21,094sims님의 댓글
sims 작성일
아,,, 감사합니다.. 몇가지 소스코드 수정 후 질문글도 수정하였습니다., 글로벌변수로 flag처럼 int notstart = 0; 이렇게 하여 무한루프에서 빠져나오는 방법은 해결 하였습니다,
아래는 수정한 소스코드입니다. 질문글에도 수정된 소스코드가 있습니다.
//Arduino Mega를 사용합니다.
/*작동 방법은 다음과 같습니다.
*
먼저 arduino의 전원을 on하면 스크류를 이용한 슬라이더의 위치를 정렬합니다.
다음으로 up, down 버튼을 눌러 motor2의 회전수를 설정합니다.
startbutton을 누르게 되면 설정 값 만큼 회전하기 위해
motor2가 작동됨과 동시에 motor1은 motor2가 설정값을
만족시킬 때 까지 1000 step 씩 스크류를 이용한 슬라이더를
좌, 우로 왕복 운동합니다.
이후 설정값을 만족 시키게 되면 motor1과 motor2는 모두 정지하고
0.5초의 딜레이가 주어진 후 슬라이드를 원 위치로 복귀시키기 위해
motor1을 +방향으로 회전합니다.
슬라이드가 움직여 홈 위치에 있는 reset버튼을 눌러 홈 위치를 인식하게 되면
스위치와의 약간의 간격을 두기 위해 -100step 정도를 움직입니다.
*/
#include <Stepper.h>
#define STEPS 200// 1.8 deg/step, 360/1.8 = 200
#define rotation 200// limitless rotation
Stepper motor1(STEPS, 8, 10, 9, 11);
Stepper motor2(rotation, 4, 5, 6, 7);
int startbutton = 38;
int reset = 30;//슬라이드를 원 위치로 복귀
int up = 31;//숫자를 0~9범위에서 1씩 증가 설정
int down = 32;//숫자를 0~9범위에서 1씩 감소 설정
int count = 2;//아직 count의 값을 받도록 회로를 구성하지 않았기 때문에 2를 입력.
int notstart = 0;
int stp = 0;
int i;
void setup() {
pinMode(reset, INPUT);
pinMode(startbutton, INPUT);
pinMode(up, INPUT);
pinMode(down, INPUT);
}
void loop() {
/*if(digitalRead(up)==HIGH){
++count;
if(count>9){
count=0;
}
}
if(digitalRead(down)==HIGH){
--count;
if(count<0){
count=9;
}
}*/ //이것은 회로구성 하지 않았습니다.
if(notstart==0){
for(;;){ //arduino전원 on시 슬라이더 위치 정렬
motor1.setSpeed(60);
motor1.step(1);
if(digitalRead(reset)==HIGH){
motor1.setSpeed(70);
motor1.step(-100);//스위치와의 간격 두기
notstart=1;
break;
}
}
}
if(digitalRead(startbutton)==HIGH){ //startbutton을 누르면 작동 시작
for(i=0; i<=count; i++){
//
motor2.setSpeed(60);
motor2.step(200*count);//200step = 1rotation
//질문1. motor2가 실행된 후 motor1이 순차적으로 실행되는데 이것을 어떻게 동시에 실행시킬 수가 있을까요?(회로도를 참고하여 코드도 써 주시면 감사하겠습니다.)
motor1.setSpeed(20);
motor1.step(-10);
motor1.step(+10);
//
if(i==count){ //설정값 만큼을 움직이면
motor2.step(0); //motor2는 정지.
if(stp==0){
for(;;){
motor1.setSpeed(50);
motor1.step(+1);
if(digitalRead(reset)==HIGH){ //슬라이더가 움직여 reset버튼을 눌러 홈 위치를 인식 할 때 까지 +1step 씩 회전
motor1.setSpeed(70);
motor1.step(-100);//스위치와의 간격 두기
stp=1;
break;
}
}
}
stp=0;
}
}
}
}
master님의 댓글
master
답변글 내용 추가했으니 다시 읽어보세요
sims님의 댓글
sims 작성일
감사합니다.. 다른 부분은 모두 해결이 되었습니다.
하지만 아직 이 부분에서 해결되지를 않네요...
동시에 작동을 하기는 하지만 모터2가 연속적으로 돌지를 않고 중간중간 정지합니다. 속도도 느리고..
motor1.setSpeed(20);
motor2.setSpeed(60);
//int k=200*count; 이 부분을 삭제하니 모터 2가 연속으로 돌아가긴 하지만 속도가 현저히 낮습니다. 속도 값을 바꾸어 주어도 변화가 없네요..
for(int n=0;n<1000;n++){ motor1.step(-1); motor2.step(1); }
for(int n=0;n<1000;n++){ motor1.step( 1); motor2.step(1); }
master님의 댓글
master
모터1과 모터2의 스텝수가 다르므로 둘 중 하나는 섰다 갔다 하는 것이 당연합니다.
master님의 댓글
master
motor1.setSpeed(20); motor2.setSpeed(60);
for(int n=0;n<1000;n++){ motor1.step(-1); motor2.step(1); }
for(int n=0;n<1000;n++){ motor1.step( 1); motor2.step(1); }
여기서의 두 모터의 속도는 동일합니다.
모터1시간+ 모터2시간 이죠
좀 더 매끄럽게 움직이려면 millis() 함수를 사용해서 시분할 구동하는 법을 공부해보세요
그렇다고 하더라도 모터1과 모터2의 총 스텝 수가 다르므로 간단하지는 않겠습니다.
sims님의 댓글
sims
아직 스텝모터 제어 부분에서 완벽히 해결되지는 않았으나
지금까지 절반 이상의 문제 해결에 도움을 주셔서 정말로.. 감사드립니다..
스텝모터 제어부분에 대해서는 조금 더 공부해 보도록 하겠습니다.