코코아팹은 누구나 창의적 아이디어를 현실로 만들어 낼 수 있도록
만들고, 공유하고, 배울 수 있는 터전이
되고자 합니다.
아이디와 비밀번호를 잊으셨나요?아이디 / 비밀번호 찾기
코코아팹 회원이 아니신가요? 회원가입
2019-10-31 11:42:59
조이스틱(Joystick)은 상하좌우로 자유롭게 움직이는 레버로 상하, 좌우 방향에 대한 정보를 동시에 전달하는 입력장치입니다.
이와 같이 조이스틱은 임의의 방향으로 자유롭게 정보를 전달할 수 있어서 게임기 컨트롤러에 있는 방향키, 카메라 컨트롤러, 비행기 조종 스틱 등 쓰이고 있습니다.
조이스틱은 내부에 2개의 가변저항으로 이루어져 있고 각각 X축과 Y축에 고정되어 있습니다. 조이스틱 레버를 한쪽으로 조이스틱 내부에 있는 X축과 Y축의 가변저항이 변하고 이 변화에 따라 조이스틱 레버의 방향을 확인하게 됩니다.
조이스틱 내부에 있는 가변저항은 아날로그 신호를 사용하므로 X축과 Y축은 각각 0 ~ 1023의 값을 가집니다.
조이스틱 모듈은 오른쪽으로 갈수록 X축 값이, 위로 올라갈수록 Y축 값이 증가합니다.
NO | 부품명 | 수량 | 상세설명 |
1 | 오렌지보드 + 확장보드 | 1 | |
2 | 조이스틱 모듈 | 2 | |
3 | 점퍼 케이블 | 10 | M/M |
부품명 | 오렌지보드 + 확장보드 | 조이스틱 모듈 | 점퍼 케이블 |
파트 |
1. 조이스틱1의 GND핀을 오렌지보드 확장실드 -버스에 연결합니다.
2. 조이스틱1의 +5V핀을 오렌지보드 확장실드 +버스에 연결합니다.
3. 조이스틱1의 VRX핀을 오렌지보드 확장실드 A1에 연결합니다.
4. 조이스틱1의 VRY핀을 오렌지보드 확장실드 A0에 연결합니다.
5. 조이스틱1의 SW핀을 오렌지보드 확장실드 D6에 연결합니다.
6. 조이스틱2의 GND핀을 오렌지보드 확장실드 -버스에 연결합니다.
7. 조이스틱2의 +5V핀을 오렌지보드 확장실드 +버스에 연결합니다.
8. 조이스틱2의 VRX핀을 오렌지보드 확장실드 A2에 연결합니다.
9. 조이스틱2의 VRY핀을 오렌지보드 확장실드 A3에 연결합니다.
10. 조이스틱2의 SW핀을 오렌지보드 확장실드 D7에 연결합니다.
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
|
/*
제목 : 조이스틱 움직이기
내용 : 조이스틱을 움직일 때 해당 위치값을 시리얼 모니터로 확인해봅시다.
*/
// 조이스틱1 X축을 A0번 핀으로 설정합니다.
int X = A0;
// 조이스틱1 Y축을 A1번 핀으로 설정합니다.
int Y = A1;
// 실행시 가장 먼저 호출되는 함수이며, 최초 1회만 실행됩니다.
// 변수를 선언하거나 초기화를 위한 코드를 포함합니다.
void setup() {
// 시리얼 통신 속도를 9600으로 설정합니다.
Serial.begin(9600);
}
void loop() {
// X축과 Y축의 아날로그 데이터를 입력받아 시리얼로 출력합니다.
Serial.print("X : ");
Serial.println(analogRead(X));
Serial.print("Y : ");
Serial.println(analogRead(Y));
delay(500);
}
|
조이스틱 2개를 이용하여 로봇팔의 4개 서보모터를 제어함으로써 로봇팔을 원하는 위치로 움직일 수 있습니다.
1번 조이스틱으로 1번, 2번 모터를 2번 조이스틱으로 3, 4번 모터를 제어하겠습니다.
조이스틱 | 모터 |
1번 X축 | 1번 모터(밑판) |
1번 Y축 | 2번 모터(옆면1) |
2번 X축 | 3번 모터(옆면2) |
2번 Y축 | 4번 모터(집게) |
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
|
#include <Servo.h>
#include <Wire.h>
Servo bottom, foward, height, gripper;
Servo servo[4] = {bottom, foward, height, gripper};
int preVal[4] = {90, 85, 90, 140};
int pin[4] = {8, 9, 10, 11};
void setup() {
for (int i = 0; i < 4; i++) {
servo[i].attach(pin[i]);
}
Serial.begin(9600);
for (int i = 0; i < 4; i++) {
servo[i].write(preVal[i]);
}
}
void loop() {
int Val[4];
for (int i = 0; i < 4; i++) {
Val[i] = analogRead(14 + i);
// 조이스틱 반대방향으로 움직이기(arm1, arm2)
if ( i == 2) {
Val[i] = 1024 - Val[i];
}
moveServo(i, Val[i]);
}
delay(25);
}
void moveServo(byte num, int joy) {
if (joy > 1000) {
preVal[num] += 5;
if (num == 0) {
if (preVal[num] > 150) {
preVal[num] = 150;
}
}
else if (num == 1) {
if (preVal[num] > 150) {
preVal[num] = 150;
}
}
else if (num == 2) {
if (preVal[num] > 180) {
preVal[num] = 180;
}
}
else if (num == 3) {
if (preVal[num] > 140) {
preVal[num] = 140;
}
}
}
else if (joy < 100) {
preVal[num] -= 5;
if (num == 0) {
if (preVal[num] < 30) {
preVal[num] = 30;
}
}
else if (num == 1) {
if (preVal[num] < 40) {
preVal[num] = 40;
}
}
else if (num == 2) {
if (preVal[num] < 30) {
preVal[num] = 30;
}
}
else if (num == 3) {
if (preVal[num] <= 90) {
preVal[num] = 90;
}
}
}
servo[num].write(preVal[num]);
}
|
각 조이스틱 별로 x축, y축의 값이 1000보다 크면 해당 모터의 각도를 올리고, 100보다 작으면 모터의 각도를 내립니다.
1
2
3
|
if ( i == 2) {
Val[i] = 1024 - Val[i];
}
|
|
2번 조이스틱의 X축은 실제 모터와 동작이 반대로 되어야 합니다.
(EX : 2번 조이스틱 X축을 위로 올렸을 때 3번 모터는 실제로 모터 각이 내려가야합니다.)
그래서 2번 조이스틱 X값은 반대로 동작하도록 측정값을 반전시켜 줍니다.(실제 측정값이 0일 때 동작은 1024가 들어오도록)
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
|
void moveServo(byte num, int joy) {
if (joy > 1000) {
preVal[num] += 5;
if (num == 0) {
if (preVal[num] > 150) {
preVal[num] = 150;
}
}
else if (num == 1) {
if (preVal[num] > 150) {
preVal[num] = 150;
}
}
else if (num == 2) {
if (preVal[num] > 180) {
preVal[num] = 180;
}
}
else if (num == 3) {
if (preVal[num] > 140) {
preVal[num] = 140;
}
}
}
else if (joy < 100) {
preVal[num] -= 5;
if (num == 0) {
if (preVal[num] < 30) {
preVal[num] = 30;
}
}
else if (num == 1) {
if (preVal[num] < 40) {
preVal[num] = 40;
}
}
else if (num == 2) {
if (preVal[num] < 30) {
preVal[num] = 30;
}
}
else if (num == 3) {
if (preVal[num] <= 90) {
preVal[num] = 90;
}
}
}
servo[num].write(preVal[num]);
}
|
로봇팔은 각 모터별로 움직일 수 있는 범위가 제한되어 있습니다. (범위 밖으로 모터를 무리해서 움직이면 고장날 수 있습니다.)
각 모터별로 최댓값, 최솟값을 확인 한 후 해당 각도를 벗어나는 움직임이 나올 때 최대값, 최소값을 넘어가지 않도록 조절해주는 부분입니다.
* 조립 결과에 따라 수치가 약간씩 바뀔 수 있으니 직접 각도를 테스트하여 아래처럼 최소값, 최대값을 찾아봅시다.
(밑의 수치는 위 코드 로봇팔 각도에 맞게 적어놓았습니다.)
모터 번호 | 최소값 | 최대값 |
1번 모터 | 30 | 150 |
2번 모터 | 40 | 150 |
3번 모터 | 30 | 180 |
4번 모터 | 90 | 140 |
왼쪽 조이스틱 버튼을 누르면 현재 로봇팔의 각도(모터 4개 각각의 값)을 저장합니다.(최대 10개)
저장된 각도 값이 있을 경우 오른쪽 조이스틱 버튼을 누르면 저장된 모터의 값을 처음부터 차례대로 10번 반복합니다.
kocoafab