커뮤니티
- 제 목 [로봇 팔 제어 프로젝트] 블루투스 통신을 이용한 6관절 로봇 팔 제어
- 작성자 Dongdon 조회 : 9,991 좋아요 : 0 댓글 : 0
- 작성일 2019-12-09 오후 2:25:40
- 첨부파일 Robot_Arm.zip
-
이번 실습은 이전에 이어오던 로봇 팔 프로젝트에서 더 나아가, 블루투스 통신을 활용한 6관절 로봇 팔 제어를 다루는 실습입니다.
1. 동작 원리
조이스틱 3개의 x축, y축을 활용하여 6개의 서보모터를 블루투스를 통해 작동시킵니다.
조이스틱은 아두이노 Nano와 연결되어 있으며 서보모터는 아두이노 Uno와 연결되어 있습니다
즉, Nano와 조이스틱만 가지고 원격으로 Uno 보드와 연결된 서보모터를 작동시키는 것이 목적입니다.
2. 준비물
제품명 수량 1 아두이노 Uno 1 2 아두이노 Nano 1 3 블루투스 모듈 HC-06 2 4 조이스틱 3 5 서보모터 6 6 BreadBoard 2 7 로봇 팔 프레임 필요한 만큼 8 Wire 필요한 만큼 3. 가이드
(1) 다음과 같이 보드와 조이스틱, 서보모터를 연결합니다.
주의점) 아래 회로에서 서보모터는 약 8V 가량의 추가 전압을 인가해야 동작합니다. 그렇지 않을 경우 전원이 불안정합니다.
(하지만 서보모터의 정격 전압은 약 6V 이기 때문에 8V를 장시간 사용하면 서보모터에 소손이 발생하는 것을 경험했습니다.
따라서 건전지를 사용해서 각 서보모터마다 외부 전원을 인가하는 것을 고려 중이나 아직 해결하지 못 했습니다.
좋은 의견 있으시면 댓글 부탁드립니다 !!)
조이스틱과 블루투스 모듈은 아두이노 보드를 통해 5V를 인가합니다.
블루투스의 TX는 아두이노 보드의 RX와, 블루투스의 RX는 아두이노 보드의 TX와 연결합니다.
(2) 코드는 다음과 같습니다.
< Master> - 아두이노 Nano
조이스틱은 각각 해당하는 Analog 핀에 연결합니다.
블루투스의 Rx는 Digital 핀 2번, Tx는 Digital 핀 3번이므로 위에 언급한 것 처럼 블루투스 모듈과 연결에 주의합니다.
또한, 하나의 블루투스를 통해 6개의 서보모터를 제어해야 하므로, 조이스틱 값과 함께 모터 판별용 상수를 1~6까지 지정합니다.
#include< SoftwareSerial.h> int motor1 = A0; //1번 조이스틱 X축 만을 사용 int motor2 = A2; //1번 조이스틱 Y축 만을 사용 int motor3 = A3; //2번 조이스틱 X축 만을 사용 int motor4 = A4; //2번 조이스틱 Y축 만을 사용 int motor5 = A5; //3번 조이스틱 X축 만을 사용 int motor6 = A6; //3번 조이스틱 Y축 만을 사용 int BLE_RX = 2; //Rx (받는핀 설정) int BLE_TX = 3; //Tx (보내는핀 설정) SoftwareSerial bleSerial(BLE_RX, BLE_TX); //블루투스 통신 설정 void setup() { bleSerial.begin(9600); //bleSerial 블루투스 통신 Serial.begin(9600); //시리얼 모니터 사용 } void loop () { if (( (analogRead(motor1) >= 0)&& (analogRead(motor1) < = 300)) || ((analogRead(motor1) >= 700) && (analogRead(motor1) < =1023)) ) //사용자가 원치 않는 조이스틱의 입력을 막기 위해 범위 지정 { int vrx = analogRead(motor1); // 조이스틱의 입력 값을 받아 vrx로 선언 vrx = map(vrx, 0, 1023, 0, 179); bleSerial.write(vrx); // 앵글 값 전송 bleSerial.write(1); // 모터 판별용 상수 전송 Serial.println(vrx); // 시리얼 모니터에 앵글 값 출력 Serial.println(1); // 시리얼 모니터에 모터 판별용 상수 출력 delay(50); } else if (( (analogRead(motor2) >= 0)&& (analogRead(motor2) < = 300)) || ((analogRead(motor2) >= 700) && (analogRead(motor2) < =1023)) ) //사용자가 원치 않는 조이스틱의 입력을 막기 위해 범위 지정 { int vrx = analogRead(motor2); // 조이스틱의 입력 값을 받아 vrx로 선언 vrx = map(vrx, 0, 1023, 0, 179); // 블루투스는 0~255까지밖에 전송할 수 없으므로 조이스틱의 입력 값을 0~180으로 맵필 bleSerial.write(vrx); // 앵글 값 전송 bleSerial.write(2); // 모터 판별용 상수 전송 Serial.println(vrx); // 시리얼 모니터에 앵글 값 출력 Serial.println(2); // 시리얼 모니터에 모터 판별용 상수 출력 delay(50); } else if (( (analogRead(motor3) >= 0)&& (analogRead(motor3) < = 300)) || ((analogRead(motor3) >= 700) && (analogRead(motor3) < =1023)) ) //사용자가 원치 않는 조이스틱의 입력을 막기 위해 범위 지정 { int vrx = analogRead(motor3); // 조이스틱의 입력 값을 받아 vrx로 선언 vrx = map(vrx, 0, 1023, 0, 179); // 블루투스는 0~255까지밖에 전송할 수 없으므로 조이스틱의 입력 값을 0~180으로 맵핑 bleSerial.write(vrx); // 앵글 값 전송 bleSerial.write(3); // 모터 판별용 상수 전송 Serial.println(vrx); // 시리얼 모니터에 앵글 값 출력 Serial.println(3); // 시리얼 모니터에 모터 판별용 상수 출력 delay(50); } else if (( (analogRead(motor4) >= 0)&& (analogRead(motor4) < = 300)) || ((analogRead(motor4) >= 700) && (analogRead(motor4) < =1023)) ) //사용자가 원치 않는 조이스틱의 입력을 막기 위해 범위 지정 { int vrx = analogRead(motor4); // 조이스틱의 입력 값을 받아 vrx로 선언 vrx = map(vrx, 0, 1023, 0, 179); // 블루투스는 0~255까지밖에 전송할 수 없으므로 조이스틱의 입력 값을 0~180으로 맵핑 bleSerial.write(vrx); // 앵글 값 전송 bleSerial.write(4); // 모터 판별용 상수 전송 Serial.println(vrx); // 시리얼 모니터에 앵글 값 출력 Serial.println(4); // 시리얼 모니터에 모터 판별용 상수 출력 delay(50); } else if (( (analogRead(motor5) >= 0)&& (analogRead(motor5) < = 300)) || ((analogRead(motor5) >= 700) && (analogRead(motor5) < =1023)) ) //사용자가 원치 않는 조이스틱의 입력을 막기 위해 범위 지정 { int vrx = analogRead(motor5); // 조이스틱의 입력 값을 받아 vrx로 선언 vrx = map(vrx, 0, 1023, 0, 179); // 블루투스는 0~255까지밖에 전송할 수 없으므로 조이스틱의 입력 값을 0~180으로 맵핑 bleSerial.write(vrx); // 앵글 값 전송 bleSerial.write(5); // 모터 판별용 상수 전송 Serial.println(vrx); // 시리얼 모니터에 앵글 값 출력 Serial.println(5); // 시리얼 모니터에 모터 판별용 상수 출력 delay(50); } else if (( (analogRead(motor6) >= 0)&& (analogRead(motor6) < = 300)) || ((analogRead(motor6) >= 700) && (analogRead(motor6) < =1023)) ) //사용자가 원치 않는 조이스틱의 입력을 막기 위해 범위 지정 { int vrx = analogRead(motor6); // 조이스틱의 입력 값을 받아 vrx로 선언 vrx = map(vrx, 0, 1023, 0, 179); // 블루투스는 0~255까지밖에 전송할 수 없으므로 조이스틱의 입력 값을 0~180으로 맵핑 bleSerial.write(vrx); // 앵글 값 전송 bleSerial.write(6); // 모터 판별용 상수 전송 Serial.println(vrx); // 시리얼 모니터에 앵글 값 출력 Serial.println(6); // 시리얼 모니터에 모터 판별용 상수 출력 delay(50); } }
< Slave> - 아두이노 Uno
Uno 보드에서는 Nano에서 보낸 조이스틱 값과 모터 판별용 상수에 따라 원하는 모터를 작동시킵니다.중요한 것은 59번째, 81번째 줄의 delay(50);입니다.
블루투스 통신이 빠르게 이루어질 경우 모터가 움직이기 전에 서로 다른 명령을 2~3개를 받아들이게 되고 오동작으로 이어집니다.
따라서 개발 환경에 따라 본인에게 적절한 delay time을 선정하여 모터 제어에 혼선이 생기지 않도록 해야합니다.
#include < SoftwareSerial.h> #include < Servo.h> Servo servo1, servo2, servo3, servo4, servo5, servo6; // 서보 모터용 변수 선언 int angle1, angle2, angle3, angle4, angle5, angle6; // 모터 앵글값 변수 선선 int motor1, motor2; // motor1은 조이스틱 값을 받아오고, motor2는 모터 판별용 변수를 받아온다. #define BLE_RX (2) //Rx (받는핀 설정) #define BLE_TX (3) //Tx (보내는핀 설정) SoftwareSerial bleSerial(BLE_RX, BLE_TX); // 블루투스 통신 설정 void setup() { bleSerial.begin(9600); // 블루투스 통신 시작 Serial.begin(9600); // 시리얼 모니터 사용 servo1.attach(11); // 11번 핀을 서보모터로 지정 servo2.attach(5); // 10번 핀을 서보모터로 지정 servo3.attach(9); // 8번 핀을 서보모터로 지정 servo4.attach(8); // 9번 핀을 서보모터로 지정 servo5.attach(7); // 7번 핀을 서보모터로 지정 servo6.attach(6); // 6번 핀을 서보모터로 지정 angle1 = 90; // 1번 서보모터 앵글 초기 값 설정 angle2 = 90; // 2번 서보모터 앵글 초기 값 설정 angle3 = 90; // 3번 서보모터 앵글 초기 값 설정 angle4 = 90; // 4번 서보모터 앵글 초기 값 설정 angle5 = 90; // 5번 서보모터 앵글 초기 값 설정 angle6 = 90; // 6번 서보모터 앵글 초기 값 설정 } void loop() { if (bleSerial.available()>=2){ motor1 = bleSerial.read(); // motor1에 조이스틱의 값을 받아옴 motor2 = bleSerial.read(); // motor2에 모터 판별용 상수를 받아옴 switch(motor2) // 모터 판별용 상수에 따라 각 서보모터가 동작한다 { //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▼서보모터 1 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--- case 1 : // 모터 판별용 변수가 1인 경우 1번 서보모터 동작 if ((motor1 < = 60) && (motor1 >= 0)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle1 = angle1 - 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle1 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle1 = 20; } if (angle1 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle1 = 150; } servo1.write(angle1); // 모터에 앵글 값을 입력 Serial.println("1번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle1); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } else if ((motor1 < = 179) && (motor1 >= 118)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle1 = angle1 + 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle1 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle1 = 20; } if (angle1 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle1 = 150; } servo1.write(angle1); // 모터에 앵글 값을 입력 Serial.println("1번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle1); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } break; //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▲서보모터 1 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\-- //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▼서보모터 2 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--- case 2 : // 모터 판별용 변수가 2인 경우 2번 서보모터 동작 if ((motor1 < = 60) && (motor1 >= 0)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle2 = angle2 - 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle2 < = 40) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle2 = 40; } if (angle2 >= 120) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle2 = 120; } servo2.write(angle2); // 모터에 앵글 값을 입력 Serial.println("2번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle2); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } else if ((motor1 < = 179) && (motor1 >= 118)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle2 = angle2 + 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle2 < = 40) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle2 = 40; } if (angle2 >= 120) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle2 = 120; } servo2.write(angle2); // 모터에 앵글 값을 입력 Serial.println("2번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle2); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } break; //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▲서보모터 2 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\-- //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▼서보모터 3 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--- case 3 : if ((motor1 < = 60) && (motor1 >= 0)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle3 = angle3 - 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle3 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle3 = 20; } if (angle3 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle3 = 150; } servo3.write(angle3); // 모터에 앵글 값을 입력 Serial.println("3번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle3); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } else if ((motor1 < = 179) && (motor1 >= 118)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle3 = angle3 + 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle3 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle3 = 20; } if (angle3 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle3 = 150; } servo3.write(angle3); // 모터에 앵글 값을 입력 Serial.println("3번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle3); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } break; //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▲서보모터 3 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\-- //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▼서보모터 4 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--- case 4 : if ((motor1 < = 60) && (motor1 >= 0)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle4 = angle4 - 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle4 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle4 = 20; } if (angle4 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle4 = 150; } servo4.write(angle4); // 모터에 앵글 값을 입력 Serial.println("4번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle4); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } else if ((motor1 < = 179) && (motor1 >= 118)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle4 = angle4 + 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle4 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle4 = 20; } if (angle4 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle4 = 150; } servo4.write(angle4); // 모터에 앵글 값을 입력 Serial.println("4번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle4); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } break; //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▲서보모터 4 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\-- //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▼서보모터 5 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--- case 5 : if ((motor1 < = 60) && (motor1 >= 0)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle5 = angle5 - 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle5 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle5 = 20; } if (angle5 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle5 = 150; } servo5.write(angle5); // 모터에 앵글 값을 입력 Serial.println("5번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle5); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } else if ((motor1 < = 179) && (motor1 >= 118)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle5 = angle5 + 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle5 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle5 = 20; } if (angle5 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle5 = 150; } servo5.write(angle5); // 모터에 앵글 값을 입력 Serial.println("5번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle5); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } break; //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▲서보모터 5 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\-- //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▼서보모터 6 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--- case 6 : if ((motor1 < = 60) && (motor1 >= 0)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle6 = angle6 - 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle6 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle6 = 20; } if (angle6 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle6 = 150; } servo6.write(angle6); // 모터에 앵글 값을 입력 Serial.println("6번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle6); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } else if ((motor1 < = 179) && (motor1 >= 118)) // 조이스틱이 움직였을 때만 작동하도록 적절한 범위 선정 { angle6 = angle6 + 2; //로봇팔의 회전속도를 조절하기 위해 실험을 통해 나온 적절한 속도값을 계산하여 구함 if (angle6 < = 20) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle6 = 20; } if (angle6 >= 150) // 과도한 앵글로 인해 버벅이는 현상을 줄이기 위해 범위를 제한 { angle6 = 150; } servo6.write(angle6); // 모터에 앵글 값을 입력 Serial.println("6번 모터"); // 시리얼 모니터에 현재 동작하는 모터를 출력 Serial.println(angle6); // 시리얼 모니터에 앵글 값 출력 delay(50); // 모터 동작을 기다려주는 delay타임 } break; //\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\---▲서보모터 6 제어\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\--\-- } } }
(3) 동작 모습은 다음과 같습니다.
(4) 문제점
위의 동영상에서 보듯이, 모터가 불안정한 점이 가장 큰 문제점입니다.
블루투스가 아닌 기존의 방식을 사용할 때에는 발생하지 않았지만, 동작하지 않아야 하는 모터에 간섭 현상이 발생하거나 모터 떨리는 것을
확인할 수 있었습니다.
이를 방지하기 위해 배선을 다시 연결하거나 delay 타임 조정, 아두이노 보드의 PWM신호에 노이즈 바이패스 캐패시터를 설치하는 등
다양한 시도를 했지만, 여전히 근본적은 해결책은 되지 않았습니다.
추가로, 초반부에 언급했듯이, 서보모터에 인가하는 전압을 최적화하는 방법도 또 다른 문제점 입니다.
좋은 해결 방안이 있으신 분은 아래 댓글에 남겨주시면 감사하겠습니다 !!