[아두이노] Differential Wheeled RC카 만들기 #2-2 "모터 데드존(Deadzone) 테스트"

    데드존(Deadzone)

    모터에서 데드존, 특히 기어 모터에서 데드존(deadzone)은 사전에 테스트를 통해 알아두어야 합니다.

    주변에서 쉽게 찾아볼 수 있는 예로 요새 어디서든 쉽게 찾아볼 수 있는 전동 킥보드가 있습니다.

    저도 전동 킥보드를 거의 4년째 타고 다니고 있는데요, 저는 앞/뒤 휠이 모두 굴러가는 듀얼 BLDC 모터로 각각 1,000W의 힘을 갖고 있습니다.

    조금만 더 버텨라... 20,000km는 타야지 본전 뽑는다...

    모터의 와트가 높고, 듀얼 모터이기 때문에 힘이 매우 좋습니다.

    약 150만원에 주고 구매했습니다.

    구글링으로 찾은 20만원짜리 전동 킥보드

    하지만 30~40만원 대 저가형 모델의 경우 대부분 모터가 1개만 장착되고, 그나마도 매우 힘이 약한 350~500W 정도의 모터를 사용합니다.

    이러한 제품의 경우 탑승자의 몸무게가 많이 나갈 경우, 경사로를 주행해야 하는 경우 등 환경의 제약을 많이 받습니다.

    이러한 경우 어떻게 주행할 수 있을까요?

    바로 '킥 스타트' 방법입니다.

     

    정지 상태에서 몸무게가 무거운 사람이 경사진 곳을 주행하려고 하면 엑셀레이터를 최대로 당겨도 꼼짝하지 않을 겁니다.

    하지만 사실 모터에는 전류가 흐르고 있고, 실제로는 일을 하고 있는 중입니다.

    다만 그 힘이 본인의 payload(=저항)를 출발시킬 힘보다 적을 뿐입니다.

    이때 탑승자가 발로 약간 땅을 구르게 되면 킥보드는 서서히 출발할 수 있을 겁니다.

    하물며 우리가 제어할 모터는 기어 모터이기 때문에 많은 기어가 물려 있습니다.

    우리는 모터를 0~255 사이의 PWM 값을 주어 속도를 제어하지만, 과연 1이란 속도를 낼 수 있을까요?

    모터 크기도 작고, 값 싼 제품이다 보니, 상당히 큰 값을 주어야 회전할 수 있을 거라고 생각합니다.

    이번에는 모터의 데드존을 찾는 테스트를 하기 위한 코드를 준비했습니다.


    코드

    #define motorLeft_EN 3    // Left Motor: ENA(PWM) pin
    #define motorLeft_OUT1 2  // Left Motor: IN1 pin
    #define motorLeft_OUT2 4  // Left Motor: IN2 pin
    #define motorRight_EN 5   // Right Motor: ENB(PWM) pin
    #define motorRight_OUT1 7 // Right Motor: IN3 pin
    #define motorRight_OUT2 6 // Right Motor: IN4 pin
    
    void setup() {
      Serial.begin(19200);
      pinMode(motorLeft_EN, OUTPUT);
      pinMode(motorLeft_OUT1, OUTPUT);
      pinMode(motorLeft_OUT2, OUTPUT);
      pinMode(motorRight_EN, OUTPUT);
      pinMode(motorRight_OUT1, OUTPUT);
      pinMode(motorRight_OUT2, OUTPUT);
    }
    
    void loop() {
      // Left motor test #1
      digitalWrite(motorLeft_OUT1, HIGH);
      digitalWrite(motorLeft_OUT2, LOW);
      for(int count = 0; count < 256; count ++) {
        Serial.print("< LEFT forward >  PWM input: ");
        Serial.println(count);
        analogWrite(motorLeft_EN, count);
        delay(500);
      }
      digitalWrite(motorLeft_OUT1, HIGH);
      digitalWrite(motorLeft_OUT2, HIGH);
      delay(2000);
    
      // Left motor test #2
      digitalWrite(motorLeft_OUT1, LOW);
      digitalWrite(motorLeft_OUT2, HIGH);
      for(int count = 0; count < 256; count ++) {
        Serial.print("< LEFT backward >  PWM input: ");
        Serial.println(count);
        analogWrite(motorLeft_EN, count);
        delay(500);
      }
      digitalWrite(motorLeft_OUT1, HIGH);
      digitalWrite(motorLeft_OUT2, HIGH);
      delay(2000);
    
      // Right motor test #1
      digitalWrite(motorRight_OUT1, HIGH);
      digitalWrite(motorRight_OUT2, LOW);
      for(int count = 0; count < 256; count ++) {
        Serial.print("< RIGHT forward >  PWM input: ");
        Serial.println(count);
        analogWrite(motorRight_EN, count);
        delay(500);
      }
      digitalWrite(motorRight_OUT1, HIGH);
      digitalWrite(motorRight_OUT2, HIGH);
      delay(2000);
    
      // Right motor test #2
      digitalWrite(motorRight_OUT1, LOW);
      digitalWrite(motorRight_OUT2, HIGH);
      for(int count = 0; count < 256; count ++) {
        Serial.print("< RIGHT backward >  PWM input: ");
        Serial.println(count);
        analogWrite(motorRight_EN, count);
        delay(500);
      }
      digitalWrite(motorRight_OUT1, HIGH);
      digitalWrite(motorRight_OUT2, HIGH);
      delay(2000);
    }

    이전 포스트에서 다루었던 모터 방향 테스트 코드에 PWM 값을 주는 부분만 for()문을 사용하여 점점 값을 높여봤습니다.

    정/역회전을 모두 테스트 하도록 코드를 작성했는데 사실 같은 모터라면 회전 방향에 관계없이 거의 같은 PWM 값에서 움직이기 시작할겁니다.

    제 모터는 좌측은 60, 우측은 85에서 동작하기 시작했습니다.

     

    어... 양쪽 모터의 오차가 매우 큰데... 큰일났네요...

    여분으로 섀시 키트를 하나 더 사놓긴 했는데 다시 뜯자니 너무 귀찮아서...

    이 제품은 그냥 테스트용으로 사용하고 다음부터는 좀 괜찮은 모터를 사용해야 할 것 같습니다.

     

    테스트 결과로 제 모터의 가동 범위를 알 수 있게 되었습니다.

      minimum PWM value PWM range
    LEFT motor 60 60~255 (196 step)
    RIGHT motor 85 85~255 (171 step)

     

    이렇게 모터의 데드존을 알아냈습니다.

    이전 포스팅 중 신호 스케일에 대해 다루었던 적이 있습니다.

    2021/02/13 - [로봇] - [아두이노] Differential Wheeled RC카 만들기 #1-3 "신호 스케일링"

     

    [아두이노] Differential Wheeled RC카 만들기 #1-3 "신호 스케일링"

    스케일 (scale) '스케일'이라는 단어를 처음 접하는 사람들에게는 조금 생소할 수 있습니다. 예를 들어 60분을 기준으로 하였을 때, 46분은 0~60분에 대하여 몇 %일까요? (46 / 60) * 100 = 약 77% 입니다.

    conceptbug.tistory.com

    제가 알아낸 데드존을 스캐일링 함수에 그대로 집어넣으면 0~100% 사이의 백분율로 계산된 값이 나오겠죠.

    하지만 양쪽 모터의 최소 PWM 값이 다르기 때문에 같은 백분율의 값이 스케일링 되었더라도 왼쪽 모터의 10%와 오른쪽 모터의 10%는 다르게 됩니다.

    이 때문에 어쩔 수 없이 더 낮은 최소 PWM 값을 가진 왼쪽 모터를 오른쪽 모터에 맞춰야 겠죠.

     

    이렇게 했을 때 큰 단점이 있습니다.

    먼저 힘이 약한 모터를 사용하기 때문에 모터 가동 범위가 매우 좁아졌습니다.

    더구나 양쪽 모터의 값도 비슷하지 않아 더 좁아진 상태죠.

    90이상의 값을 주어야 모터가 굴러가기 시작하는데, 아마 느린 속도를 내기 힘들겁니다..

    정지 상태에서 느린 속도로 출발하려면 먼저 겉으로 티가 안나게 강한 PWM값을 짧은 시간 주고 모터를 돌린 다음에 느린 속도로 가게 하는 방법이 있지만 과연 부드럽게 될지...


    킥 스타트 영상

    글을 마치려다가 '킥 스타트'에 대해 설명을 드리긴 했지만, 실제로 무슨 말인지 모를 수도 있어 영상을 찍어봤습니다.

    제 장난감 기준으로 왼쪽 모터의 최소 PWM값은 60이었습니다.

    이 말은 60 밑으로는 데드존으로 실제로 모터에 전류는 들어가지만, 기어(혹은 부하)를 회전할 힘이 부족하여 발악하고 있는 상태입니다.

    굴러가려고 떼는 쓰고는 있지만 움직이지는 않는...

    기본 코드를 약간 수정하여 왼쪽 모터만 0~70까지의 값을 줘보도록 하겠습니다.

    #define motorLeft_EN 3    // Left Motor: ENA(PWM) pin
    #define motorLeft_OUT1 2  // Left Motor: IN1 pin
    #define motorLeft_OUT2 4  // Left Motor: IN2 pin
    #define motorRight_EN 5   // Right Motor: ENB(PWM) pin
    #define motorRight_OUT1 7 // Right Motor: IN3 pin
    #define motorRight_OUT2 6 // Right Motor: IN4 pin
    
    void setup() {
      Serial.begin(19200);
      pinMode(motorLeft_EN, OUTPUT);
      pinMode(motorLeft_OUT1, OUTPUT);
      pinMode(motorLeft_OUT2, OUTPUT);
      pinMode(motorRight_EN, OUTPUT);
      pinMode(motorRight_OUT1, OUTPUT);
      pinMode(motorRight_OUT2, OUTPUT);
    }
    
    void loop() {
      // Left motor test #1
      digitalWrite(motorLeft_OUT1, HIGH);
      digitalWrite(motorLeft_OUT2, LOW);
      for(int count = 0; count < 70; count ++) {
        Serial.print("< LEFT forward >  PWM input: ");
        Serial.println(count);
        analogWrite(motorLeft_EN, count);
        delay(500);
      }
      digitalWrite(motorLeft_OUT1, HIGH);
      digitalWrite(motorLeft_OUT2, HIGH);
      delay(2000);
    }

     

     

    댓글

    Designed by JB FACTORY