프로젝트

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

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

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] = 180;
      }
    }
    else if (num == 1) {
      if (preVal[num] > 150) {
        preVal[num] = 130;
      }
    }
    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] = 60;
      }
    }
    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] = 180;
      }
    }
    else if (num == 1) {
      if (preVal[num] > 150) {
        preVal[num] = 130;
      }
    }
    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] = 60;
      }
    }
    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

 

kocoafab