[아두이노] 스위치버턴+Servo Motor 제어

IOT/아두이노|2019. 4. 21. 09:00

[아두이노] 스위치버턴+Servo Motor 제어



어제 조이스틱으로 Servo Motor를 실험을 했는데 포스트를 본신 분들이 그냥 글을 보는거로만 끝내는 것이 좀 그런 것 같아서 조이스틱의 느낌을 스위치 버턴으로 최대한 살려서 비슷하게 가상시뮬레이터에서 테스트를 해 볼 수 있도록 변경을 해 봤습니다. 원리는 동일하고 스위치 버턴 2개로 조이스틱의 좌/우측의 회전 값으로 표현을 했고 스위치 버턴 1개로 조이스틱의 스위치 버턴으로 표현을 해서 총 3개의 스위치 버턴으로 조이스틱의 느낌을 담아 회로도와 코딩을 수정했네요. 위에 공개회로도를 클릭하시면 바로 가상시뮬레이터를 실행 할 수 있는 창이 나오니깐 가상시뮬레이터로 직접 스위치를 눌러 Servo Motor를 회전 시켜보세요. 대충 어떤 느낌으로 회전이 이루어지는지 체험을 하실 수 있습니다. 이제 본격으로 어떻게 표현 했는지 살펴보도록 하죠.

1. 회로도 구성


  • 준비물 : 스위치 버턴 3개, Red LED 1개, 저항 220옴 1개, Servo Motor 1개, 아두이노우노
  • 내용 : Servo Motor핀은 7번에 연결, 스위치 버턴은 3,4,5 번핀에 연결, Red LED은 12번 핀으로 연결


어제 포스팅한 조이스틱 + Servo Motor 회로에서 조이스틱 부분만 스위치 3개로 대신 표현한 회로도 입니다. 나머지는 동일하고 스위치 버턴 3개만 변경 했네요.

3. 코딩


  • 사용함수 : pinMode(), digitalRead(), delay(), servo.attach(), servo.write(), map()
  • 내용 : 스위치 버턴 2개로 Servo Motor를 회전 시키고 나머지 한개로 Red LED를 제어 깜박이게 해보자.

함수

  • pinMode(사용핀, 입/출력모드) : 해당 사용핀을 어떤 모드로 사용할지 결정한다. INPUT_PULLUP모드로 설정(내부저항을 사용할 예정)
  • digitalRead(디지털핀) : 디지털 신호를 읽음(0 or 1)
  • digitalWrite(출력핀, HIGH/LOW) : 출력핀에 HIGH(5V) or LOW(0)를 출력
  • delay(시간값) : 시간값만큼 대기한다.

Servo Motor 함수

#include <Servo.h> 
  • Servo servo : 서보모터 객체 선언
  • servo.attach(서보핀) : 서보 모터에 출력을 담당할 핀 선언
  • servo.write(회전각) : 회전각 만큰 서보모터를 회전 시킴

[ 조이스틱 소스 ]

#include <Servo.h> 

Servo servo;

const int AXIS_X = A0;
const int AXIS_Y = A1;
const int SW_P = 3; 

const int servoPin = 7;
const int redLed = 12;

int m_Angle = 0;
 
void setup() {
  servo.attach(servoPin);
  pinMode(redLed, OUTPUT);
  pinMode(SW_P,INPUT_PULLUP);
}
 
void loop() {
  m_Angle = map(analogRead(AXIS_X),0,1023,0,180);
  digitalWrite(redLed,digitalRead(SW_P));
  servo.write(m_Angle); 
  delay(100); 
  
}

변경 후, 어떻게 코딩이 되었는지 볼까요.

[스위치 버턴 소스]

#include <Servo.h> 

Servo servo;

const int AXIS_X1 = 5;
const int AXIS_X2 = 4;
const int SW_P = 3; 

const int servoPin = 7;
const int redLed = 12;

int m_Angle = 0;

void setup()
{
  servo.attach(servoPin);
  pinMode(redLed, OUTPUT);
  pinMode(AXIS_X1, INPUT_PULLUP);
  pinMode(AXIS_X2, INPUT_PULLUP);
  pinMode(SW_P, INPUT_PULLUP);
}

void loop()
{    
  if(digitalRead(AXIS_X1) == 0){  
    if(m_Angle<180){
      m_Angle=m_Angle+10; 
    }          
  }
  else if(digitalRead(AXIS_X2) == 0){ 
    if(m_Angle>0){
      m_Angle=m_Angle-10; 
    }      
  }
  else{
    digitalWrite(redLed,digitalRead(SW_P));
  }
  servo.write(m_Angle);
  delay(100);
}

pinMode()함수로 두개의 스위치 버턴의 모드를 풀업저항모드로 설정을 했고 loop()함수 내부의 코드가 좀 바뀌었네요.

조이스틱보다 코딩이 좀 길어졌죠. if~else if 문을 사용했습니다. AXIS_X1과 AXIS_X2 로 두개의 변수를 설정해서 방향 스위치를 만들었습니다. AXIS_X1 방향이 정방향이면 AXIS_X2은 역방향이 됩니다.

이제 회전 시킬려면 스위치를 눌렀을 때 상황을 만들어 줘야 합니다. 정방향 스위치를 눌렀는지 역방향 스위치를 눌렀는지를 IF문으로 표현 하면 됩니다. 참고로 내부풀업저항을 이용 했기 때문에 초기 상태는 '1'의 상태입니다. 여기서 스위치를 누르면 '0'의 상태가 됨으로 스위치가 눌렀을 때 '0'인가 라고 IF문에서 체크하면 됩니다.

다음과 같은 코딩으로 표현이 되겠죠.

if(digitalRead(AXIS_X1) == 0) {
    정방향 10도 회전;
}
else if(digitalRead(AXIS_X2) == 0){  
    역방향 10도 회전;
}

이제 두 개의 방향스위치로 해당 스위치를 누르면 10도씩 회전하게 만들려면 m_Angle(각) 변수를 하나 만들어 놓고 이 변수값을 10씩 변화를 주면 됩니다.

  • 정방향 => m_Angle=m_Angle+10;
  • 역방향 => m_Angle=m_Angle-10;

간단하게 이 표현으로 스위치를 눌렀을 때 정방향은 +10이 되고 역방향은 -10이 되도록 위 문장을 코딩을 하면 간단하게 회전 시킬 각을 만들 수 있습니다.

그런데 Servo Motor은 0~180도 회전만 할 수 있습니다. 아무리 스위치 버턴을 눌러도 180도 이상 증가하면 안되고 0도이하로 감소해도 안됩니다.

if(m_Angle<180)  m_Angle=m_Angle+10; 

if(m_Angle>0)  m_Angle=m_Angle-10; 

이렇게 if문으로 각에 대해 제한을 두면 아무리 스위치를 눌러도 180이상 0이하로 m_Angle 값은 더이상 변하지 않게 됩니다.

종합해보면,

  if(digitalRead(AXIS_X1) == 0){  
    if(m_Angle<180) m_Angle=m_Angle+10; 
  }
  else if(digitalRead(AXIS_X2) == 0){ 
    if(m_Angle>0) m_Angle=m_Angle-10;     
  }
    else{
    digitalWrite(redLed,digitalRead(SW_P));
  }

이렇게 방향 스위치를 누르지 않았다면 else 문을 수행하는데 SW_P핀의 스위치가 상태값에 따른 redLed핀의 출력을 만들어 내면 마무리가 됩니다. 그냥 else에서 SW_P핀의 스위치가 눌러졌는지 체크하고 그냥 넘어가는 표현이라고 생각하시면 될 듯 싶네요.
이 부분을 else if()문으로 눌러졌는지 물어 보는 코딩을 해도 되지만 그냥 스위치 상태값으로 LED를 상태를 결정하기 때문에 묻는 조건식은 생략 했네요.

4. 결과


가상시뮬레이터 결과 영상입니다.


이것도 실제로 표현을 해서 어떻게 돌아가는지 돌려봤네요.


마무리


어제는 조이스틱으로 Servo Motor를 제어 했고 오늘은 스위치 버턴으로 같은 느낌으로 Servo Motor를 제어를 해 보았습니다. 뭔가를 표현학 그게 동작하는 모습을 봐야 어떤 느낌인지 이해가 빠를 꺼에요. 원래 Servo Motor 회전 제어를 예전 포스트에서 리모콘으로 조정했던 포스트였습니다. 아마도 Bluetooth 통신 포스트를 할 때도 LED나 Servo Motor를 가지고 제어를 하지 않을까 싶네요. 가장 시각적으로 표현하기 쉬운 부품이니깐요.

아무튼 어제 배운 조이스틱의 내용이 중요하니깐 꼭 조이스틱의 동작 원리를 이해하셨으면 합니다. 그리고 오늘 다룬 내용은 같은 의미로 스위치 버턴이 대신한 응용편으로 복습이라고 생각하시면 될 듯 싶네요.

여러분들도 다른 것을 이용하여 비슷한 동작을 수행하시고 싶으시다면 어떤 부품으로 비슷한 느낌을 표현할 수 있을지 상상의 나래를 펼쳐 보세요.


댓글()

[아두이노] 조이스틱 + Servo Motor 제어

IOT/아두이노|2019. 4. 20. 09:00

[아두이노] 조이스틱 + Servo Motor 제어



조이스틱으로 뭔가를 조정하는 응용 예제로 소개할 만한게 없나 고민하다가 지금까지 포스트 한 것 중에서 찾다가 조정 느낌이 느낄 수 있는 LED로 실험 했다가 그냥 포스트에 올리는 걸 포기했네요. 다른 부품으로 찾다가 Servo Motor를 제어를 해보는게 재밌 소재가 될 것 같고 따로 코딩하는 부분도 별로 없을 것 같아 실험 주제로 결정 했네요. 코딩도 아주 초 간단하게 원리만 표현 했고 지난 시간에 조이스틱 조정기 값을 읽는 것을 배웠으니깐 이제는 그 값을 기준으로 Servo Motor의 Angle을 정하면 되니깐 별로 어렵지 않고 재밌는 포스팅이 될 것 같네요.

자! 그러면 Servo Motor를 조이스틱으로 제어를 해 봅시다.

1. 회로도 구성


  • 준비물 : 조이스틱 1개, Servo Motor 1개, Red LED 1개, 저항 220옴 1개, 아두이노우노
  • 내용 : A0, A1 핀은 x,y 방향 아날로그 신호를 받고 5번핀은 스위치 신호를 받도록 선은 연결하고 7번핀에 Servo Motor 출력핀으로 연결하고 12번핀은 Red LED의 출력으로 사용한다.

[ Fritzing 디자인 ]


회로도를 보시면 좀 복잡해 보일 수 있는데, 조이스틱에서 방향 신호(VRX, VRY)와 스위치 신호(SW) 선만 아날로그 핀과 디지털 핀에 연결 하고, Servo Motor핀과 LED 핀들은 사용하고자 하는 디지털 핀을 선택해서 연결하시면 됩니다. 나머지는 다 전원에 관련된 핀이라 회로도 그림만 좀 복잡해 보이고 선 연결은 어렵지 않습니다.

2. 코딩



함수

  • pinMode(사용핀, 입/출력모드) : 해당 사용핀을 어떤 모드로 사용할지 결정한다. INPUT_PULLUP모드로 설정(내부저항을 사용할 예정)
  • analogRead(아날로그핀) : 아날로그 신호를 읽음(0~1023)
  • digitalRead(디지털핀) : 디지털 신호를 읽음(0 or 1)
  • digitalWrite(출력핀, HIGH/LOW) : 출력핀에 HIGH(5V) or LOW(0)를 출력
  • delay(시간값) : 시간값만큼 대기한다.
  • map(입력값,입력최소,입력최대,출력최소,출력최대) : 입력값이 입력 최소~최대범위가 출력 최소~최대에 매칭되어 출력

Servo Motor 함수

#include <Servo.h> 
  • Servo servo : 서보모터 객체 선언
  • servo.attach(서보핀) : 서보 모터에 출력을 담당할 핀 선언
  • servo.write(회전각) : 회전각 만큼 서보모터를 회전 시킴

설계

조이스틱의 어떤 값으로 Servo Motor를 제어 해야 할까요. X 방향, Y 방향, 스위치 버턴 이 세가지 신호 중에 어떤 것을 사용할까요. 여기서, X, Y 값 중에 하나를 선택하면 됩니다. Servo Motor 한개가 하나의 축 방향이라고 생각하면서 접근하시면 됩니다.

간단히, 저는 X 방향 아날로그 신호로 Servo Motor를 제어 해볼까 합니다.

그러면 조정값을 어떻게 Servo Motor랑 매칭해야 할까요. 한번 생각을 해보세요.

조이스틱이 처음 어떤 상태로 어떤 값을 초기값으로 되어 있나요. 조이스틱의 현재 상태와 현재 신호를 곰곰히 생각 해보시면 그 안에 답이 있습니다. 바로, 조이스틱은 방향 아날로그 신호값이 중앙값으로 처음 시작 합니다. 즉, 0~1023의 아날로그 신호에서 512이라는 중심값이 초기 상태로 아날로그 신호로 시작 합니다.

이때 왼쪽은 0~512 사이가 되고 오른쪽은 512~1023 사이의 값으로 좌우 방향을 나타낼 수 있습니다. 이 원리를 이용하시면 쉽게 해결 됩니다. 512를 기점으로 좌우 신호 값으로 Angle를 표현하면 되니깐요. 여기서 0~1023의 아날로그 신호값에서 0도가 0의 값이 되고 180도는 1023이 되게 하면 중앙값 512은 90도가 되고 이 개념을 가지고 코딩을 하면 됩니다.

그렇게 하면, 처음 시작은 중앙값 512로 Servo Motor은 90도에서 시작하게 되고 아날로그 신호가 0에 가까울 수록 0도에 가까워지고 아날로그 신호가 1023에 가까울 수록 180도에 가까워지겠죠.

여기서, 문제점은 0을 0도로 1023을 180도로 어떻게 표현 할까요. map()함수를 이용하면 됩니다. 은근히 자주 사용하는 함수인데 여기에서도 사용 하네요.

m_Angle = map(analogRead(AXIS_X),0,1023,0,180);

AXIS_X핀의 아날로그 신호값이 0~1023 범위에서 출력 0~180범위에 어느 정도의 위치가 되는지 알아서 해당 값을 찾아주는 함수입니다. 만약, 512값이 입력신호로 들어오면 출력 0~180 범위에서 90이라는 값의 위치하니깐 90이 반환되어 나옵니다. 즉, 입력신호값을 0~180사이의 값으로 자동으로 변환시켜주는 함수인 셈이죠.

이 한줄로 조이스틱의 X방향의 아날로그 신호를 각도로 만들어 낼 수 있겠죠.

 servo.write(m_Angle); 
 delay(100); 

아날로그 신호 512일 때, Servo.write(90)함수로 90도를 Servo Motor가 회전하게 됩니다. delay()함수는 Servo Motor가 충분이 회전할 시간값을 줘야 하기때문에 같이 코딩 해야 합니다. 100은 0.1초인데 더 짧게 하시면 좋겠죠. 그냥 이전 포스트 소스를 가져다가 표현한거라 딜레이 시간은 그냥 뒀네요. 원래 저 값은 특정한 각도로 회전 한뒤에 다시 다른 특정한 각도로 회전할 때까지의 충분한 시간 값인데 조이스틱 조정기에서는 이렇게 큰 시간값은 필요 없습니다. 각도 값 범위가 변화율은 크지 않기 때문에 짧게 시간을 주면 됩니다. 100은 아주 큰 값이지만 조정기로 해본 결과 그냥 사용해도 제 실험에서는 상관 없어서 그냥 뒀네요.

결론은 조이스틱의 X방향 신호값을 읽어와서 map()함수로 각도를 만들어 내고 servo.write()로 각도를 출력하는 코딩으로 딱 두줄이면 조이스틱으로 Servo Motor를 움직이게 할 수 있게 됩니다.

그러면, 전체 소스를 살펴봅시다.

[ 소스 ]

#include <Servo.h> 

Servo servo;

const int AXIS_X = A0;
const int AXIS_Y = A1;
const int SW_P = 3; 

const int servoPin = 7;
const int redLed = 12;

int m_Angle = 0;
 
void setup() {
  servo.attach(servoPin);
  pinMode(redLed, OUTPUT);
  pinMode(SW_P,INPUT_PULLUP);
}
 
void loop() {
  m_Angle = map(analogRead(AXIS_X),0,1023,0,180);
  digitalWrite(redLed,digitalRead(SW_P));
  servo.write(m_Angle); 
  delay(100);   
}

변수가 코딩의 절반을 차지 하네요. 정작 로직 코딩은 몇 줄 안되는 데 말이죠.

  digitalWrite(redLed,digitalRead(SW_P));

서비스 코딩으로 스위치 버턴을 누르면 12번에 연결된 Red LED가 꺼지도록 했네요. 조이스틱 스위치 버턴은 내부풀업저항을 이용하기 때문에 초기값은 '1'이 됩니다. 그래서 전원이 공급되면 Red LED에 불이 들어오게 됩니다. 그리고 스위치를 누르면 '0'의 상태가 되어서 Red LED는 불이 꺼지게 됩니다.

4. 결과




5. 추가 내용


위 실험 코딩은 그냥 조정기의 0~1023값을 단적으로 0~180도로 나눠서 조정한 거라서 실제로 뭔가 조정하거나 정밀 제어 할 때는 사용하지 않는 코딩입니다. 단순히 조정기를 움직일 때 그 움직임 값으로 Servo Motor를 움직이게 한 것 뿐이니깐요.

원래는 조정기에 대한 코딩을 제대로 하실려면은 조정기를 움직일 때에 채터링 문제 또는 조정값의 범위라던가 조정기의 수치에 따른 회전 속도라든가 고려해야할 것이 산더미로 많습니다. 거기에 조종기의 중심값의 보정 작업도 추가 해야 합니다.

이런것들을 다 코딩하면 회전 하나의 동작을 하기 위해서 수십 줄의 코딩으로 늘어나게 됩니다. 배보다 배꼽이 더 커지겠죠. 여기서 배워야할 것은 Servo Motor를 조이스틱으로 회전할 수 있는 기초 원리를 배우는게 목적이기 때문에 간단하게 원리만 전달하는 코딩만 한 것이니깐 여러분들이 실제로 뭔가를 제어할려면 많은 부분을 생각하고 코딩 하셔야 합니다.

그리고, 여러분들이 이 기초를 이해 하셨다면 조정기에 필요한 부분이 뭐가 있을지 생각하고 여러가지 상황들을 제시하고 그 문제를 해결하면서 코딩을 늘려가셨으면 합니다.

마무리


조이스틱으로 Servo Motor를 제어할 수 있게 되었네요. 한개의 Servo Motor를 제어 했지만 여기서 Y방향 값도 같이 적용을 하여 Motor 두개를 사용한다면 어떻게 될까요. x와 y방향으로 평면의 좌표로 이동할 수 있게 됩니다. 3D 프린터나 평면 그림을 그리는 프린트기 같은 걸 만들 수 있겠죠. 여기에 사용되는 Motor는 Stepper Motor로 360도를 회전하는 것을 사용합니다. 어찌 되었든 조정기로 뭔가를 움직이는 물체를 제작 가능해 지겠죠.

마지막으로, 뭔가 로봇 같은 관절 제어 쪽으로 상상력을 발휘해 보세요. 재밌는 상상력들을 많이 해 보셨으면 합니다.

예를들어, 로봇 손가락을 상상해 보세요. 자신의 손을 쫙 펴보세요. 손가락 하나에는 3마디로 구성 되어 있잖아요. 이 각 마디와 마디 사이에는 관절이 있습니다. 이 3개의 관절을 Servo Motor가 대신 한다고 상상을 해보세요. 손을 다시 주먹을 쥐어보세요. 한마디가 구부러질 때 몇도의 각도가 되나요. 각 관절이 90도에 가깝게 꺽기게 됩니다. 그러면 Servo모터로 3개의 관절을 동일하게 angle을 0도에서 서서히 90도에 가깝게 일정한 속도로 회전 시키면 어떻게 될까요. 주먹을 쥐는 형태로 자연스럽게 구브러 지겠죠. 다시 펼 때는 90도에서 서서히 0도로 3개의 Servo모터를 회전 시키면 어떻게 될까요 서서히 손가락을 펴는 모습이 되겠죠.
직접 자신의 손을 주먹을 쥐었다 폈다를 반복하면서 머리속에서 손가락 관절의 각도를 그려 보세요. 그 원리를 깨우치게 되면 로봇 손가락 관절 제어를 할 수 있게 됩니다.

일상의 모습을 보고 우리는 그걸 코딩화 할 수 있습니다. 일상의 모습을 코딩화 하기 위해서는 끊임없이 상상력을 끌어 올려야 하고요. 계속 자신에게 어떤 것을 배우고 다룰 수 있게 되면 다음에 뭘 배우지 보다는 이것을 이용하여 뭘 할 수 있지 하고 2개 이상의 응용할 수 있는 상상력 훈련을 하셨으면 합니다.


댓글()

[아두이노] RC카 장애물 감지시 방향 전환 기초

IOT/아두이노|2019. 2. 22. 11:52

[아두이노] RC카 장애물 감지시 방향 전환 기초



초음파레이더의 원리는 지난 시간에 기초 실험으로 살펴 보았습니다. 하다보니깐 RC카 자율주행할 때 초음파 센서로 장애물 감지을 할 경우가 문득 떠오르더군요. 그래서 초음파레이더 만들기 소스를 그대로 이용하여 몇부분만 추가하여 코딩을 완성했습니다. 그냥 갑자기 떠오른 생각이라서 코딩은 깔끔하지 않네요. 막 떠오르는데로 코딩한거니 그 점을 감안해서 코딩을 보시기 바랍니다.

1. 회로도 구성


  • 준비물 : 서보모터 2개, 초음파센서 1개, 아두이노우노
  • 내용 :45~ 125도 서보모터를 회전시키면서 초음파센서로 거리를 측정부분은 그대로 유지한 상태에서 RC카 앞바퀴 방향 제어용 서보모터를 추가하자.


머리속에서 각 부품을 실제 RC카에 배치를 상상해 보세요. 첫번째 초음파센서가 서보모터에 부착되어 있고 두번째 서보모터는 RC카 앞바퀴에 연결되었다고 상상 해보세요.

3. 코딩


  • 사용함수 : attach(사용핀), write(각도), pulseIn(입력핀, HIGH), Serial.begin(9600), Serial.print(출력값),Serial.println(출력값)
  • 내용 : 간단히 서보모터가 회전은 45~125도 범위를 잡고 전방의 장애물 탐지를 초음파센서가 담당하게 코딩하고 앞바퀴담당 서보모터는 거리 50이하 일때 전방 90도 기준으로 좌측에 장애물 발견시 우측으로 우측 장애물 발견시 좌측으로 회전시키는 코딩을 한다.

설계

앞바퀴 방향 제어를 하기 위해서 서보모터를 제어해야겠죠.

그래서 서보모터 객체를 하나 더 선언합니다.

Servo servo2;

그리고 핀을 10번을 사용하기 위해서 연결합니다.

int servoPin2 = 10;
servo2.attach(servoPin2); //angle (0~180)

앞바퀴 장애물 방향전환 조건문을 만듭니다.(하나의 패턴으로 자율주행 첫단추로 접근하는 시작 코딩)

  if(m_distance<=50 && m_angle>90) {    
    servo2.write(45);
    delay(50);   
  }
  else if (m_distance<=50 && m_angle<90){
    servo2.write(125);
    delay(50);   
  }
  else {
    servo2.write(90);
    delay(50);   
  }
  if(m_distance<=50 && m_angle>90) {    

if조건문

  • 첫번째 조건식 : "장애물(벽) 거리가 50cm 이하이고 각도가 90도 보다 큰가?" (왼쪽장애물확인)
    그러면 왼쪽 장애물이 너무 가까우니깐 오른쪽으로 핸들을 꺽어야 겠죠.
  • 두번째 조건식 : "그게 아니면 장애물(벽) 거리가 50cm 이하이고 각도가 90도보다 작은가?"(오른쪽장애물확인)
    그러면 오른쪽 장애물이 너무 가까우니깐 왼쪽으로 핸들을 꺽어야 겠죠.
  • 거짓이면 : 그냥 앞바퀴 방향각 90도로 정중앙 정면을 향하게 한다.

즉, 조건식으로 50cm이하일때 현재 방향에 따른 핸들의 방향을 결정하게 됩니다. 50cm이하에 장애물이 없으면 그냥 정면으로 계속 진행하도록 로직을 짜봤습니다.
여기서 핸들 각도를 변수로 빼면 중복되는 코딩이 3번 반복되는데 이걸 하나로 줄일 수 있겠지만 우선은 동작을 좀 더 직관적으로 이해할 수 있도록 하기 위해서 수정은 안했습니다.

초음파레이더 소스와 위에 방향전환 로직을 합쳐서 전체코딩을 을 살펴보면

#include <Servo.h>

Servo servo1;
Servo servo2;
int servoPin1 = 9;
int servoPin2 = 10;
int m_distance=0;
int m_angle=45;
int m_chk=0;

void setup() {
  Serial.begin(9600);
  servo1.attach(servoPin1); //angle (0~180)
  servo2.attach(servoPin2); //angle (0~180)
}

void loop() {
  
  //초음파센서 몸체 회전
  servo1.write(m_angle);
  delay(50);
  
  m_distance=CalDistance(7);  //초음파센서로 거리계산함수   
  Serial.print("d : ");
  Serial.println(m_distance);
  
  //앞바퀴 장애물 방향전환
  if(m_distance<=50 && m_angle>90) {    
    servo2.write(45);
    delay(50);   
  }
  else if (m_distance<=50 && m_angle<90){
    servo2.write(125);
    delay(50);   
  }
  else {
    servo2.write(90);
    delay(50);   
  }
  
  //초음파센서 회전각
  if(m_chk==0){
    if(m_angle<125)m_angle+=1;
    else m_chk=1;
  }
  else{
    if(m_angle>45)m_angle-=1;
    else m_chk=0;
  }
  
}

int CalDistance (int Pin){  //초음파센서(3핀) 예제를 그대로 외부함수로 빼냄
  pinMode(Pin,OUTPUT); //출력모드로  사용
  digitalWrite(Pin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(Pin,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(Pin,LOW); 
  
  pinMode(Pin,INPUT);    //입력모드로 사용
  int duration = pulseIn(Pin, HIGH);
  
  int distance = duration / 57.5;  //가상시뮬레이션의 오차율을 줄이기 위해 이걸로 테스트 함.

  return distance; //거리값 리턴
}

5. 결과


설계과정은 이번에 생략하고 결과만 시뮬레이터로 돌려 보는 장면만 보여 드립니다. 지난시간에 회로도 만드는 과정을 해봤으니 구지 중복해서 다시 똑같은 것을 찍을 필요는 없고 서보모터만 하나 추가했기 때문에 결과만으로 충분해서 회로도 배치과정은 생략했네요.

마무리


오늘은 아두이노 RC카에 주행에 관한 첫 단추인 방향전환에서 하나의 패턴을 기초 패턴으로 로직을 만들었습니다. 이걸로 주행이 가능하지 않습니다. 단지 이렇게 코딩해 놓고 조금씩 패턴을 늘리고 로직을 늘려가야 합니다.

여기서는 단적으로 왼쪽 장애물 감지시 레드존에 들어가고 바로 오른쪽으로 45도 회전을 시켜서 그린존으로 탈출하는 코딩입니다. 어떤 문제가 있을까요 바로 현재 RC카의 주행 속력에 대한 장애물과의 거리별로 방향전환 각도를 가변적으로 해야합니다. 그래야 매끄렇게 회전이 됩니다. 그리고 또 문제는 가령 전방 직선도로로 달릴때 통과 할 수 공간이 충분하지만 가력 왼쪽이나 오른쪽 방향에 장애물이나 벽과의 거리가 50 이하면 그냥 방향핸들을 반대 방향으로 꺽어버리는 문제가 방생합니다. 즉, 전방에 안전거리 확보가 확인되면 그상태로 주행하고 안전거리가 미확인시 좌우측에 위험거리가 감지되면 방향을 전환하더록 로직을 수정해야겠죠.

이렇게 주행에서의 문제들을 하나씩 찾아내고 그걸 해결하는 패턴들을 하나씩 만들어 내야합니다. 그래야 자율주행이 가능해지는 것이죠. 다른 방식으로 장애물 감지되면 그상태에서 주행이 정지되고 안전거리 확보 패턴로직 주행을 하고 다시 안전거리가 확보되면 주행을 다시 시작하는 방식으로도 변경할 수 있겠죠.

코딩을 쉽게 하기 위해서는 실제 장난감 자동차를 방에서 손으로 밀면서 주행을 시켜보세요 그리고 관찰하면 이런 상황일때 이걸 어떻게 어떻게 빠져나올지 손으로 자동차를 움직이시고 그 움직을 잘 기억했다가 그 움직이는 동작 패턴을 코딩화 하시면 됩니다.

암튼 집에 굴러다니는 장단감을 가지고 한번 손으로 밀면서 띠따! 빵빵! 하면서 가지고 노세요. 그리고 나서 그 움직임을 기역했다가 코딩을 상상해보세요.


댓글()

[아두이노] 초음파레이더 만들기(기본동작제어)

IOT/아두이노|2019. 2. 21. 10:16

[아두이노] 초음파레이더 만들기(기본동작제어)



이번시간에 초음파레이더를 기본동작 원리를 실험하는 시간을 갖도록 하겠습니다. 가장 많이 검색되는 주제이기도 하죠. 현재 초음파센서가 없는 관계로 실제 구동 장면은 추가하고 싶었는데 아쉽게 못 보여 드리네요. 그래도 가상시물레이터에서 충분히 표현이 되니깐 실제 만드는 것은 그리 어렵지 않을꺼에요. 물론 거리계산에 따른 오차율 보정 작업이 필요하지만요. 오늘은 서보모터를 회전시키면서 초음파센서로 거리를 측정하고 그 값을 아두이노 IDE 시리얼모니터로 거리 값이 동시에 출력되게 표현 함으로 초음파레이더의 기본 원리를 배워보도록 하죠.

1. 초음파센서 복습


제 블로그에서 정리할 때 함수로 표현했었습니다. 초음파센서로 거리를 측정하는 로직을 따로 외부함수로 만든 것을 그대로 인용해서 적용하겠습니다.int distance = duration / 57.5; 이것은 가상시뮬레이터에 대충 거리를 보정한 값이고 실제로는 공식을 해보고 거리값의 오차가 있으면 약간씩 값을 바꾸면서 거리값을 보정하시면 됩니다.

  • 공식 : ((float)(340 * duration) / 10000) / 2; (340은 초음기종에 따라 달라질 수 있는점 참고)
int CalDistance (int Pin){  //초음파센서(3핀) 예제를 그대로 외부함수로 빼냄
  
  pinMode(Pin,OUTPUT); //출력모드로  사용
  digitalWrite(Pin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(Pin,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(Pin,LOW); 
  
  
  pinMode(Pin,INPUT);    //입력모드로 사용
  int duration = pulseIn(Pin, HIGH);
  
  int distance = duration / 57.5;  //가상시뮬레이션의 오차율을 줄이기 위해 이걸로 테스트 함.

  return distance; //거리값 리턴
}

이렇게 함수로 만들어 놓으면 나중에 초음파센서를 사용할 때 이 함수를 복사하시면 되겠죠. 이건 3핀 초음파센서여서 사실 4핀 초음파센서에서는 TRIG, ECHO핀이 따로 존재하기 때문에 setup()함수에서 각 핀을 선언해주시면 되기 때문에 CallDistance()함수에서 핀의 출력/입력모드를 선언할 필요가 없습니다. 가상시뮬레이터에서는 3핀이여서 어쩔 수 없이 추가된 것이기 때문에 실제로 1200원 짜리 4핀 초음파센서를 사용하시면 핀모드 선언을 지워주셔서 함수를 사용하시면 됩니다.
쏘는것은 TRIG, 받는 것은 ECHO 핀인 것만 기억하시면 쉽게 변경되시겠지요. 즉, 3핀 초음파센서에서 출력모드일 때 TRIG이고 입력모드일 때 ECHO라고 생각하시면 됩니다.

2. 서보모터 복습


#include <Servo.h>
 
 Servo servo;
 int servoPin = 9;
 
 servo.attach(servoPin); //angle (0~180)
 servo.write(m_angle);
 delay(50);
 
 m_angle+=1; or m_angle= m_angle+1;

9번핀을 servo모터의 출력핀으로 연결하고 servo.write()로 각도(angle)만큼 이동하는데 마지막 라인의 m_angle은 +1씩 증가합니다. 즉 0도에서 1도씩 계속 servo모터를 회전하게 되는 것이죠. 딜레이시간은 1도여서 아주 짧게 0.05초를 줬습니다.

3. 회로도 구성


  • 준비물 : 서보모터 1개, 초음파센서 1개, 아두이노우노
  • 내용 : 0~180도 서보모터를 회전시키면서 초음파센서로 거리를 측정해보자.


가장 간단한 회로도 입니다. 대충 회로도를 보시고 해당 위치의 핀에 선을 연결하시면 됩니다.

4. 코딩


  • 사용함수 : attach(사용핀), write(각도), pulseIn(입력핀, HIGH), Serial.begin(9600), Serial.print(출력값),Serial.println(출력값)
  • 내용 : 간단히 0~180의 범위를 1도씩 회전하면서 초음파로 거리를 측정하여 아두이노시리얼모니터에 거리값을 출력한다.

설계는 위의 1, 2에서 복습 차원의 코딩을 그대로 사용했습니다. 중요한 것은 0에서 180도 까지 1도씩 회전시키고 다시 180에서 0도까지 1도씩 회전하는 것이죠.

설계

(1) 제어 변수를 만든다.

Servo servo; 
int servoPin = 9;

int m_distance=0;
int m_angle=0;
int m_chk=0;
  • servo : 서보클래스 객체 선언
  • servoPin : 서보모터 제어하는 핀번호
  • m_distance : 거리 계산값(초음파센서로 거리측정동작을 수행하는 CalDistance()함수로 구한 값이 저장)
  • m_angle : 서보모터의 회전각(write()함수로 서보모터를 실제 회전)
  • m_chk : 회전 방향 상태값(초기값 0은 0에서 180도로 회전을 뜻하고 1은 180도에서 0도로 회전을 뜻한다.)

(2) m_chk 변수가 회전 방향 상태를 나타내고 제어하는 방법

if(m_chk==0){
    if(m_angle<180)m_angle+=1;
    else m_chk=1;
  }
  else{
    if(m_angle>0)m_angle-=1;
    else m_chk=0;
  }

if 조건문으로 m_chk변수의 초기값이 0이다 m_angle(각)도 0도이다. 조건식이 m_chk==0 으로 m_chk가 0과 같은가 아닌가로 물어본다. 두가지 패턴으로 분리되는 순간이다. 0가 같다면 참인문장이 1이면 거짓문장이 수행 되겠죠. m_chk변수가 초기값으로 0임으로 참이 된다. 그 안에 다시 if문으로 m_angle(각)이 180도보다 작은가가 조건식이 걸려있다. 180도보다 작으면 m_angle+=1;로 m_angle=m_angle=+1과 같은 문장이다. 즉, m_angle(각)은 1도ㅀ 증가하게 된다. 그런데 만약에 m_angle(각)가 180도 이상이 되면 else 이하 문장이 수행됩니다. m_chk=1로 회전 방향 상태값이 바뀌게 됩니다. 그러면 다음 루프때 if 조건문 m_chk가 0이 아니기 때문에 else 이하 문장이 수행되고 반대로 m_angle 변수가 0보다 크냐고 붇고 크면은 m_angle-=1로 -1도로 감소하게 된다. 위 코딩하고는 반대 동작을 수행하는 것이죠.

다시 종합해서 설명하자면 m_chk변수 기준으로 0이면 m_angle 값이 180도가 될때까지 1씩 증가하고 180도가 되면은 m_chk변수를 1로 변경하고 m_chk변수가 1이면 m_angle 값이 0도가 될때까지 -1씩 감소하게 된다. 그리고 0도가가 되면 m_chk변수를 0으로 변경한다. 이렇게 무한 반복하게 되는 로직입니다.

(3) 결과는 아두이노 IDE 시리얼모니터로 출력

Serial.begin(9600);

Serial.print("d : ");
Serial.println(m_distance);

begin(9600)은 setup()함수에 선언하고 나머지 모니터 출력은 print(출력값)와 printIn(출력값)함수가 있는데 print()은 출력값을 출력하고 새로운 라인으로 넘어가지 않고 현재 라인에 머문다. printIn()은 출력값을 출력한뒤에 새로운 라인으로 넘어가라는 의미 입니다. 문서 장성할 때 키보드 Enter 명령으로 생각하시면 됩니다. C언어에서는 '\n'로 생각하시면 됩니다.

Serial.print("d : ");
Serial.println(110);

결과 => d : 110

대충 의미를 이해하셨겠죠.

코딩을 하면

#include <Servo.h>

Servo servo; 
int servoPin = 9;
int m_distance=0;
int m_angle=0;
int m_chk=0;

void setup() {
  Serial.begin(9600);
  servo.attach(servoPin); //angle (0~180)
}

void loop() {
  servo.write(m_angle);
  delay(50);
  
  m_distance=CalDistance(7);  //초음파센서로 거리계산함수   
  Serial.print("d : ");
  Serial.println(m_distance);
    
  if(m_chk==0){
    if(m_angle<180)m_angle+=1;
    else m_chk=1;
  }
  else{
    if(m_angle>0)m_angle-=1;
    else m_chk=0;
  }
}

int CalDistance (int Pin){  //초음파센서(3핀) 예제를 그대로 외부함수로 빼냄
  pinMode(Pin,OUTPUT); //출력모드로  사용
  digitalWrite(Pin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(Pin,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(Pin,LOW); 
  
  
  pinMode(Pin,INPUT);    //입력모드로 사용
  int duration = pulseIn(Pin, HIGH);
  
  int distance = duration / 57.5;  //가상시뮬레이션의 오차율을 줄이기 위해 이걸로 테스트 함.

  return distance; //거리값 리턴
}

5. 결과


가상시뮬레터에서 실험 결과는 깔끔하게 나왔는데 실제 표현에서는 보정 작업이 꼭 필요 합니다.

그리고, 원래 실제로 초음파레이더를 만든다면 그래픽작업으로 레이더를 만들어 레이더에 검색된 물체를 현재회전각과 거리값으로 (x,y)의 좌표를 구할 수 있고 그걸 그래픽작업한 모니터에 원하는 형태로 그래픽모양을 출력하면 좀 더 그럴싸해 지겠죠.

여기에서는 단지 아두이노 IDE 시리얼모니터에 거리값만 출력했습니다. 그게 기본 초음파레이더의 정보입니다. 서보모터의 각도와 거리만 있으면 측정된 물체의 (x,y) 좌표를 구할 수 있고 그것을 프로세싱이나 스크래치로 이미지화 하면 보기가 더 좋겠지만 핵심은 그게 아니로 회전과 거리 측정을 동시에 수행한다는 것에 있습니다. 이미지 시각화를 단지 보여주는 부수적인 효과일뿐이죠. 동영상을 보시고 서보모터가 회전하면서 시리얼모니터에 초음파 센서의 거리가 측정되어 출력되는 걸 잘 보시고 상상을 해보세요. 서보모터에 초음파센서가 부착되어 회전되는데 그 회전하는 각도에 정면의 물체와의 거리를 측정하는 모습을요. 그러면 아마 대충은 이해가 되실 꺼에요.

마무리


간단히 초음파레이더의 기본 로직만 설명했습니다. 그리고, 오늘 포스팅한 코딩은 사실 정교한 제어라고 할 수 없습니다. 왜냐면 서보모터 종류에 따라 좀 다르게 회전이 되는 경우가 있습니다. 참고로 코딩에서 servo.attach(servoPin, Min, Max)로 범위를 설정하고 servo2.writeMicroseconds(각도시간값)으로 제어하시면 더 정교하게 제어가 가능할꺼에요. 실제로 테스트 할때는 위 방식대로 해보다가 안되면 이 방식으로 바꿔서 서보모터의 각도를 제어하시면 됩니다. 4핀이였으면은 현실 4핀 서보모터랑 동일해서 더 편했을텐데 3핀 초음파센서여서 약간 코딩이 아쉽습니다.

추가로 스크래치나 프로세싱 프로그램을 다룰 수 있는 분이라면 그걸 통해서 초음파레이더에 그래픽처리를 통해 실제 레이더처럼 표현이 가능할 꺼에요. 프로세싱을 제대로 공부한적이 없고 잠깐 맛보기로 함수만 몇개 써본게 전부라 프로세싱 프로그램을 사용하여 레이더 그래픽효과를 다음편에 추가해서 보여주고 싶긴 하는데 할까 말까 고민되네요. 잠깐 프로세싱에서 레이더 표현 그래픽 함수 몇개만 공부해서 로직을 짜면 되기는 한데 프로세싱을 새로 설치하고 공부하기가 좀 귀찮아서 생략할지 아니면 표현을 할지 고민을 해 봐야 겠네요.

오늘의 포스팅의 내용은 서모모터회전을 하면서 초음파센서로 거리를 측정한다 이것만 머리속에 넣으시면 됩니다.


댓글()

[아두이노] Servo.h 없이 직접 서보모터를 회전

IOT/아두이노|2019. 2. 20. 13:38

[아두이노] Servo.h 없이 직접 서보모터를 회전



이번에 서보모터의 단순히 전원 공급으로만로 회전을 시켜보는 걸 해보겠습니다. 이것도 오래전 Servo.h 없이 제어를 할 수 있는 방법이 없을까 하고 고민을 좀 했었습니다.
https://github.com/esp8266/Arduino/blob/master/libraries/Servo/src/Servo.h 에서 Servo 클래스에 대해 분석도 하고 했지만 너무 복잡하더군요. 그냥 단순 제어를 해볼려고 조사하다가 전기 신호 파형에 따라 각도를 제어할 수 있다고 해서 digitalWrite()함수 하나로 제어하는 실험을 하게 되었습니다. 혹시 서보모터의 원리를 보다 자세히 알고 싶다면 구글링 서보모터원리라는 단어로 하시면 쉽게 찾을 수 있을거에요. 이번 실험은 전류를 서보모터에 보내고 펄스 간격을 시간값으로 해서 쪼개서 전류공급과 차단을 하면 서보모터의 회전을 시키는 실험으로 진행됩니다. 그리고 이전에 포스팅한 Ardunio min = 544, max=2400 값을 기준으로 이번에 가상시뮬테이의 회전 실험을 해보도록 하죠. 제 블로그의 있던 소스를 그대로 가져와서 실험 포스팅을 하도록 하겠습니다. 고치자니 귀찮니즘이 밀려와서 구지 고칠 필요가 없다고 생각되어 그냥 소개합니다.
그리고 가상시뮬레이터에서 실험하던 당시 서보모터가 다른 기종이여서 min=1000, max=2000을 기준으로 회전시켰지만 이번 실험은 544~2400 값으로 해서 회전이 되는 서보모터를 사용하여 기준은 544~2400으로 실험했습니다.

1. 서보모터의 회전 이해


구글링 검색하시면 서보모터 원리에 대해서 자세히 소개되어 있는데 그냥 아래의 그림처럼 단순하게 생각하시고 넘어가시면 됩니다. 전기 신호는 일정한 간격으로 해서 아래와 같은 파형을 만들어 냅니다. 전류가 공급되고 차단하는 그 시간차 값으로 서보모터의 각도를 만들어 낸다고 가단히 생각하세요. 전류 공급(5V)가 짧은 간격으로 공급된다면 회전하는 각이 그 시간만큼만 회전한다고 생각하면 됩니다.


파형을 아두이노에서 만든다면( Ardunio min = 544, max=2400 값을 기준)

   digitalWrite(servoPin, HIGH);  
   delayMicroseconds(1500);     
   digitalWrite(servoPin, LOW);   
   delayMicroseconds(펄스간격남은값);   

즉, 서보모터 핀에 HIGH(5V)의 전류를 1500마이크로초 동안 전류를 공급하고 LOW(0)로 전류를 차단을 펄스간격남은값(max-회전시간값)만큼이란 표현입니다. 현실 구동은 스피드하게 회전하지 않겠지만 가상시뮬레이터에서 저리 코딩하면 순간 90도정도의 각도로 회전해버립니다. 가상시뮬레이터에서 서보모터라이브러리에서 제공되는 함수와 비슷하게 회전을 보여줄려면은 대충 delay()함수로 시간을 좀 더 크게 대기시켜서 보면은 최대한 비슷하게 회전합니다.

대충,

void setup() {
  pinMode(9, OUTPUT);
}
void loop() {
   digitalWrite(9, HIGH);  
   delayMicroseconds(1500);     
   digitalWrite(9, LOW);   
   delayMicroseconds(2400-1500);   
   delay(100);
}

이정도만 코딩해서 아래 회로도 디자인한 곳에다 코딩을 넣어보세요. 1500시간값만큼의 각도까지 움직이다가 그 각도에서 덜덜덜 떨고 있을꺼에요. 정상적으로 동작되는걸 보실꺼에요

여기서 펄스간격남은값 2400-1500으로 해서 펄스 간격을 일정하게 만들었습니다. 그냥 아두이노의 최대값 2400을 펄스간격 기준값으로 설정했네요. 펄스간격 기준값 2400을 기준으로 얼마만큼의 시간이 5V와 0V가 되었는지의 시간입니다. 그래서 1500만큼의 전류가 공급되었으니 나머지 시간은 LOW에 할당해야겠죠.

쉽게말해서, 회전 파형을 만든다고 생각하시면 됩니다. 구지 자세히 생각하지 마시고요. 이런게 있다는 정도만 이해하시고 오늘 포스팅을 깊게 이해하실 필요 없습니다. 그냥 Servo 라이브러리 파일이 오픈소스로 제공되는데 구지 힘들게 만들 필요는 없겠죠. 이렇게 만들었다고 해서 정교한 컨트롤은 되지 않으며 단지 이런식으로 회전이 이뤄지는 거구나 정도용이니 깊게 생각하지 마세요.

2. 회로도 구성


  • 준비물 : 서보모터 1개, 아두이노우노
  • 내용 : 서보모터 회전 시키자


서보모터는 Vcc(5V), Gnd, Signal(입력신호)로 3핀이로 구성되어 있고 아두이노에서 Signal핀에 신호를 보냄으로써 각도를 제어는 지난시간과 동일합니다.

3. 코딩


  • 사용함수 : pinMode(사용핀, 모드), digitalWrite(사용핀, 상태), delayMicroseconds(시간값), delay(시간값)
  • 내용 : 간단히 180도 회전만 시키자.

설계

우선 delayMicroseconds() 함수를 사용한 목적은 서보모터를 회전시킬 시간값이고 지연시간도 이 함수로 사용했습니다. 그리고 0~180도까지 회전이 끝나면 delay()로 1초동안 잠시 대기는 목적으로 사용합니다.

그리고 digitalWrite()함수를 사용하기 위해서는 pinMode()함수로 핀모드를 설정해야 합니다. 그리고 digitalWrite()함수로 서보모터에 신호값으로 전류 공급과 차단으로 전기신호파형을 만들어 특정 각으로 회전시킵니다.

코딩을 하면

int servoPin = 9;
int m_max=2400;

void setup() {
  pinMode(servoPin, OUTPUT);
}

void loop() {
  for(int i=544;i<2400;i++){
   digitalWrite(servoPin, HIGH);  
   delayMicroseconds(i);     
   digitalWrite(servoPin, LOW);   
   delayMicroseconds(m_max-i);    
  }
  delay(1000);

  for(int i=2400;i>544;i--){
   digitalWrite(servoPin, HIGH);  
   delayMicroseconds(i);     
   digitalWrite(servoPin, LOW);   
   delayMicroseconds(m_max-i);    
  }
  delay(1000);
}
}

for문으로 사용해서 min(544)값에서 max(2400)값이 될때까지 delayMicroseconds(i)로 전류의 공급 간격입니다. 이게 바로 각도이고요. delayMicroseconds()함수을 이용하여 전기 파형을 만들어 냅니다. 전류 공급시간이 작을 경우 펄스간격 시간단위로 짧은 파형이 작게 형성됩니다. 그럴때 서보모터의 움직이는 회전이 짧아서 그 상태를 유지하는거고요 i값이 클경우 그 파형이 크게 형성됩니다. 서보모터의 움직이는 회전각 커집니다. 그리고 그 회전에 도달하면 더이상 회전을 하지 않으며 그 회전각을 계속 유지하게 됩니다. 544에서 2400될때까지 전원 공급 간격이 점차적으로 커져가니깐 결과적으로 0~180도로 회전을 시키게 되는 것이죠. 두번째 for문은 2400에서 544가 될때까지 i의 전원 공급 간격이 적어지니깐 180~0도로 회전을 시키게 됩니다.

이해가 안된다고 생각하시면 쉽게 delayMicroseconds(i) 각도로 생각하시고 전원 공급과차단의 간격을 펄스간격 기준값(m_max)값이라고 생각하시면 됩니다. 펄스간격동안 delayMicroseconds()함수로 전류의 파형을 만들고 그 파형만큼의 각도로 회전을 시킨다고만 이해하시면 됩니다.

4. 결과


따로 제작과정없이 그냥 코드만 삽입해서 그 결과를 보여드립니다. 한번 서보모터 회전를 이해하기 위해서 동영상에서 과연 1500마이크로초 동안 공급될때 어느정도의 회전이 되고 그 상태를 유지할때 서보모터의 움직임을 유심히 살펴보시면서 회전을 어떤 느낌으로 회전되는지 이해하시면 되겠습니다. 그리고 본론으로 들어간 실험 코딩은 0~180도까지 회전 시키고 1초 대기했다가 180~0도까지 회전 시키는 과정을 반복합니다. 그리고 여기서는 아두이노우노의 2400의 값을 펄스파형을 이 일정하게 증가하다가 일정하게 감소하는 과정에서 전류를 시간값으로 해서 파형을 만들어내고 그 파형에 따라서 각도가 발생하는 점을 생각하시고 동영상의 서보모터의 회전을 보시면 되겠습니다.

마무리


쉬울 것 같아서 소개했는데 하고나니깐 이거 전기 신호의 파형을 봐야하고 서보모터의 동작원리를 자세히 알아야하는데 그렇게 자세히 설명을 하자니 삼천포로 빠질 가능성이 있어서 기본만 설명하다보니 좀 애매하게 됐네요.
오늘 포스팅 내용은 그냥 이런게 있구나 정도로만 하고 그냥 넘어가시고 구지 깊게 생각할 필요 없고요 편하게 Servo.h 의 Servo 클래스를 이용하시면 됩니다.
그냥 예전에 호기심에서 시작해서 그냥 제어만 해본거라 오늘 포스팅은 가볍게 읽고 이해가 안되더라도 무시하고 넘어가시면 됩니다.


댓글()