메이킹/메이킹 프로젝트

서보모터를 이용한 간단한 로봇 팔 제작기

트리맨스 2020. 3. 4. 23:04
반응형

 

방학때 이것저것 만들어 보겠다던 나의 포부는 역시나 물거품이 되어 사라졌다. 하지만 몇 개 만들어 놓은 것 중 하나가 로봇팔 제작을 해보는 것이였다. 원래의 목표는 다이나믹셀 같은 고성능 모터를 이용하여 제작하는 것이였다. 하지만 다이나믹셀은 제일 저렴한 모터가 하나에 3만원 씩이나 한다. 또한 그에 걸맞는 부품을 장착할려면, 돈이 무지막지하게 들어간다. 그래서 가격을 생각하여 저렴하게 만들 것을 찾다보니, 서보모터를 이용하여 만든 로봇팔을 찾아냈다. 서보모터는 다이나믹셀에 비해서 성능이 매우 떨어진다. 토크도 약하고 수명도 짧다. 하지만 가장 큰 장점은 저렴하다는 것이다. 솔직히 가격 아니면 서보모터는 쓸 일이 없다.

 

 

여하튼 서보모터를 이용하여 간단한 로봇 팔을 제작해보기로 했다. 

 

1. 프레임 가공


로봇팔의 가장 기본이 되는 프레임을 출력해야 한다. 간단하게 제작할 수 있는 로봇팔을 검색하다 보니, MeArm 이라는 이름을 가진 도면이 있었다. 이미 이 로봇팔을 이용하여 교육용 키트도 파는 것처럼 보인다.

 

https://www.instructables.com/id/MeArm-Robot-Arm-Your-Robot-V10/

 

MeArm Robot Arm - Your Robot - V1.0

MeArm Robot Arm - Your Robot - V1.0: We have this available as a kit over on our store or you can cut your own! This is version 1.0 of the build instructions for the MeArm Robot Arm. The MeArm first came to instructables in April 2014 when we claimed a sec

www.instructables.com

 

나는 이 사람의 로봇팔을 프레임으로 쓸 생각이다. 이 사이트에서 로봇팔 도면을 저장한 뒤, 3T (두께가 3mm) 의 아크릴에 출력해준다. 우리 학교에는 레이저 커팅기를 무료로 쓸 수 있어서 아크릴만 장만하면 간단히 인쇄를 할 수 있었다. 파워 80~85퍼센트로 출력하면 한번에 3T 아크릴을 커팅할 수 있었다. 

 

 

2. 서보모터 보정 및 조립하기


사이트에 나온 대로 천천히 조립하면 어려움은 없다. 단 서보모터를 모두 보정해야 한다. 

 

왜냐하면, 서보모터와 프레임을 조립하고 나서 코딩을 할려고 하면, 180 (가용범위는 160도) 의 범위 밖에서 움직이는 일이 분명히 생길 것이다. 완성품을 보고 나서 서보모터의 동작 범위가 어디서부터 어디까지인지 숙지하고, 모터에 0도의 각을 주어서 4개의 서보모터 모두 보정을 시켜 놓는다.

 

 

3. 회로 꾸미기


회로 꾸미기라고 해봤자 어려운 것이 거의 없다. 각 가변 저항은 아날로그 입력 0번~4번까지 연결한다. 또한 서보모터는 정해진 디지털 출력 (나는 4,5,6,7번) 에 장착한 후 1.5v 건전지 4개를 연결했다. 여기서 주의할 것은 테스트를 할 때 아두이노가 컴퓨터에서 공급받는 전력을 쓰면 안 된다는 것이다. 왜냐하면, 노트북  usb에서 나오는 전력은 모터를 구동하기에는 부족한 양이기 때문이다. 서보모터 1개는 잘 돌아갈 수 있으나, 2개 이상 부터는 모터에 공급되는 전력이 부족하여 정상 구동이 되지 않는다. 마찬가지로 가변 저항의 입력도 일정하게 입력이 되지 않는다. 전력을 추가적으로 공급하는 것이 필수적이다.

 

 

 

4. 코딩하기


코딩은 더욱 쉽다. 가변저항의 값을 받은 뒤에 0~180의 값으로 변환한 후에 출력하면 된다. 여기서 주의할 것은 사이드 서보모터 및 손잡이 부분의 서보모터는 각 모터의 한계점이 프레임에 영향을 받아 가동범위가 줄어드니, 가동범위에 벗어나는 무리한 조작이 가해지지 않게 주의한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <Servo.h>
 
//바닥, 팔꿈치, 손목 , 손 4개의 저항 및 모터
 
#define floor_in A0 //입력 부분 순서대로 a0 a1 a2 a3 연결
#define elbow_in A1
#define wrist_in A2
#define hand_in A3
 
#define floor_moter 4 //입력받은 값 모터로 전달 변수 4 5 6 7
#define elbow_moter 5
#define wrist_moter 6
#define hand_moter 7
 
#define green 12
#define yellow 11
#define red 10
 
#define record A6
#define play A5
 
int rfloor[20000]={0};
int relbow[20000]={0};
int rwrist[20000]={0};
int rhand[20000]={0};
 
 
Servo servo_floor; //서보모터를 작동시키는 함수 선언
Servo servo_elbow;
Servo servo_wrist;
Servo servo_hand;
 
int state=-1//-1이면 평상시 1이면 녹화중 0은 재생
 
void record(int f,int e,int w,int h)
{
  static int i=0;
  
  rfloor[i]=f;
  relbow[i]=e;
  rwrist[i]=w;
  rhand[i]=h;
 
  i++;
  if(i>=19999) state=0;
}
 
void play()
{
  static int i=0;
 
  servo_floor.write(rfloor[i]); 
  servo_elbow.write(relbow[i]); 
  servo_wrist.write(rwrist[i]);
  servo_hand.write(rhand[i]);
 
  i++;
  i%=20000;
}
 
void resetrecord()
{
  for(int i=0;i<20000;i++)
  {
    rfloor[i]=0;
    relbow[i]=0;
    rwrist[i]=0;
    rhand[i]=0;
  }
}
 
void setup() {
  pinMode(floor_in,INPUT);
  pinMode(elbow_in,INPUT);
  pinMode(wrist_in,INPUT);
  pinMode(hand_in,INPUT);
 
  pinMode(record,INPUT_PULLUP);  
  pinMode(play,INPUT_PULLUP);   
 
  pinMode(red,OUTPUT);
  pinMode(green,OUTPUT);
  pinMode(yellow,OUTPUT);
  
  servo_floor.attach(floor_moter);
  servo_elbow.attach(elbow_moter);
  servo_wrist.attach(wrist_moter);
  servo_hand.attach(hand_moter);
  
  Serial.begin(9600);
}
 
void loop() {
    
  int f=map(analogRead(floor_in),0,1023,0,160); //맵핑을 통해 0~1023까지의 값을 0~359로 조정
  int e=map(analogRead(elbow_in),0,1023,0,160);
  int w=map(analogRead(wrist_in),0,1023,0,160);
  int h=map(analogRead(hand_in),0,1023,53,111);
 
  int state1=digitalRead(record); //원하는것 : 액티브 하이 스위치
  int state2=digitalRead(play);
 
  if(state2==1&&state==-1) state=0;
  else if(state2==1&&state==0) state=-1;
  else if(state1==1) state*=-1//녹화와 평상시를 왔다갔다
  
 
  if(state==0) play();
  else if(state==1)
  {
    resetrecord();
    record(f,e,w,h);
  }
  else if(state==-1)
  {
     servo_floor.write(f); //입력받은 값을 서보모터로 출력
     servo_elbow.write(e); 
     servo_wrist.write(w);
     servo_hand.write(h);
  }
 
  Serial.print(f);
  Serial.print(" ");
  Serial.print(e);
  Serial.print(" ");
  Serial.print(w); 
  Serial.print(" ");
  Serial.println(h);
 
  delay(10); //시간 조절
}
cs

 

5. 동작 확인하기


동작을 확인해 보자.

 

 

동작이 정상적으로 이루어지는 것을 확인했다. 추후 기능에는 자이로(가속도) 센서와의 연동 및 동작 녹화 기능을 추가해볼 예정이다.

 

반응형