2륜 RC카 원리를 가상시뮬레이터로 실험(아두이노)

in #kr-arduino6 years ago

2륜 RC카 원리를 가상시뮬레이터로 실험(아두이노)



지난 시간에 기본 아두이노 2륜 RC카 조정에 대해서 마무리 했습니다. post로만 아두이노 RC카 설명을 끝내기가 아쉬워서 가상시뮬레이터에서 동일하게 표현하고 코딩도 유사하게 코딩해서 간접적으로나마 체험 할 수 있게 하면 좋을 것 같아서 간단히 가상시뮬레이터에서 회로도를 만들어 보았습니다.

구체적으로 어떻게 표현했는지 설명 하겠습니다.

1. 아두이노 2륜 RC카 회도로


  • 준비물 : L293D 칩 1개, DC Motor 2개, 외부전원, 아두이노우노
  • 내용 : 아두이노 위에 L293D 칩 pin 들을 아두이노우노에 원하는 위치에 연결한다.
  • 참고 : L293D + DC MOTOR 제어 (아두이노)

회로도가 복잡해 보일 꺼에요. 회로도가 이해가 안가신다면 위에 링크 걸린 참고 자료에 가셔서 복습하시면 됩니다.

참고로, 2륜 RC카 Bluetooth를 통해 스마트폰(무선) 조정하기 (아두이노) post의 동작과 동일합니다. 실제로 만들 경우에 동일한 결과가 나오겠지요.

그리고, 이 회로도에서 Bluetooth은 0,1 핀을 사용한다는 가정하에서 진행됩니다. 저번에 설명했듯이 아두이노 내부 시리얼통신 핀을 사용할 경우는 SoftwareSerial 라이브러리가 필요 없습니다. 그냥 상상으로 0,1번핀에 Bluetooth가 연결되었다고 상상하신 후 보시기 바랍니다.

Bluetooth Tx = arduino Pin0
Bluetooth Rx = arduino Pin1

3. Motor 라이브러리 만들기



원래는 Adafruit-Motor-Shield-library 를 인용해서 코딩해야 하는데 해당 부분만 편집하면 좀 문제가 생길 수 있고 해서 지난시간에 이 라이브러리로 실험했던 느낌을 계속 유지하기 위해서 라이브러리에 사용한 함수명만 그대로 인용해서 새롭게 Motor 라이브러리를 만들어 보았습니다.


  • AF_DCMotor motor(3) : M3핀을 DC Motor 제어용으로 사용.
  • motor.setSpeed(200) : 모터 속도
  • motor.run(FORWARD) : FORWARD, BACKWARD, RELEASE 회전 명령

기본 구조가 이렇게 위처럼 되어 있는데 혼동을 피하고 같은 느낌을 계속 유지하기 위해서 위 표현을 그대로 인용 합니다.

#define FORWARD  1
#define BACKWARD 2
#define RELEASE  3

class DCMotor{
 public:
   DCMotor(uint8_t pinA, uint8_t pinB, uint8_t pinC);
   void run(uint8_t);
   void setSpeed(uint8_t);
   private:
   uint8_t motorA, motorB,speedPin;
};

위 처럼 우선 생성자 DCMotor() 함수를 표현 했습니다. 어떤 핀을 Motor로 제어할지 Motor 객체변수를 선언과 동시에 지정해주기 위해서 입니다. 그리고, run(), setSpeed() 함수명을 그대로 인용했네요.

함수들의 로직 코딩을 볼까요.

DCMotor::DCMotor(uint8_t pinA, uint8_t pinB, uint8_t pinC) {
  motorA = pinA;
  motorB = pinB;
  speedPin = pinC;
  pinMode(motorA,OUTPUT);
  pinMode(motorB,OUTPUT);
  pinMode(speedPin,OUTPUT);
}

DCMotor()함수는 private 형으로 선언한 클래스 내부 변수들에 대한 초기화 작업을 수행합니다. 각 pin의 사용 모드도 여기서 초기화 합니다. 사실 클래스 형태로 표현할려면 이런 코딩이 아니라 아두이노 주소번지로 직접 접근하여 좀 더 하드웨어적 코딩을 해야하는데 복잡해 보일 것 같아서 아두이노 함수로 간단히 클래스를 표현했네요. 느낌만 표현한 클래스 입니다. 진짜 만든다면 이렇게 하면 안되고요. 좀 더 하드웨어적 코딩을 해야 합니다. 우리는 즐기기 위해서 하는 것이기 때문에 쉽게 코딩하는게 좋겠죠.

void DCMotor::run(uint8_t key) {
  switch (key) {
  case 1:
    digitalWrite(motorA,HIGH); //전진
    digitalWrite(motorB,LOW);
    break;
  case 2:
    digitalWrite(motorA,LOW); //후진
    digitalWrite(motorB,HIGH);
    break;
  case 3:
    digitalWrite(motorA,LOW); //정지
    digitalWrite(motorB,LOW);
    break;
  default:
    return;
  }
}

run()함수는 key 값은 FORWARD, BACKWARD, RELEASE 값을 말합니다. define으로 정의한 1, 2, 3값에 해당되는 switch()함수를 통해서 해당된 pin을 digitalWrite()함수로 High or Low로 결정하게 됩니다. 이 코딩은 이미 지난 Post L293D + DC MOTOR 제어 (아두이노) 에서 소개 했습니다. 혹시 잘 모르시겠다면 해당 post에 가셔서 한번 읽고 오시기 바랍니다.

void DCMotor::setSpeed(uint8_t speed) {
   analogWrite(speedPin, speed);
}

setSpeed()함수는 Enable Pin으로 값을 출력하는데 PWM Pin을 사용하여 0~255 사이의 아날로그 신호를 출력합니다. speed의 값을 analogWrite()함수로 아날로그 신호를 출력하면 되기 때문에 딱 한줄 명령으로 표현 됩니다.

이렇게 해서 DCMotor 클래스를 간단히 표현 했습니다.

3. 코딩


만든 DC Motor 클래스

  • DCMotor motor1(7,6,5);) : In1, In2, EnablePin
  • motor.setSpeed(200) : 모터 속도
  • motor.run(FORWARD) : FORWARD, BACKWARD, RELEASE 회전 명령

[소스]

#define FORWARD  1
#define BACKWARD 2
#define RELEASE  3

class DCMotor{
 public:
   DCMotor(uint8_t pinA, uint8_t pinB, uint8_t pinC);
   void run(uint8_t);
   void setSpeed(uint8_t);
   private:
   uint8_t motorA, motorB,speedPin;
};

DCMotor::DCMotor(uint8_t pinA, uint8_t pinB, uint8_t pinC) {
  motorA = pinA;
  motorB = pinB;
  speedPin = pinC;
  pinMode(motorA,OUTPUT);
  pinMode(motorB,OUTPUT);
  pinMode(speedPin,OUTPUT);
}
void DCMotor::run(uint8_t key) {
  switch (key) {
  case 1:
    digitalWrite(motorA,HIGH);
    digitalWrite(motorB,LOW);
    break;
  case 2:
    digitalWrite(motorA,LOW);
    digitalWrite(motorB,HIGH);
    break;
  case 3:
    digitalWrite(motorA,LOW);
    digitalWrite(motorB,LOW);
    break;
  default:
    return;
  }
}

void DCMotor::setSpeed(uint8_t speed) {
   analogWrite(speedPin, speed);
}
                 
DCMotor motor1(7,6,5); //L293D Motor Pin과 Enable Pin
DCMotor motor2(9,8,3);

int speed = 200;
                 
void setup() {
  Serial.begin(9600);   
  motor1.setSpeed(speed);
  motor2.setSpeed(speed);
  motor1.run(RELEASE);
  motor2.run(RELEASE); 
}
 
void loop() {
  if (Serial.available()){
    char ch = Serial.read();

    switch(ch){
      case 'w':
            motor1.run(FORWARD);
            motor2.run(FORWARD);
            break;
      case 's':
            motor1.run(BACKWARD);
            motor2.run(BACKWARD);
            break;
      case 'a':
            motor1.run(BACKWARD);
            motor2.run(FORWARD);
            break;
      case 'd':
            motor1.run(FORWARD);
            motor2.run(BACKWARD);
            break;
      case 'z':
            motor1.run(RELEASE);
            motor2.run(RELEASE);
            break;
      case 'm':
            speed+=10;
            if(speed>=250) speed=250;
            motor1.setSpeed(speed);
            motor2.setSpeed(speed);
            break;
      case 'n':
            speed-=10;
            if(speed<=0) speed=0;
            motor1.setSpeed(speed);
            motor2.setSpeed(speed);
            break;
    }         
  }
}

만든 Motor 클래스만 추가되고 setup(), loop()함수는 실제 제작했던 Post 2륜 RC카 Bluetooth를 통해 스마트폰(무선) 조정하기 (아두이노) 와 동일한 소스 입니다.

이렇게 해서 가상시뮬레이터로 회로도를 만들고 코딩도 동일하게 코딩해서 실험할 수 있도록 세팅이 끝났네요.

위 소스에서 실제로 L293D Motor Shield로 제어한다면 해당 라이브러리를 다운 받은 후 객체 선언부분만 형식에 맞춰서 하신 후 setup(), loop()함수는 수정 없이 그대로 사용하면 실제로 스마트폰으로 조정이 가능 합니다.

5. 결과


가상시뮬레이터를 싱행 시킨 후 위 그림처럼 시리얼모니터에서 회전 명령 키값을 전송하면 됩니다. 스마트폰의 역활을 대신하는 것이죠. 0,1번 핀에 Bluetooth Pin을 연결하면 바로 스마트폰으로 제어가 가능합니다.

전진(w)/후진(s), 좌(a)/우회전(d), 정지(z), 속도 증가(m)/감소(n) 의 명령으로 세팅 되어 있고 가상시뮬레이터가 스마트폰으로 상상하고 키값을 입력하여 전송하면 거기에 맞게 가상시뮬레이터에 DC기어모터가 회전을 하게 됩니다.

아래는 테스트 결과입니다.

위 영상이 제대로 식별이 안되신다면 위에 공개회로도를 링크 걸어 놓았어요. 가셔서 실제로 실행 시켜보셔서 확인하시면 됩니다. 시뮬레이더 실행 키 누르고 코딩창 열고 코딩창 하단에 시리얼모니터 아이콘을 눌러서 창을 개방시키고 조정 키값을 입력하시면 회로도의 DC기어모터가 조정 키값에 따른 회전명령을 수행합니다.

마무리


실제로 아두이노 RC카 부품을 구매해서 직접 제작하지 않더라도 간접적으로 이렇게 가상시뮬레이터에서 실험을 할 수 있습니다. 실제로 주행하는 모습은 볼 수 없지만 DC Motor 회전만으로도 간접적으로 회전의 원리를 체험할 수 있습니다.

실험을 하실 때 Post 아두이노 2륜 RC카 주행 패턴 실험 (아두이노) 에서 그림으로 주행 패턴을 설명했는데 그 그림을 보시고 가상시뮬레이터의 DC기어모터 회전을 합쳐진 이미지를 머리속에서 상상하시면서 오늘 post의 내용을 보시면 대충 상상속에서 주행하는 모습이 이미지로 그려질 거라 생각합니다.

이렇게 해서 아두이노 RC카를 만들고 Bluetooth로 무선 조정하고 마무리로 가상시뮬레이터로 표현까지 해서 꽤 긴 Post를 마무리 합니다. 사실 간단하게 이렇게조립하세요. 소스코딩은 이렇게하면 Bluetooth로 조정이 돼요. 하면 1~2일 post 주제로 끝낼 수 있었지만 아두이노 RC카의 만드는 것보다 만드는 과정을 보여드리고 싶었기 때문에 post가 길어졌네요.

마지막으로 아두이노 RC카의 주행 패턴도 알았고 조정하는 방법까지 알았습니다. RC카의 움직임을 원하는 형태로 여러분들은 할 수 있게 되었습니다. 즉, 어떤 상황이 되었을 때 여러분들이 아두이노 RC카를 특정한 패턴의 움직임을 보이도로 설계가 가능하다는 이야기가 됩니다. 쉽게 말해서, 이 의미는 아두이노 RC카를 상황에 맞게 주행할 수 있도록 자율주행 설계가 가능하다는 의미가 됩니다. 예를들면, 아두이노 RC카 앞에 장애물이 발견되면 그 장애물을 피해서 주행을 자동으로 할 수 있게 할 수 있다는 것이죠.

여러분들이 상상력을 어디까지 끌어 올리느냐에 따라서, 아두이노 RC카 자율주행을 단순하게 또는 정교하게 표현을 가능해 집니다. 한번 아두이노 RC카 자율주행에 대해서 상상의 나래를 펼쳐 보세요.

Sort:  

아두이노에 가상 시뮬레이션 프로그램이 있는 모양이네요. 못하는 게 없는 참 쓸만한 보드 같습니다.

아두이노 입문자에게 좋은 가상시뮬레이터이죠.
제 post 맨 상단에 링크를 매일 걸어놓는 저곳이 바로 아두이노 없이 아두이노를 컴퓨터상에서 온라인으로 실험할 수 있는 사이트 거든요.
저도 처음에 아두이노를 입문할 당시 저 사이트에서 실험 한뒤에 실제로 아두이노를 구입해서 실험했어요.
아두이노가 적성에 맞는지 먼저 실험을 온라인상에서 해보고 실제로 도전하면 좋아요.

애휴...요기서도 해메는데 자율주행을 무단행단 변수까지 넣고 계산입력생각하면 현기증이 와욬ㅋㅋㅋ

거창한 자율주행은 아니고요 아두이노 RC카 자율주행은 간단히 아두이노 RC카가 전진하면서 앞에 장애물이나 벽이 발견되면 그걸 피하는 정도의 코딩을 하면 됩니다.
쉽게 말해서 장애물 피하기라고 생각하시면 될 듯요.
단순하게 장애물 피하기는요.

if(초음파센서 장애물거리<10){
   피하기 회전;
}
else{
  전진;
}

이걸로 자율주행 끝!
간단하지요. 어려운게 아니라 그냥 어떤 상황이 되면 전진 주행 중에서 원하는 방향으로 RC카를 움직이게 하면 끝나요.
처음에는 너무 복잡하게 생각 안하셔도 돼요.

짱짱맨 호출에 출동했습니다!!
어뷰저를 잡아주세요!
https://steemit.com/jjangjjangman/@virus707/hayrx

짱짱맨 방문에 감사합니다.
블록체인 정보를 보면 어느정도 가늠은 가능하지만 분쟁을 싫어해서 누구 post가 어쩌다 말하는 자체가 마음이 아프네요.
빛과 어둠이 언제나 공존하고 이 또한 스팀안에서의 또하나의 모습인지라.
다툼의 여지가 있는 곳은 안보고 스팀의 빛만 보고 살아가고 싶어요.

pairplay 가 kr-dev 컨텐츠를 응원합니다! :)

컨텐츠 응원에 감사합니다.

Coin Marketplace

STEEM 0.25
TRX 0.11
JST 0.033
BTC 62777.23
ETH 3059.34
USDT 1.00
SBD 3.81