복잡한 코딩 시간이다쉽게 진행되기 위해 복수의 함수로 동작을 구분하여 설명한다.
앞에서 말한 선을 참조해야 하기 때문에 연결된 내용을 다시 한번 읽으면서 코드를 정리한다.
첫 번째로 할 일은 접속된 태핑을 정의하는 것이다.
위와 같이 핀접속에 관한 사항을 모두 정의하면 된다.서보 모터의 경우, 좌우의 움직임을 0~90도까지 회전하려고 하며, 초기에는 45도로 고정해서 정면을 보도록 하는 stop Motors는 모든 모터를 정지하라는 함수이다.모든 움직임은 별도의 함수를 통해 실현되므로, 우리가 모터의 움직임을 위해 만들어야 하는 함수는 다음과 같다.
void forward() // 직진하라 void backward() // 후진하라 void left() // 왼쪽으로 움직여라 void right() // 오른쪽으로 움직여라 stop Motors() // 멈춰라
좌우 장애물을 판단해 방향을 결정하기 위한 함수는 다음과 같다.floatcheck_distance() // 좌우 어느 쪽에 장애물이 멀지 않은지 판단하여 방향전환 voidchange Direction() // 초음파 센서의 거리측정
이상을 하나하나 점검하고 잘 조합하는 법을 배워야 한다.
모터가 스톱하는 경우는 좌우 바퀴 모두 전원이 LOW 상태일 것.그 코드는 다음과 같다.void stopMotors ( ) { digitalWrite ( INL 1 , LOW ) ; digitalWrite ( INL 2 , LOW ) ; digitalWrite ( INR 1 , LOW ) ; digitalWrite ( INR 2 , LOW ) ; }
앞으로 갈 때는 모든 모터가 같은 방향으로 움직여야 한다.왜 1, 2의 HIGH, LOW가 반대인가 하면 그렇게 모터에 들어간 전선의 방향이 정해져 있기 때문이다.아래 방향이 앞으로 가는 방향이라면 그 반대 방향으로 HIGH, LOW를 선택하면 모터가 뒤로 가는 방향이 되는 것이다. 이 값은 각자 설치된 모터에 따라 확인하여 정리하면 된다.
void forward ( ) { digitalWrite ( INL 1 , HIGH ) ; digitalWrite ( INL 2 , LOW ) ; digitalWrite ( INR 1 , LOW ) ; digitalWrite ( INR 2 , HIGH ) ; }
그러면 후향의 코드는 당연히 다음과 같이 될 것이다.void backward ( ) { digitalWrite ( INL 1 , LOW ) ; digitalWrite ( INL 2 , HIGH ) ; digitalWrite ( INR 1 , HIGH ) ; digitalWrite ( INR 2 , LOW ) ; }
왼쪽으로 가려면 오른쪽 바퀴는 앞으로 굴러가고 왼쪽 바퀴는 뒤로 굴러가면 쉽게 방향이 바뀐다.void left ( ) { digitalWrite ( INL 1 , LOW ) ; digitalWrite ( INL 2 , HIGH ) ; digitalWrite ( INR 1 , LOW ) ; digitalWrite ( INR 2 , HIGH ) ; }
오른쪽으로 가려면 왼쪽 타이어는 앞으로 구부러지고 오른쪽 타이어는 뒤로 돌면 쉽게 방향이 바뀐다.void right ( ) { Serial . println ( ” right … ” ) ; digitalWrite ( INL 1 , HIGH ) ; analogWrite ( INL 2 , LOW ) ; digitalWrite ( INR 1 , HIGH ) ; analogWrite ( INR 2 , LOW ) ; }
이제 장애물에 대한 판단과 방향 전환을 어떻게 할 것인지를 코드화해 보자 코드는 전방에 있는 장애물 거리다. 예전에 만든 코드와는 조금 다르게 만들어 봤다.모든 매우 정밀한 계산은 온도를 측정하지 않는 한 불가능하다.어쨌든 거리를 측정해 그 cm값을 return한다.
float check _ distance ( ) { digitalWrite ( tPin , LOW ) ; delayMicroseconds ( 10 ) ; digitalWrite ( tPin , HIGH ) ; delayMicroseconds ( 10 ) ; digitalWrite ( tPin , LOW ) ; float duration = pulseIn ( ePin , HIGH ) ; float distance = (( float ) ( 340 * duration ) / 10000 ) / 2 ; return distance ; }
지금까지는 하드웨어를 구동하는 기본 코드이며, 앞으로는 제작자의 기량이나 기획에 따라 마음껏 바꿔도 될 가장 중요한 코드이다. 독자가 원하는 형태로 수정하고 싶으면 여기를 수정하면 된다.여기가 좀 더 자세히 설명하려고 한다.
void changeDirection ( ) {
intlDist; // 좌측장애물의 거리 intrDist; // 우측장애물의 거리 delay(300);
Srv.write(90);//초음파센서의 방향을 왼쪽으로 돌린다.delay(300); // 잠시 여유를 두어야 한다. 이 부분을 넣지 않았기 때문에 문제가 많았다. // 만약 좌우 거리 값이 틀렸다면, 조금 더 delay 값을 늘려 보세요. lDist= check_distance(); // 좌측 장애물 거리 측정 delay(600);
Srv.write(0);//초음파센서의 방향을 오른쪽으로 돌린다.delay(300); // 잠시 여유를 두어야 한다. 이 부분을 넣지 않았기 때문에 문제가 많았다. rDist= check_distance(); // 우측 장애물 거리측정 delay(600);
Srv.write(45); // 다시 정면보기.if (lDist<rDist) { // 왼쪽에 장애물이 가까우면 right(); // 오른쪽에 방향전환 delay(300); // 오른쪽 회전량을 이 값으로 조절 stop Motors(); // 오른쪽 회전량이 멈추면 left () /// 오른쪽 회전량을 이 값으로 조절 stop Motors(); // 멈춘다.
모든 코드의 해석을 한 줄씩 첨부하였으니 잘 확인하시고 이해하시기 바란다.지금 이 모든 코드를 실행할 Loop 함수를 확인해 보자.
프로그램이 시작되면 주행 중 정면 20cm 앞에 장애물이 있을 경우 change Direction 함수를 불러 왼쪽 또는 오른쪽으로 장애물을 피해 가라는 명령이 정리되어 있다.3편으로 나뉜 자율주행자동차 만들기가 끝났다.
좀 복잡한 내용이었을지 모르지만 이들 코드가 모든 아두이노 장난감 자동차를 전후좌우로 움직이는 코드의 근간이다. 이 코드를 이용해 앞으로 블루투스나 무선으로 조종하는 자동차를 만들게 되니 이해해주기 바란다.다시 한 번 자동차의 움직임을 보면서 마무리하자.