산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Arduino 및 BitVoicer 서버가 있는 2WD 음성 제어 로봇

구성품 및 소모품

Arduino UNO
× 1
Pololu 듀얼 MC33926 모터 드라이버 실드
× 1
SparkFun XBee 실드
× 1
마이크로칩 RN171VX 모듈
× 1
SparkFun Electret 마이크 브레이크아웃
× 1
2WD 로봇 자동차 섀시
× 1
Texas Instruments LM1117(TO-220) 전압 조정기
× 1
커패시터 10μF
× 1
LED(일반)
× 4
저항 330옴
× 4
AA 배터리
× 4
9V 배터리(일반)
× 1
9V-배럴 잭 어댑터
× 1
점퍼 와이어(일반)
× 17
일반 구리 와이어
× 1
고정용 나사 및 유연한 플라스틱 클램프
× 1

필요한 도구 및 기계

납땜 인두(일반)
플라이어
스크류드라이버

앱 및 온라인 서비스

비트보이서 서버 1.0

이 프로젝트 정보

이 튜토리얼에서는 2WD 음성 제어 로봇을 만드는 방법을 보여 드리겠습니다. 로봇을 움직이기 위해 DC 모터만 제어하고 있지만 스테퍼 모터와 서보 모터를 음성으로 제어하는 ​​데 동일한 접근 방식을 사용할 수 있으므로 기계적 움직임을 수행하는 음성 제어 로봇을 만들 계획이라면 이 튜토리얼이 도움이 될 수 있습니다. 프로젝트에 대한 참조입니다.

이 로봇을 만들려면 기본적으로 2륜 섀시, Arduino 보드 1개, DC 모터 드라이버 쉴드 1개, BitVoicer 서버 라이선스 1개, WiFi 모듈 1개, 사전 증폭 마이크 1개가 필요합니다. 구성 요소와 관련하여 시장에는 매우 다양한 구성 요소가 있으며 다른 조합을 사용하여 동일한 결과를 얻을 수 있습니다. 1단계에서는 로봇에 사용되는 일부 구성 요소에 대해 몇 가지 세부 정보를 제공하므로 일부를 변경해야 하는 경우 유사한 기능을 가진 구성 요소를 찾으면 됩니다.

음성 명령을 로봇 움직임으로 변환하기 위해 다음 절차가 실행됩니다.

<울>
  • 1. 오디오 웨이브는 Sparkfun Electret Breakout 보드에서 캡처 및 증폭됩니다.
  • 2. 증폭된 신호는 아날로그-디지털 변환기(ADC)를 사용하여 Arduino에서 디지털화되고 버퍼링됩니다.
  • 3. 오디오 샘플은 Microchip WiFi 모듈을 사용하여 BitVoicer 서버로 스트리밍됩니다.
  • 4. BitVoicer Server는 오디오 스트림을 처리하고 포함된 음성을 인식합니다.
  • 5. 인식된 음성은 Arduino로 전송될 미리 정의된 명령에 매핑됩니다.
  • 6. Arduino는 명령을 식별하고 어떤 DC 모터가 얼마나 오래 그리고 어떤 속도로 사용될 것인지 정의합니다.
  • 7. 모터 드라이버는 모터를 움직이는 데 필요한 전압과 전류를 제공하도록 활성화됩니다.
  • 자료 목록:

    <울>
  • Arduino UNO:~U$ 25.00
  • 폴로루 듀얼 MC33926 모터 드라이버 실드:US 29.95
  • SparkFun XBee 실드:U$ 14.95
  • Microchip RN171VX 모듈(안테나 포함):U$ 34.95
  • SparkFun 일렉트릿 마이크 브레이크아웃:U$ 7.95
  • BitVoicer 서버 1.0:U$ 8.90
  • 2WD 로봇 자동차 섀시:U$ 15.95
  • Texas Instruments LM1117(TO-220) 전압 조정기:~U$ 1.95
  • 10μF 전해 커패시터:~U$ 0.35
  • 4 x LED:~US 1.00
  • 4 x 330옴 저항기:~U$ 0.75
  • 4 x 1.5V AA 배터리:~US 2.00
  • 9V 배터리:~US 2.00
  • 9V-배럴 잭 어댑터:~US 2.50
  • 점퍼 전선 및 일반 전선:~U$ 2.00
  • 고정용 나사 및 유연한 플라스틱 클램프
  • 납땜 및 땜납
  • 1단계:구성 요소 알아보기

    이 단계에서는 로봇의 구성 요소와 장착을 위해 준비하는 방법에 대한 몇 가지 중요한 정보를 제공합니다.

    우선 로봇의 핵심은 Arduino UNO R3입니다. 나는 Arduino UNO를 사용하고 있지만 다른 Arduino 보드를 사용하여 로봇을 장착할 수 있습니다. 저는 Arduino UNO를 사용하기로 결정했습니다. 왜냐하면 지금까지 가장 인기 있는 Arduino 보드이고 더 많은 사람들이 이 로봇을 다시 만들 수 있기 때문입니다. Arduino DUE가 있는 경우 이 튜토리얼에서 했던 것처럼 로봇에 음성 응답을 추가할 수도 있습니다.

    DC 모터를 움직이기 위해 이 Pololu 실드를 사용했습니다. 5~28V DC 모터를 제어할 수 있고 모터당 최대 3A의 연속 전류를 공급할 수 있는 듀얼 모터 드라이버입니다. 이것은 매우 좋은 방패라고 생각하지만 Pololu의 제품에서 가장 인상 깊었던 것은 명확하고 상세한 문서입니다. 게다가, Pololu는 모터를 정말 간단하게 제어할 수 있는 Arduino 라이브러리를 제공합니다. 속도와 방향(음수 또는 양수 값)을 setSpeeds에 전달하기만 하면 됩니다. 기능. 다른 DC 모터 드라이버를 사용하기로 선택한 경우 로봇이 사용하는 다른 핀과 충돌할 수 없으므로 드라이버가 사용하는 핀에 주의하십시오. Pololu 실드는 다음 Arduino 핀을 사용합니다. 디지털 4, 7, 8, 9, 10 및 12; 아날로그 0과 1; 지면; 그리고 5V. 여기서 가장 중요한 측면은 핀 9와 10만 PWM 핀으로 사용되며 이 핀에서 펄스를 생성하는 데 사용되는 타이머가 BitSophia의 BVSMic 클래스에서 사용하는 것과 동일한 타이머(UNO의 타이머 2)가 아니라는 것입니다.

    서버와의 통신을 설정하고 BitVoicer 서버 서비스에 액세스하기 위해 Microchip WiFi RN171VX 모듈을 사용합니다. 이 모듈에서 두 가지 주요 기능이 두드러집니다. 모든 통신은 직렬 포트를 통해 간단한 방식으로 수행될 수 있습니다. 이 모듈은 대부분의 인기 있는 XBee 모듈과 동일한 폼 팩터를 가지고 있습니다. 즉, 이미 XBee 실드가 있는 경우 이 로봇에 사용하는 Sparkfun 실드를 구입할 필요가 없을 것입니다.

    Microchip WiFi 모듈과 함께 XBee 실드를 사용하면 로봇을 매우 쉽게 장착할 수 있습니다. 그러나 이 조합에서 문제를 확인했습니다. 라디오 작업은 매우 복잡하며 일부 사람들은 "부두 마술"로 간주하는 것으로 알려져 있습니다. 글쎄, 나는 WiFi 어댑터가 켜져 있고 데이터를 전송하는 동안 Arduino ADC에서 측정 한 오디오 신호에 강한 간섭이 발생한다는 것을 알았습니다. 이 간섭의 원인을 정확하게 식별할 수 없었지만 가능한 두 가지 원인이 있습니다. 모듈 피크 전류 소모(최대 240mA)가 제대로 분리되지 않고 Arduino ADC에 제공되는 기준 전압이 손상됩니다. 또는 안테나에서 방출되는 신호가 모듈 바로 아래에 있는 일부 노출된 핀에 의해 포착됩니다. 일반적으로 WiFi 모듈 제조업체는 이러한 문제를 방지하기 위해 설계자에게 안테나 근처에 어떤 물체(접지판도 포함)를 두지 않도록 지시합니다.

    위에서 설명한 문제를 해결하기 위해 3.3V 전압 조정기와 10μF 전해 커패시터 1개를 Sparkfun 실드에 납땜하여 Arduino ADC에 기준 전압을 제공할 수 있도록 했습니다. 동일한 전원이 Sparkfun 일렉트릿 마이크에 사용됩니다. BitVoider Server Manager에서 볼 수 있었던 최대 볼륨 문제를 해결했습니다. 침묵 기간 동안에도 오디오 레벨은 Server Monitor에서 35(0-100)까지 올라갔습니다. 프로젝트에서 동일한 일이 발생하는 경우 Arduino ADC에서 측정한 오디오 신호에 어떤 일이 일어나고 있는지 조사하십시오.

    나는 또한 Sparkfun 실드에서 사용 가능한 프로토타이핑 공간을 사용하여 일부 BitVoicer 서버 기능의 상태를 알려주는 몇 가지 LED를 납땜하기로 결정했습니다. 아래 그림에서 왼쪽에서 오른쪽으로 LED에 의해 다음 정보가 노출됩니다.

    <울>
  • BitVoicer 서버가 실행 중인지 여부 및/또는 연결이 활성 상태로 남아 있는지 여부를 나타냅니다.
  • 데이터 전달 서비스가 실행 중인지 여부를 나타냅니다.
  • 음성 인식 엔진이 Arduino에 할당되었는지 여부를 나타냅니다.
  • 활성화 단어 활성화 기간에 있는지 여부를 나타냅니다. 이 LED는 활성화 단어가 식별될 때만 켜집니다.
  • 사전 증폭 일렉트릿 마이크와 관련하여 시장에는 Sparkfun, Adafruit, RoboCore, Hackerstore 및 기타 많은 옵션이 있습니다. 이 튜토리얼에 게시하는 코드를 사용하려면 구입하는 마이크가 아날로그인지, Arduino 보드에서 필요한 전압을 사용할 수 있는지, Arduino ADC에 대해 증폭이 충분히 높은지(일반적으로 일렉트릿 마이크의 경우 100x) 확인하십시오.

    로봇에 사용된 2WD 섀시는 eBay에서 가장 저렴하고 인기 있는 섀시 중 하나입니다. 전체 키트에는 아크릴 플랫폼 1개, 플라스틱/고무 바퀴 2개, 360º 바퀴 1개, 기어가 있는 DC 모터 2개(1:48 비율), 4xAA 배터리 홀더 1개, 속도 인코더 디스크 2개 및 나사 세트가 포함되어 있습니다.

    2단계:장착

    일하러 가자! 이 단계에서는 아래 그림과 같이 섀시에 모든 구성 요소를 장착해야 합니다.

    XBee 실드에 LED와 전압 조정기를 납땜하지 않으려면 아래 그림과 같이 작은 브레드보드에 장착할 수 있습니다. 이 경우 더 이상 문제 없이 섀시의 어딘가에 고정할 수 있도록 축소된 크기의 브레드보드를 ​​선택합니다.

    위의 사진에서 마이크를 고정하기 위해 철선 지지대를 만든 것을 알 수 있습니다. 360º 휠 주위에 펠트 천 조각을 붙인 것도 볼 수 있습니다. 로봇에서 발생하는 소음과 로봇이 움직일 때 마이크에 포착되는 소음을 줄이기 위해 이 두 가지 조치를 취했습니다. 지지대에서 마이크 와이어를 분리하기 위해 작은 스폰지 조각도 자릅니다. 물론 100% 효과가 있는 것은 아니지만 노이즈를 조금 줄이고 음성 인식 정확도를 높였습니다.

    3단계:WiFi 모듈 설정

    1단계에서 말했듯이 Microchip RN171VX WiFi 모듈은 직렬 포트를 통해 완전히 작동할 수 있습니다. 이것은 모든 명령이 Arduino 직렬 포트를 통해 전송되는 간단한 문자열이기 때문에 모듈을 설정하기가 매우 쉽습니다. "$$$"가 포함된 문자열을 보내면 명령 모드로 들어가고 명령을 보낸 다음 "exit"가 포함된 문자열을 보내면 데이터 모드로 돌아갑니다.

    WiFi 모듈 설정이라는 코드 이 가이드의 하단에는 홈 네트워크에서 WiFi 모듈을 설정하는 데 사용한 코드가 있습니다. WiFi 네트워크의 정보로 "XXXXXX"로 표시된 코드 부분을 변경해야 합니다. 세 가지 명령을 변경해야 합니다.

    <울>
  • wlan ssid XXXXXX 설정 :XXXXXX를 네트워크 이름(SSID)으로 바꿉니다.
  • WLAN 문구 XXXXXX 설정 :XXXXXX를 네트워크 비밀번호로 교체합니다.
  • IP 주소 XXXXXX 설정 :XXXXXX를 WiFi 모듈에 설정하려는 IP 주소(고정)로 바꿉니다.
  • 내 WiFi 네트워크에서 인증 방법은 WPA2-PSK입니다. 네트워크에서 다른 인증 방법을 사용하는 경우 set wlan auth도 변경해야 합니다. 명령. WiFi 모듈 설명서(섹션 4.3 명령 설정)를 확인하여 네트워크에 올바른 값을 찾으십시오.

    중요가 있습니다. Sparkfun 실드와 작은 스위치에 대한 세부 정보(아래 그림). USB 인터페이스를 사용하여 Arduino에 코드를 업로드하려면 스위치를 DLINE 위치로 설정해야 합니다. Arduino가 직렬 포트를 사용하여 WiFi 모듈을 통해 데이터를 송수신하려면 스위치를 UART 위치로 설정해야 합니다. 이것은 Arduino UNO의 WiFi 모듈과 USB 칩이 ATmega 마이크로 컨트롤러에서 동일한 직렬 포트를 사용하기 때문에 필요합니다. 스위치가 UART로 설정되어 있고 Arduino에 코드를 업로드하려고 하면 Arduino IDE에 오류 메시지가 표시됩니다.

    WiFi 모듈 설정을 업로드하려면 Arduino에 코드를 입력하고 Arduino가 WiFi 모듈을 설정하도록 하려면 아래 단계를 따르십시오.

    <울>
  • 1. 스위치를 DLINE 위치로 설정합니다.
  • 2. Arduino IDE를 열고 코드를 Arduino에 붙여넣고 업로드합니다.
  • 3. 업로드가 완료되면 명령이 WiFi 모듈로 전송되기 전에 스위치를 UART 위치로 변경하는 데 5초(코드 시작 시 지연)가 주어집니다. 첫 번째 명령이 손실되면 다른 명령은 작동하지 않습니다. 이 경우 스케치를 처음부터 다시 실행할 수 있도록 Arduino를 재설정하기만 하면 됩니다.
  • 약 25초가 소요되는 모듈 구성 중에는 모듈 LED가 표준 패턴과 다르게 깜박입니다. 이 순간 WiFi 모듈이 구성되고 있음을 알 수 있습니다.

    모듈을 구성한 후 IP 주소 설정에 지정된 IP 주소를 사용하여 모듈에 대해 ping(명령 프롬프트 --> "ping [IP 주소]" --> Enter 누르기)을 시도합니다. 명령. 모듈에서 응답을 받지 못하면 이전 단계에서 문제가 발생한 것입니다.

    4단계:로봇 이동 계획

    로봇에는 두 개의 DC 모터만 있지만 일련의 복잡한 움직임을 수행할 수 있습니다. 이 튜토리얼을 최대한 간단하게 유지하기 위해 약 30여 개의 기본 균일 동작과 기본 동작의 조합으로 형성되는 몇 가지 복잡한 동작만 정의하기로 했습니다.

    2단계의 사진에서 볼 수 있듯이 저는 바퀴의 회전 센서, 초음파 센서 또는 다른 유형의 센서를 사용하여 물체와의 거리 또는 이동 거리를 측정하지 않습니다. 이는 로봇이 고정밀 움직임을 수행하는 것을 방지합니다. 그러나 모터의 방향과 속도만 제어하면 로봇을 움직일 수 있을 정도로 정밀한 수준을 얻을 수 있습니다.

    각 동작에 필요한 실행 시간을 계산하기 위해 가장 먼저 알아야 할 것은 로봇의 평균 속도입니다. 그렇게 하려면 줄자를 로봇과 평행하게 놓고 1~2초 동안 두 모터를 동시에 활성화하고 이동 거리를 측정하고 속도를 추론합니다. 내 구성에서 최대 모터 속도(250/400, Pololu Arduino 라이브러리 참조)의 62.5%를 사용하여 초당 13.7센티미터를 얻었습니다. 즉, 로봇을 1미터(100cm) 앞으로 움직이기 위해 모터는 7.299270…초 동안 동시에 활성화되어야 했습니다. 나는 시간을 밀리초 단위로 계산하도록 선택했지만 더 높은 이동 정밀도를 달성하려면 해상도를 마이크로초로 높이는 것을 고려하십시오. 간단히 말해서 로봇을 1미터 이동하려면 두 모터를 동시에 7299밀리초 동안 활성화해야 합니다. 이 숫자에서 모든 것은 다른 거리에 대한 3의 규칙이 됩니다. 호 또는 원형 이동을 수행하려면 한 바퀴가 다른 바퀴보다 빠르게 움직여야 합니다. 로봇을 옆으로 돌리려면 한 바퀴만 활성화하거나 반대 방향(자체 축에서 회전)으로 둘 다 활성화해야 합니다. 여기서 각 바퀴가 이동한 거리와 각 모터가 활성화되어야 하는 시간을 파악하기 위해 삼각법을 사용해야 합니다. 이러한 개념에 대한 좋은 출발점은 다음 링크에서 찾을 수 있습니다(여기서 더 자세히 설명하지 않겠습니다):http://rossum.sourceforge.net/papers/CalculationsForRobotics/CirclePath.htm 및 http://math .stackexchange.com/questions/60176/move-two-wheeled-robot-from-one-point-to-another.

    아래 비디오 끝 부분에서 볼 수 있듯이 로봇이 바닥에 몇 가지 기본적인 기하학적 형태(사각형, 삼각형 및 원)를 "그리게" 합니다. 이러한 움직임은 기본 움직임(예:전진, 회전, 전진, 회전 등)의 조합으로 이루어집니다. 이러한 움직임의 조합은 BitVoicer 서버 음성 스키마에서 이루어지며 다음 단계에서 제공되는 Arduino 스케치에서는 이러한 움직임을 볼 수 없습니다.

    5단계:Arduino에 코드 업로드

    이 단계에서는 로봇 소스 코드라는 스케치를 업로드해야 합니다. , 이 가이드 하단에 있는 Arduino에 연결합니다. 아래 링크에서 Arduino 스케치를 다운로드할 수도 있습니다. Arduino에 코드를 보내려면 3단계에서 설명한 대로 Sparkfun 실드의 스위치를 DLINE 위치로 설정해야 합니다. 코드를 업로드하기 전에 BitVoicer 서버와 Pololu 모터 드라이버 라이브러리를 Arduino IDE에 올바르게 설치해야 합니다. (.zip 라이브러리 가져오기).

    로봇 소스 코드 :BVS_Demo3.ino

    이 스케치의 일부는 이전 자습서 중 하나에서 사용한 부분과 유사하며 BitVoicer Server(BVSP 및 BVSMic 클래스)와의 통신을 다룹니다. 이 튜토리얼에서는 스케치의 새로운 부분에 대한 설명을 고수할 것입니다. BVSP 및 BVSMic 클래스를 사용하는 방법에 대한 자세한 정보를 얻으려면 위에서 언급한 자습서를 참조하는 것이 좋습니다.

    <울>
  • 상수 선언 :스케치를 시작할 때 코드 전체에 사용되는 일련의 상수를 선언합니다. 모터 설정이 있는 상수 그룹은 기본 모터 속도와 두 가지 방향 상수를 정의합니다. Pololu 모터 드라이버 라이브러리는 0이 꺼짐을 의미하는 모터 속도에 대해 -400에서 +400 사이의 값을 허용합니다. 음수 값은 역회전을 나타냅니다. 저처럼 모터 와이어를 역전시킨 경우 정회전을 나타냅니다. 명령 값이 있는 상수 그룹은 BitVoicer 서버에서 전송될 명령을 나타냅니다. 이 스케치에서는 byte 의 기본 명령 40개만 정의했습니다. 유형이지만 이러한 명령을 결합하여 더 복잡한 움직임을 수행할 수 있습니다.
  • 실행 제어 변수 :5개의 변수가 코드 시작 부분에 정의되어 명령 실행을 제어합니다(motorSpeed , cmdDuration , cmdStartTime , cmd실행 중 e lastFwdCmd ). 모터 속도 변수는 현재 모터 속도를 유지합니다. 이 변수는 Arduino가 BitVoicer 서버로부터 모터 속도를 업데이트하라는 명령을 받으면 속도 상수에 의해 정의된 기본값 중 하나로 업데이트됩니다. cmdDuration 변수는 현재 명령의 총 지속 시간을 보유합니다. 이 변수는 cmdStartTime 에 대해 확인됩니다. 루프 의 모든 반복에서 변수 cmdRunning 인 경우 함수 사실 . 명령 실행 시간이 만료된 경우 RunCommand 모터를 정지시키는 함수가 호출됩니다. lastFwdCmd 변수는 마지막 "이동/앞으로 이동" 명령을 보유합니다. 이 변수는 "복귀" 명령을 실행할 수 있도록 마지막 이동 거리를 아는 데 사용됩니다. 이 명령을 사용하려면 먼저 로봇에게 회전하도록 지시해야 합니다.
  • WiFi 연결 :스케치 끝에서 BitVoicer Server(연결 연결 해제 ). 이러한 기능은 Microchip WiFi 모듈을 명령 모드로 전환하고 TCP/IP 연결을 열거나 닫고 모듈을 데이터 모드로 되돌립니다. 루프 내부 연결된 변수가 true가 아닌 경우 함수 , 저는 연결 기능. BVSP 클래스가 서버 상태가 만료되었다고 보고하는 경우, 즉 마지막 상태 요청에 대한 응답이 수신되지 않은 경우 연결이 끊어졌다고 가정하고 연결 해제 기능. 이렇게 하면 다음 루프 반복에서 새로운 연결 시도가 강제 실행됩니다.
  • 런커맨드 기능 :이 함수는 BitVoicer 서버에서 명령을 수신할 때마다 호출됩니다. 바이트 가 필요합니다. 스케치 시작 시 상수로 정의된 기본 명령 중 하나에 해당하는 값. 각 기본 명령은 스위치 내부에서 식별되므로 적절한 모터 속도와 명령 지속 시간을 설정할 수 있습니다. 함수 끝에서 cmdRunning 변수가 true 로 설정됨 밀리 로 반환된 시간 함수는 cmdStartTime 에 저장됩니다. 변하기 쉬운. 이를 통해 Arduino는 위에서 설명한 대로 명령 실행을 제어할 수 있습니다. 이전 단계에서 설명한 대로 각 명령에 대한 시간(밀리초)을 얻었습니다.
  • 6단계:BitVoicer 서버 설정

    이 단계에서는 인식할 문장과 Arduino로 보낼 명령으로 BitVoicer 서버 음성 스키마를 빌드해야 합니다. 이 단계가 끝나면 이 튜토리얼에서 사용된 모든 BitVoicer 서버 솔루션 개체를 포함하는 파일에 대한 두 개의 링크가 있습니다. 모든 솔루션 개체를 하나씩 생성하지 않으려면 이러한 파일을 사용하여 가져올 수 있습니다(솔루션 개체 가져오기).

    음성 스키마 구축을 시작하기 전에 BitVoicer 서버에서 Arduino를 나타낼 장치를 만들어야 합니다. 혼합 장치를 만들고 이름을 ArduinoUnoWiFi로 지정합니다. Communication 탭에서 TCP/IP를 선택하고 3단계에서 WiFi 모듈에 할당된 IP 주소를 입력합니다. Cues 탭에서 Start of Activated Period를 활성화합니다. 및 활성화 기간 종료 단서. 두 큐에 대해 Int16 SendData 명령을 선택하고 명령의 대상으로 ArduinoUnoWiFi 장치를 선택합니다. 데이터 필드에 활성화된 기간의 시작에 대해 1을 입력합니다. 활성화된 기간의 끝에 대한 큐 및 0 큐. 이 신호는 활성화 단어가 인식될 때마다 Arduino가 하나의 LED를 켜도록 합니다. 활성화된 기간(음성 스키마에서 정의)이 만료되면 이 LED가 꺼집니다.

    이제 음성 스키마를 빌드해 보겠습니다. 로봇에는 40개의 기본 명령만 있지만 동일한 명령을 실행하는 여러 단어 조합을 만들고 싶을 수 있습니다. 예를 들어 "한 미터 앞으로 이동" 및 "한 미터 앞으로 이동"이라는 문장이 동일한 명령을 실행하도록 할 수 있습니다. 또한 일련의 임시 명령을 순서대로 트리거하는 "정사각형 수행"과 같은 복잡한 명령을 생성할 수 있습니다. 그 때문에 음성 스키마는 크게 성장할 수 있고 40개 이상의 기본 명령을 가질 수 있습니다. BitVoicer Server는 무제한 문장을 지원하므로 필요한 만큼 문장을 정의할 수 있습니다(제 경우 80개 이상의 문장으로 끝남). 여기에서 두 가지 팁을 제공하고 싶습니다. BitVoicer 서버 관리자 옵션에서 기본 명령을 생성합니다. 한 문장에서 다른 문장으로 중복된 명령을 복사하여 붙여넣습니다.

    문장 명령은 byte 를 보냅니다. 데이터 유형을 Arduino에 제공합니다. 스케치 시작 부분에 정의된 상수를 사용하여 각 명령에 대해 어떤 값을 보내야 하는지 알 수 있습니다. 복잡한 명령은 많은 값을 순서대로 전송하므로 이전 명령이 실행되는 동안 값이 전송되지 않도록 이들 사이의 간격(지연)을 제어해야 합니다. 지연 필드를 사용하여 명령 사이의 간격을 설정합니다.

    솔루션 개체 파일 :

    Device.sof

    VoiceSchema.sof

    7단계:결론

    이제 AA 배터리를 넣고 9V 배터리를 Arduino 전원 잭에 연결하여 로봇에 생명을 불어넣기만 하면 됩니다! Arduino에 코드를 업로드한 후 Sparkfun 실드에 장착된 스위치를 UART 위치로 설정하는 것을 잊지 마십시오. 그렇지 않으면 WiFi 모듈은 Arduino 직렬 포트에서 보낸 데이터를 수신하지 않습니다.

    로봇을 켠 후 상태 LED가 켜질 때까지 약간의 시간이 걸립니다. WiFi 모듈이 통신을 시작하고 TCP/IP 연결이 설정되면 모듈 LED 중 하나가 계속 켜져 있는 것을 볼 수 있습니다. 잠시 후 4개의 상태 LED 중 3개도 켜집니다. 이것은 하나의 음성 인식 엔진이 Arduino에 할당되었음을 의미합니다. 이제부터 로봇이 명령을 내릴 준비가 되었습니다.

    로봇으로 몇 가지 테스트를 한 후 음성 인식에 꽤 만족했습니다. 비록 항상 명령을 100% 인식하지는 못했지만 말입니다. 이 측면에서 BitVoicer Server는 저를 정말 놀라게 했습니다. 하지만 로봇의 움직임의 정확성은 그다지 만족스럽지 못했습니다. 이 문제를 해결하려면 바퀴에 회전 센서를 추가해야 합니다. 로봇에서 사용한 섀시 키트에는 기어에 부착할 수 있는 디코더 디스크가 이미 포함되어 있습니다. 이 디스크에 센서를 적용하면 실제 이동 거리를 기반으로 로봇을 움직여 더 정확하게 움직일 수 있습니다. 가구 주변에 부딪히는 것을 방지하기 위해 초음파 센서를 추가할 수도 있습니다. 언젠가는 그렇게 하겠지만, 지금은 당신에게 맡깁니다.

    다음에 만나요!


    <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • WiFi 모듈 설정
  • 로봇 소스 코드
  • WiFi 모듈 설정Arduino
    Arduino 직렬 포트를 사용하여 Microchip WiFi RN171VX 모듈을 구성합니다.
    void setup() { Serial.begin(115200); 핀모드(13, 출력); 지연(5000); Serial.print("$$$"); 지연(1000); Serial.println("wlan 인증 4를 설정합니다."); 지연(1000); Serial.println("WLAN 구문 XXXXXX 설정"); 지연(1000); Serial.println("wlan ssid XXXXXX 설정"); 지연(1000); Serial.println("WLAN 채널 0을 설정합니다."); 지연(1000); Serial.println("WLAN 조인 1 설정"); 지연(1000); Serial.println("wlan tx 0으로 설정"); 지연(1000); Serial.println("ip dhcp 0으로 설정"); 지연(1000); Serial.println("IP 주소 XXXXXX 설정"); 지연(1000); Serial.println("통신 리모트 0번 설정"); 지연(1000); Serial.println("통신 닫기 0으로 설정"); 지연(1000); Serial.println("통신 열기 0으로 설정"); 지연(1000); Serial.println("통신 크기를 500으로 설정합니다."); 지연(1000); Serial.println("통신 시간을 50으로 설정합니다."); 지연(1000); Serial.println("uart baud 115200으로 설정"); 지연(1000); Serial.println("uart 흐름 0으로 설정"); 지연(1000); Serial.println("저장"); 지연(1000); Serial.println("종료"); 지연(1000); digitalWrite(13, LOW);}무효 루프() { }
    로봇 소스 코드Arduino
    로봇 움직임을 제어하고, 오디오를 캡처하고, TCP/IP 연결을 관리하고 BitVoicer 서버와 통신합니다.
    #include #include #include // Arduino 핀을 정의합니다. // LED를 제어하고 오디오를 캡처하는 데 사용됩니다.#define BVS_RUNNING 2#define BVS_SRE 5#define BVS_DATA_FWD 3#define BVS_ACT_PERIOD 6#define BVSM_AUDIO_INPUT 3// BVSP를 시작하기 위해 매개변수로 전달할 상수를 정의합니다. functionconst unsigned long STATUS_REQUEST_INTERVAL =2000;const unsigned long STATUS_REQUEST_TIMEOUT =1000;// Defines the size of the mic bufferconst int MIC_BUFFER_SIZE =64;// Initializes a new global instance of the BVSP classBVSP bvsp =BVSP();// Initializes a new global instance of the BVSMic classBVSMic bvsm =BVSMic();// Initializes a new global instance of the // DualMC33926MotorShield classDualMC33926MotorShield ms =DualMC33926MotorShield();// Creates a buffer that will be used to read recorded samples // from the BVSMic classbyte micBuffer[MIC_BUFFER_SIZE];// Creates a global variable that indicates whether the // Arduino is connected to BitVoicer Serverboolean connected =false;// Defines some constants for the motor settingsconst int SPEED_STOP =0;const int SPEED_SLOW =100;const int SPEED_NORMAL =250;const int SPEED_FAST =400;const int DIRECTION_FRONT =-1;const int DIRECTION_BACK =1;// Declares a global variables to hold the current motor speed.// The default is SPEED_NORMAL, but there are voice // commands that change this setting.int motorSpeed =SPEED_NORMAL;// Stores the command duration in millisecondsunsigned long cmdDuration =0;// Stores the time the command started runningunsigned long cmdStartTime =0;// Stores whether a command is running or notbool cmdRunning =false;// Stores the last MOVE_FORWARD command. This variable // is used only for the COME_BACK command.byte lastFwdCmd =0;// Defines some constants for command names/values// Just to make the code more readableconst byte CMD_STOP =0;const byte CMD_MOVE_FORWARD =1;const byte CMD_MOVE_FORWARD_1_CM =2;const byte CMD_MOVE_FORWARD_2_CM =3;const byte CMD_MOVE_FORWARD_5_CM =4;const byte CMD_MOVE_FORWARD_10_CM =5;const byte CMD_MOVE_FORWARD_25_CM =6;const byte CMD_MOVE_FORWARD_50_CM =7;const byte CMD_MOVE_FORWARD_1_M =8;const byte CMD_MOVE_BACKWARD =9;const byte CMD_MOVE_BACKWARD_1_CM =10;const byte CMD_MOVE_BACKWARD_2_CM =11;const byte CMD_MOVE_BACKWARD_5_CM =12;const byte CMD_MOVE_BACKWARD_10_CM =13;const byte CMD_MOVE_BACKWARD_25_CM =14;const byte CMD_MOVE_BACKWARD_50_CM =15;const byte CMD_MOVE_BACKWARD_1_M =16;const byte CMD_TURN_AROUND =17;const byte CMD_TURN_AROUND_RIGHT =18;const byte CMD_TURN_AROUND_LEFT =19;const byte CMD_DO_360 =20;const byte CMD_TURN_RIGHT =21;const byte CMD_TURN_RIGHT_10 =22;const byte C MD_TURN_RIGHT_25 =23;const byte CMD_TURN_RIGHT_45 =24;const byte CMD_TURN_LEFT =25;const byte CMD_TURN_LEFT_10 =26;const byte CMD_TURN_LEFT_25 =27;const byte CMD_TURN_LEFT_45 =28;const byte CMD_DO_CIRCLE =29;const byte CMD_COME_BACK =30;const byte CMD_MOVE_FORWARD_2_M =31;const byte CMD_MOVE_FORWARD_3_M =32;const byte CMD_MOVE_BACKWARD_2_M =33;const byte CMD_MOVE_BACKWARD_3_M =34;const byte CMD_SET_SPEED_SLOW =35;const byte CMD_SET_SPEED_NORMAL =36;const byte CMD_SET_SPEED_FAST =37;const byte CMD_TURN_LEFT_45_BACKWARD =38;const byte CMD_TURN_RIGHT_45_BACKWARD =39;void setup(){ // Starts serial communication at 115200 bps Serial.begin(115200); // Sets the Arduino pin modes pinMode(BVS_RUNNING, OUTPUT); pinMode(BVS_SRE, OUTPUT); pinMode(BVS_DATA_FWD, OUTPUT); pinMode(BVS_ACT_PERIOD, OUTPUT); AllLEDsOff(); // Sets the Arduino serial port that will be used for // communication, how long it will take before a status request // times out and how often status requests should be sent to // BitVoicer Server bvsp.begin(Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Sets the function that will handle the frameReceived // event bvsp.frameReceived =BVSP_frameReceived; // Prepares the BVSMic class timer bvsm.begin(); // Prepares the motor shield class (pins and timer1) ms.init();}void loop() { // If it is not connected to the server, opens a TCP/IP // connection, sets connected to true and resets the BVSP // class if (!connected) { Connect(Serial); connected =true; bvsp.reset(); } // Checks if the status request interval has elapsed and if it // has, sends a status request to BitVoicer Server bvsp.keepAlive(); // Checks if there is data available at the serial port buffer // and processes its content according to the specifications // of the BitVoicer Server Protocol bvsp.receive(); // Gets the respective status from the BVSP class and sets // the LEDs on or off digitalWrite(BVS_RUNNING, bvsp.isBVSRunning()); digitalWrite(BVS_DATA_FWD, bvsp.isDataFwdRunning()); // Checks if there is a SRE assigned to the Arduino if (bvsp.isSREAvailable()) { // Turns on the SRE available LED digitalWrite(BVS_SRE, HIGH); // If the BVSMic class is not recording, sets up the audio // input and starts recording if (!bvsm.isRecording) { bvsm.setAudioInput(BVSM_AUDIO_INPUT, EXTERNAL); bvsm.startRecording(); } // Checks if the BVSMic class has available samples if (bvsm.available) { // Makes sure the inbound mode is STREAM_MODE before // transmitting the stream if (bvsp.inboundMode ==FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE); // Reads the audio samples from the BVSMic class int bytesRead =bvsm.read(micBuffer, MIC_BUFFER_SIZE); // Sends the audio stream to BitVoicer Server bvsp.sendStream(micBuffer, bytesRead); } } else { // There is no SRE available // Turns off the SRE and ACT_PERIOD LEDs digitalWrite(BVS_SRE, LOW); digitalWrite(BVS_ACT_PERIOD, LOW); // If the BVSMic class is recording, stops it if (bvsm.isRecording) bvsm.stopRecording(); } // If the status has timed out, the connection is considered // lost if (bvsp.hasStatusTimedOut()) { // If the BVSMic is recording, stops it if (bvsm.isRecording) bvsm.stopRecording(); // Closes the TCP/IP connection Disconnect(Serial); AllLEDsOff(); connected =false; } // If a command is running, checks if its duration has // expired. If it has, stop the motors. if (cmdRunning) if (millis() - cmdStartTime>=cmdDuration) RunCommand(CMD_STOP);}// Handles the frameReceived eventvoid BVSP_frameReceived(byte dataType, int payloadSize){ // Performs the appropriate actions based on the frame // data type. If the data type is byte, it is a command. // If the data type is int, changes the activated // period LED. switch (dataType) { case DATA_TYPE_BYTE:RunCommand(bvsp.getReceivedByte()); 부서지다; case DATA_TYPE_INT16:digitalWrite(BVS_ACT_PERIOD, bvsp.getReceivedInt16()); 부서지다; }}// Runs the command received from the servervoid RunCommand(byte cmd){ switch (cmd) { case CMD_STOP:ms.setSpeeds(SPEED_STOP, SPEED_STOP); cmdRunning =false; 반품; case CMD_MOVE_FORWARD:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =60000; 부서지다; case CMD_MOVE_FORWARD_1_CM:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =23; 부서지다; case CMD_MOVE_FORWARD_2_CM:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =47; 부서지다; case CMD_MOVE_FORWARD_5_CM:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =117; 부서지다; case CMD_MOVE_FORWARD_10_CM:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =234; 부서지다; case CMD_MOVE_FORWARD_25_CM:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =468; 부서지다; case CMD_MOVE_FORWARD_50_CM:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =1170; 부서지다; case CMD_MOVE_FORWARD_1_M:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =2339; 부서지다; case CMD_MOVE_FORWARD_2_M:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =4678; 부서지다; case CMD_MOVE_FORWARD_3_M:lastFwdCmd =cmd; ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_FRONT); cmdDuration =7018; 부서지다; case CMD_MOVE_BACKWARD:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =60000; 부서지다; case CMD_MOVE_BACKWARD_1_CM:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =23; 부서지다; case CMD_MOVE_BACKWARD_2_CM:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =47; 부서지다; case CMD_MOVE_BACKWARD_5_CM:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =117; 부서지다; case CMD_MOVE_BACKWARD_10_CM:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =234; 부서지다; case CMD_MOVE_BACKWARD_25_CM:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =468; 부서지다; case CMD_MOVE_BACKWARD_50_CM:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =1170; 부서지다; case CMD_MOVE_BACKWARD_1_M:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =2339; 부서지다; case CMD_MOVE_BACKWARD_2_M:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =4678; 부서지다; case CMD_MOVE_BACKWARD_3_M:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_BACK); cmdDuration =7017; 부서지다; case CMD_TURN_AROUND:ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_BACK); cmdDuration =540; 부서지다; case CMD_TURN_AROUND_RIGHT:ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_BACK); cmdDuration =540; 부서지다; case CMD_TURN_AROUND_LEFT:ms.setSpeeds( motorSpeed * DIRECTION_BACK, motorSpeed * DIRECTION_FRONT); cmdDuration =540; 부서지다; case CMD_DO_360:ms.setSpeeds( motorSpeed * DIRECTION_FRONT, motorSpeed * DIRECTION_BACK); cmdDuration =1065; 부서지다; case CMD_TURN_RIGHT:ms.setSpeeds(motorSpeed * DIRECTION_FRONT, 0); cmdDuration =503; 부서지다; case CMD_TURN_RIGHT_10:ms.setSpeeds(motorSpeed * DIRECTION_FRONT, 0); cmdDuration =56; 부서지다; case CMD_TURN_RIGHT_25:ms.setSpeeds(motorSpeed * DIRECTION_FRONT, 0); cmdDuration =140; 부서지다; case CMD_TURN_RIGHT_45:ms.setSpeeds(motorSpeed * DIRECTION_FRONT, 0); cmdDuration =252; 부서지다; case CMD_TURN_LEFT:ms.setSpeeds(0, motorSpeed * DIRECTION_FRONT); cmdDuration =503; 부서지다; case CMD_TURN_LEFT_10:ms.setSpeeds(0, motorSpeed * DIRECTION_FRONT); cmdDuration =56; 부서지다; case CMD_TURN_LEFT_25:ms.setSpeeds(0, motorSpeed * DIRECTION_FRONT); cmdDuration =140; 부서지다; case CMD_TURN_LEFT_45:ms.setSpeeds(0, motorSpeed * DIRECTION_FRONT); cmdDuration =252; 부서지다; case CMD_DO_CIRCLE:ms.setSpeeds( SPEED_NORMAL * DIRECTION_FRONT, SPEED_NORMAL * DIRECTION_FRONT * 0.60); cmdDuration =4587; 부서지다; case CMD_COME_BACK:RunCommand(lastFwdCmd); 반품; case CMD_SET_SPEED_SLOW:motorSpeed =SPEED_SLOW; 반품; case CMD_SET_SPEED_NORMAL:motorSpeed =SPEED_NORMAL; 반품; case CMD_SET_SPEED_FAST:motorSpeed =SPEED_FAST; 반품; case CMD_TURN_LEFT_45_BACKWARD:ms.setSpeeds(motorSpeed * DIRECTION_BACK, 0); cmdDuration =252; 부서지다; case CMD_TURN_RIGHT_45_BACKWARD:ms.setSpeeds(0, motorSpeed * DIRECTION_BACK); cmdDuration =252; 부서지다; } // Sets the command start time cmdStartTime =millis(); // Sets cmdRunning to true cmdRunning =true;}// Opens a TCP/IP connection with the BitVoicer Servervoid Connect(HardwareSerial &serialPort){ serialPort.print("$$$"); 지연(500); // Use the IP address of the server and the TCP port set // in the server properties serialPort.println("open 192.168.0.11 4194"); 지연(1000); serialPort.println("exit"); delay(500);}// Closes the TCP/IP connection with the BitVoicer Servervoid Disconnect(HardwareSerial &serialPort){ serialPort.print("$$$"); 지연(500); serialPort.println("close"); 지연(1000); serialPort.println("exit"); delay(500);}// Turns all LEDs offvoid AllLEDsOff(){ digitalWrite(BVS_RUNNING, LOW); digitalWrite(BVS_SRE, LOW); digitalWrite(BVS_DATA_FWD, LOW); digitalWrite(BVS_ACT_PERIOD, LOW);}

    회로도


    제조공정

    1. Bluetooth를 통해 제어되는 Raspberry Pi Robot
    2. Arduino 및 Raspberry Pi로 인터넷 제어 비디오 스트리밍 로봇 구축
    3. Python과 함께 Arduino 및 RFID를 사용한 출석 시스템
    4. NeoPixel Ring으로 재미있는 자이로스코프
    5. Raspberry Motor Shield를 사용한 Android 제어 장난감
    6. 서보 모터로 로봇을 피하는 장애물
    7. Arduino 및 Android 기기로 Roomba 로봇 제어
    8. Nunchuk 제어 로봇 팔(Arduino 포함)
    9. 음성 제어 로봇
    10. OK Google이 포함된 Bluetooth 음성 제어 기기