아두이노 코딩-148: 음성인식명령으로 주행하는 RC카 앱인벤터 코딩

in #kr6 years ago (edited)

noname01.png

앱인벤터 음성인식 연습도 해보았고, 초음파 센서도 달았고 더 이상 벽에 부딪히는 일은 없으므로 이제부터는 좋게 좋게 말로 아두이노 RC카를 음성 인식으로 제어해 보자. 음성인식 사용하려면 마이크 아이콘 터치에서 시작하여 시간이 많이 소요되므로 급하면 바로 위의 터치 키를 사용하도록 한다.

블루투스로 제어되는 아두이노 코드는 RCCAR_BT_ULTRASIONIC_01에서 if 제어문 내용을 조금 수정하면 된다.

즉 블루투스 앱인벤터 코딩에서 문자 “F’, ‘B’,‘S’,‘L’,‘R’을 직접 버튼 터치에 의해 선택하여 송신하는 것뿐만 아니라 음성인식에 의해 얻어진 텍스트의 영어 머리글자 하나씩만 전송하므로 자신의 스마트폰에서 확인해 보고 if 문을 OR(||) 형태로 수정하기 바란다.

주의해야 할 점은 구글의 음성인식엔진이 콩글리쉬로 인식하기 때문에 글자 명령의 발음에 주의해야 하며 약간의 훈련이 필요하기도 하다. 몇 번의 경험에 의하면 엘이디라든지 엠비씨와 같이 세글자 콩글리쉬의 영문 인식율이 높다.

”Google“ 이라고 발음할 때에 영어로 ”Google“ 로 출력되는 것을 확인하도록 하자. 물론 머리 ㄱㄹ자인 ”G“ 만 송신한다. 후진에 해당하는 Back 은 우리 말 ”비케이“로 발음하면 쉽게 ”BK“로 출력되며 ”B“자를 아두이노에 송신하게 된다. 왼쪽에 해당하는 ”L“ 발음은 ”LA“ 즉 우리말로 ”엘에이“하면 쉽게 출력이 된다. 물론 머리글자 ”L“만 송신하게 된다. Stop도 오히려 ”에스티“하면 ”st“ 가 쉽게 인식 출력되어 ”s“ 만 송신하게 된다. Demonstration 대신 우리말로 ”데스크“라고 발음하면 쉽게 ”desk“ 로 출력된다. 물론 머리 글자만 보내게 된다.

시끄러운 분위기에서 전화로 머리글자 불러주는 헐리우드 스파이 영화에서 많이 보는 방식이다. 예를 들면 대문자 ‘C”는 “Charlie” 또는 “Clinton” 으로 불러주고 “T”는 “Trump” 처럼 불러 주는 방식이다.

noname02.png

앱인벤터 코딩을 하도록 해보자. 코딩을 시작하기 전에 마이크 이미지로 사용하기 위한 그림 파일을 준비해둔다. 이미지 파일 조사해서 복사해 와도 좋으며 또는 스스로 간단하게 해결하는 습관을 가지면 좋을 듯해서 그림판을 사용해 3 분 만에 직접 그려 파일명을 부여하고 확장자 png 파일로 저장하였다.

커버 그림으로 올려둔 스마트폰 화면에 따른 앱인벤터 콤포넌트 구성을 살펴보기로 하자. 핵심만 얘기하지면 블루투스 Connect 버튼과 전진 후진 좌회전 우회전 정지 버튼과 마이크 버튼이다, 아울러 Non visible 요소로는 음성인식(Voice recognizer), BluetoothClient 가 전부이다.

5개의 버튼 키는 RC카 움직임을 제어하기 위한 것이다.
음성 제어를 위해서는 아래의 마이크 이미지를 터치해서 뿅 소리가 나면 발성을 통해 입력해야 한다. 전진의 경우 약간의 발음 훈련이 필요하다, 후진 Back의 경우는 BK로 명령하면 쉽게 인식된다. 좌회전 Left는 LA로 우회전 Right는 rain으로, Stop은 st 로 발음하도록 한다.

음성명령이 인식되면 마이크 이미지 하단에 지가 인식한 내용을 텍스트로 출력한다.

이와같이 RC카 터치 명령 키보드와 음성명령 키보드와의 합성은 기존의 터치 명령 블록 코딩에 음성 부분을 추가하면 되므로 대단히 간단하다.

아래의 블록은 listPicker를 사용한 블루투스 검색 및 연결을 위한 퍼즐 코딩 부분이다.

noname03.png

아래의 코딩은 5개의 RC카 움직임 제어 명령 코딩이다. 버튼 키의 위치는 디자이너의 레이아웃 내부에서 3X3 TableArrangement를 사용하여 버튼들을 배치하면되며 퍼즐코딩과는 상관이 없다.

noname04.png

음성 명령은 마이크 버튼 클릭과 함께 음성인식 엔진으로부터 텍스트를 받아내어 블루투스로 송신하는 과정이다. 아래의 퍼즐 코딩을 단순히 추가하면 된다. 터치 명령과 음성 명령은 섞어 사용해도 무방하다.

noname05.png

한편 콤포넌트 구성과 블록에서의 퍼즐 코딩을 위한 디렉토리 구조를 참고하기 바란다. 아울러 블록 디렉토리의 TableArrangement 밑에 6개의 버튼 요소가 포함되어 있다.

noname06.png

한편 추가된 demonstration 키에 해당하는 아두이노 코드에서는 if문에 “D” 또는 “d”일 경우에 사용자가 넣고 싶은 주행 명령을 코딩해 넣어도 되며 코딩할 만한 내용이 없으면 비워두면 된다.

//RCCAR_BT_VOICE_ULTRASONIC_01
#define ECHO 2
#define TRIG 13

#include <AFMotor.h>
AF_DCMotor motor1(3);
AF_DCMotor motor2(4);
int mspd = 255;
char command;

void setup() {
Serial.begin(9600);
pinMode(TRIG,OUTPUT);
pinMode(ECHO,INPUT);
Stop();
delay(11000);
}

void loop() {
digitalWrite(TRIG,HIGH); //send Pulse
delayMicroseconds(10);
digitalWrite(TRIG,LOW);
int us = pulseIn(ECHO,HIGH); //get return time
int cm = us/58;
Serial.print("cm : ");
Serial.println(cm);

    if( cm < 30 ) {
      Stop();
      delay(50);
    }

if(Serial.available() > 0){
command = Serial.read();
// if( command == 'F') {
if( command == 'G' || command == 'g' || command == 'F') {
forward();
delay(50);
}

// if( command == 'B') {
if( command == 'B' || command == 'b' || command == 'BK') {
back();
delay(50);
}

// if( command == 'L') {
if( command == 'L' || command == 'l' || command == 'LA') {
left();
delay(50);
}

// if( command == 'R') {
if( command == 'R' || command == 'r' || command == 'h') {
right();
delay(50);
}

// if( command == 'S') {
if( command == 'S' || command == 's' || command == 'st') {
Stop();
delay(50);
}

 if( command == 'D' || command == 'd' ) {
  //please fill this space for your demonstration, otherwise leave it empty
 }

}
}

void forward() {
motor1.setSpeed(mspd); //Define maximum velocity
motor1.run(FORWARD); //rotate the motor clockwise
motor2.setSpeed(mspd); //Define maximum velocity
motor2.run(FORWARD); //rotate the motor clockwise
}

void back() {
motor1.setSpeed(mspd);
motor1.run(BACKWARD); //rotate the motor counterclockwise
motor2.setSpeed(mspd);
motor2.run(BACKWARD); //rotate the motor counterclockwise
}

void left() {
motor1.setSpeed(mspd); //Define maximum velocity
motor1.run(FORWARD); //rotate the motor clockwise
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}

void right() {
motor1.setSpeed(0);
motor1.run(RELEASE); //turn motor1 off
motor2.setSpeed(mspd); //Define maximum velocity
motor2.run(FORWARD); //rotate the motor clockwise
}

void Stop() {
motor1.setSpeed(0);
motor1.run(RELEASE); //turn motor1 off
motor2.setSpeed(0);
motor2.run(RELEASE); //turn motor2 off
}

//끝

Sort:  

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

Coin Marketplace

STEEM 0.26
TRX 0.11
JST 0.033
BTC 64507.66
ETH 3080.07
USDT 1.00
SBD 3.85