프로젝트

나도 메이커! 메이커스 여러분들의 작품/프로젝트를 공유하는 공간입니다.

조이스틱 제어 로봇팔 만들기

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

 

 

부품명 오렌지보드 + 확장보드 조이스틱 모듈 점퍼 케이블
파트

 

 

 

 

 

하드웨어 making


 

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에 연결합니다.

 

 

 

소프트웨어 coding

 

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= {908590140};
int pin[4= {891011};
 
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