[과제제출] vcp로 라인트레이서 만들기

안녕하세요 FAET 양세중 매니저입니다.

라인트레이서 (4)

저는 자동차를 좋아하는 아들에게 자율주행 자동차라고 속이고 라인트레이서를 함께 만들어 주려고 체험단에 참여하게 되었씁니다.

첫 계획은 LED를 다수 사용하여 여러가지 (웰컴 라이트, 경찰 경광등.. 등..) 계획을 하였으나 육아 및 체력 이슈로 인해 트레이싱만 간단히 구현하는데 그쳐 아쉬움이 남습니다.. 이하 음슴체로 남깁니다.

아쉬운점:

  • 12V power 이슈 때문에 배터리를 알리에서 구하느라 시간이 조금 지체되었음
  • 라이트 기능 구현을 하지 못했다
  • 파인 튜닝 (디지털로 구현하다 보니 한계가 있었음)

구현 방법:

아두이노로 구현하였음

  • 적외선 센서
    • 적외선 센서를 두개 연결하여 각각 high/low 신호를 받음
    • 디지털 신호여서 모듈의 +를 돌려서 민감도 조절 필요
  • 모터
    • 둘다 검은색이면 직진
    • 한쪽만 검은색일 경우 방향전환 및 방향 저장
    • 둘다 하얀색일 경우 저장된 방향을 읽어 라인쪽으로 뱡향전환
  • 버튼
    • 파란색 버튼: 주행 모드. 부팅 시에는 기본 주행 모드로 설정
    • 빨간색 버튼: 모터 정지
    • 노란색 버튼: 속도 조절 (5에서 10까지 조절 가능). 버튼 누르면 1초간 모터 정지
  • 지도
    • 아래 PDF 파일을 프린트하여 아들이 만든 지도 (영상 참조)

    • 제출본은 독일 뉘르부르크링 노르트슐라이페를 참고하여 만듦

      LineFollowingTracks.pdf (54.6 KB)

이하 아두이노 코드 입니다.

/*  
This code prints "Detected" to the Serial Monitor when an object is detected,   
and "Not Detected" when no object is detected.  
*/  

#include "HardwareSerial.h"  
HardwareSerial Serial;  

int irLeft = 20;  
int irRight = 21;
int motorLeft[] = {52, 53};
int motorRight[] = {50, 51};
int ledSiren[] = {2, 8, 12, 14};
int ledFront[] = {22, 23};
int ledDirectionIndicator[] = {24, 25};
int buttonPin[] = {30, 32, 34};
int buttonMode = -1;
int val[] = {0, 0};
int isLeft = 0;
int accel = 0;
int speed = 5;

void setup() {  
    Serial.begin(115200);
    // LED
    for (int i=0; i<4; i++) {
        pinMode(ledSiren[i], OUTPUT);
        digitalWrite(ledSiren[i], HIGH);
    }

    // IR sensor
    pinMode(irLeft, INPUT);
    pinMode(irRight, INPUT);

    // Motor
    for (int i=0; i<2; i++) {
        pinMode(motorLeft[i], OUTPUT);
        pinMode(motorRight[i], OUTPUT);
        pinMode(ledFront[i], OUTPUT);
        pinMode(ledDirectionIndicator[i], OUTPUT);
        digitalWrite(ledFront[i], LOW);
        digitalWrite(ledDirectionIndicator[i], LOW);
    }

    // button
    for (int i=0; i<3; i++) {
        pinMode(buttonPin[i], INPUT_PULLUP);
    }

    // default mode is Driving Mode
    mode1();
}  

void loop() {
    switch (buttonMode) {
        case 0:
            Serial.println("Mode 0 selected");
            mode0();
            break;
        case 1:
            Serial.println("Mode 1 selected: Driving mode");
            mode1();
            break;
        case 2:
            Serial.println("Mode 2 selected");
            mode2();
            break;
        default:
            // Serial.println("No switch pressed");
            buttonMode = selectMode();
            break;
    }
    // delay(10);
}

void readLine() {
    val[0] = digitalRead(irLeft);
    val[1] = digitalRead(irRight);
    return;
}

int selectMode() {
    for (int i=0; i<3; i++) {
        int button = digitalRead(buttonPin[i]);
        if (button == LOW) {
            return i;
        }
    }
    return buttonMode;
}

void stopDelay(int time) {
    // Serial.println("stop");
    delay(speed);
    digitalWrite(motorLeft[0], LOW);
    digitalWrite(motorLeft[1], LOW);
    digitalWrite(motorRight[0], LOW);
    digitalWrite(motorRight[1], LOW);
    delay(time);
    return;
}

void mode0() {
    // stop mode (red button)
    while (buttonMode == 0) {
        readLine();
        digitalWrite(motorLeft[0], LOW);
        digitalWrite(motorLeft[1], LOW);
        digitalWrite(motorRight[0], LOW);
        digitalWrite(motorRight[1], LOW);
        
        buttonMode = selectMode();
        delay(10);
    }
    Serial.println("Escape mode 0");
    return;
}

void mode1() {
    // driving mode (default and blue button)
    while (buttonMode == 1 || buttonMode == -1) {
        readLine();
        if (val[0] == HIGH && val[1] == HIGH) {
            // Serial.println("Straight");
            digitalWrite(motorLeft[0], LOW);
            digitalWrite(motorLeft[1], HIGH);
            digitalWrite(motorRight[0], LOW);
            digitalWrite(motorRight[1], HIGH);
            stopDelay(10 - accel);
            if (accel < 5) {
                accel += 1;
            }
        }  
        else if (val[0] == HIGH && val[1] == LOW) {  
            // Serial.println("Left");
            isLeft = 0;
            accel = 0;
            digitalWrite(motorLeft[0], HIGH);
            digitalWrite(motorLeft[1], HIGH);
            digitalWrite(motorRight[0], LOW);
            digitalWrite(motorRight[1], HIGH);
            stopDelay(10);
        }
        else if (val[0] == LOW && val[1] == HIGH) {  
            // Serial.println("RIGHT");
            isLeft = 1;
            accel = 0;
            digitalWrite(motorLeft[0], LOW);
            digitalWrite(motorLeft[1], HIGH);
            digitalWrite(motorRight[0], HIGH);
            digitalWrite(motorRight[1], HIGH);
            stopDelay(10);
        }
        else if (val[0] == LOW && val[1] == LOW) {  
            // Serial.println("Out of line. Turn");
            accel = 0;
            if (isLeft == 0) {
                digitalWrite(motorLeft[0], HIGH);
                digitalWrite(motorLeft[1], LOW);
                digitalWrite(motorRight[0], LOW);
                digitalWrite(motorRight[1], HIGH);
            } else {
                digitalWrite(motorLeft[0], LOW);
                digitalWrite(motorLeft[1], HIGH);
                digitalWrite(motorRight[0], HIGH);
                digitalWrite(motorRight[1], LOW);
            }
            stopDelay(20);
        }
        buttonMode = selectMode();
    }
    Serial.println("Escape mode 1");
    return;
}

void mode2() {
    // increase speed by 1 when yellow button pushed from 5 to 10
    if (speed >= 10) {
        speed = 5;
    } else {
        speed += 1;
    }
    Serial.print("speed is ");
    Serial.println(speed);
    buttonMode = 1;
    // pause for 1 sec
    delay(1000);
    return;
}

느낀점:

VCP로 직접 뭔가 만드는것이 재미있었고, 기회가 있다면 더 재미있는 것도 만들고 싶음

이상입니다.

1 Like