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

Firmata 및 Xbox One 컨트롤러를 사용하여 Arduino Rover 제어

구성품 및 소모품

Windows용 Microsoft Xbox 컨트롤러 및 무선 어댑터
이 컨트롤러는 어댑터를 사용하여 Windows PC에 추가할 수 있습니다.
× 1
SparkFun 블루투스 모뎀 - BlueSMiRF 실버
또는 동일한(HC-05, HC-06) Bluetooth 모듈
× 1
Arduino UNO
× 1

앱 및 온라인 서비스

Microsoft Windows 10 IoT Core
이 앱은 표준 Firmata 스케치와 Xbox One 컨트롤러 사이의 중간입니다.

이 프로젝트 정보

몇 달 전에 나는 아주 좋은 가격에 작은 로버(Arduino Uno로 제어됨)를 샀습니다. 키트는 자동차 섀시, 자동차 바퀴 2개, DC 기어 모터 2개, UNO R3, L298N Dual H-Bridge 모터 컨트롤러 및 기타 여러 구성 요소로 매우 완벽했습니다.

이 로버는 자율 작동을 위해 프로그래밍되었습니다. 따라서 초음파 센서와 서보도 키트에 추가됩니다. 또한 멋진 Arduino 센서 실드 5가 키트에 있습니다. 네, 정말 저렴했습니다;-)

하지만 내 아이디어는 Xbox One 컨트롤러와 Firmata 프로토콜을 모두 사용하여 나 혼자 또는 내 아들 중 한 명이 이 컨트롤러를 운전하는 것이었습니다. 그리고 아주 잘 작동합니다!

다음은 최종 솔루션에 대한 동영상입니다.

이 프로젝트에 사용된 주요 부분은 다음과 같습니다.

<울>
  • 로버 키트(이 데모에서는 베이스 플레이트, 바퀴, 모터, Arduino Uno, 9볼트 배터리 홀더 및 L298N Dual H-Bridge 모터 컨트롤러와 같은 부품의 하위 집합만 사용합니다.)
  • AA 배터리 6개용 추가 배터리 홀더
  • 블루투스 모듈(HC-06)
  • Windows용 무선 어댑터가 있는 Xbox One 컨트롤러(노트북 연결용)
  • 노트북(Windows 10 + VS2015 + Bluetooth 동글 포함)
  • 극적인 효과만을 위한 번쩍이는 조명
  • 키트 제작

    키트를 만드는 것은 그렇게 어렵지 않습니다. 구성 설명서가 중국어로 되어 있지만 모두 꽤 논리적인 것 같습니다. 베이스 플레이트가 하나뿐이므로 일부 구성요소를 그 위에 놓고 일부 구성요소를 하단(지금은 모터 컨트롤러)에 배치해야 했습니다.

    이 그림에서 두 개의 다른 배터리 홀더가 추가되었습니다. 프로그래밍하는 동안 모터를 작동시키려면 별도의 전원 공급 장치를 사용해야 한다는 것을 알게 되었습니다.

    모터 연결 – 컨트롤러의 핀 배치

    이번에 하드웨어의 핵심은 아두이노 우노가 아니라 모터 컨트롤러다.

    “L298은 DC 브러시 모터와 스테퍼 모터를 위한 듀얼 H 브리지 드라이버입니다. 넓은 작동 전압 범위를 지원하며 DIY 프로젝트에 액세스할 수 있는 스루홀 패키지로 채널당 2A를 전달할 수 있습니다."

    이 컨트롤러는 Arduino에서 오는 신호를 사용하여 두 모터 각각의 속도와 방향을 제어합니다.

    L298N Dual H-Bridge 모터 컨트롤러의 핀 레이아웃은 다음과 같습니다.

    <울>
  • DC 모터 1의 플러스 +
  • - DC 모터 1의 마이너스
  • 전원 입력. 별도의 배터리 홀더에서 9볼트를 공급합니다.
  • 공통점. 별도의 배터리 홀더와 Arduino 모두에 연결
  • 전원 끄기 . 5볼트 생성 가능(사용하지 않음 . 내 Arduino는 다른 배터리 홀더에서 전원을 얻습니다)
  • 아두이노 D10에 연결된 ENA. 이 포트는 PWM(흰색)
  • 이 가능합니다.
  • IN1은 Arduino D9에 연결됩니다. (회색)
  • IN2는 Arduino D8에 연결됩니다. (보라색)
  • IN3는 Arduino D7에 연결됩니다. (파란색)
  • IN4는 Arduino D6에 연결됩니다. (녹색)
  • 아두이노 D5에 연결된 ENB. 이 포트는 PWM이 가능합니다(노란색)
  • DC 모터 2의 플러스 +
  • 마이너스 - DC 모터 2
  • 2 및 3 옆에 있는 점퍼 제거되지 않음 12볼트(최대 35볼트) 이상의 입력 전력을 초과하지 않기 때문에(점퍼는 그림에 표시되지 않음)
  • 참고:컨트롤러에는 자체 전원 공급 장치가 있습니다. Arduino에도 하나가 있습니다. 작업을 계속 실행하려면(얇아지지 않으면서 공통점을 제공하세요. . 위의 4번 항목 참조)

    모터 연결 – Arduino의 핀 레이아웃

    Arduino를 연결하는 것은 매우 간단합니다. 우리는 Arduino에 전원 공급 장치의 접지와 5V를 연결합니다. 그리고 6개의 라인(ENA, IN1-4 및 ENB)을 D10에서 D5까지 핀에 연결합니다.

    포트 7과 8(다른 모터의 경우 9와 10)은 일반 GPIO 포트라는 것이 분명해야 합니다. 이것들은 모터의 방향에 사용됩니다. 두 포트(예:7 및 8)가 모두 LOW이면 모터는 아무 작업도 수행하지 않습니다(정지). 하나가 HIGH이고 다른 하나가 LOW이면 모터는 한 방향으로 작동합니다. 반대로 연결하면(첫 번째는 LOW로, 다른 하나는 HIGH로 설정) 연결된 모터는 다른 방향으로 작동합니다.

    그러나 .. 이 핀을 설정하기만 하면 아무 것도 발생하지 않습니다. 아직 움직이는 부분이 없습니다!

    마법은 핀 5와 10에서 나옵니다. 이들은 PWM 신호를 생성할 수 있는 '특수' 핀입니다. 0과 255 사이의 값을 설정하면 모터가 매우 느리게(정지됨) 또는 고속으로 실행됩니다.

    참고:PWM이 가능한 Arduino Uno의 각 포트는 물결표(~)로 표시됩니다.

    블루투스 연결

    내가 사용하는 Bluetooth 모듈은 RX 및 TX 포트(선을 가로질러)에 연결하기만 하면 되며 Arduino에서 5볼트 전원과 접지가 필요합니다.

    Arduino의 Firmata 스케치

    Firmata 스케치 "StandardFirmata"는 Arduino에 필요한 전부입니다! Arduino IDE 예제에서 가져와서 업로드하면 됩니다(업로드를 완료하려면 먼저 TX/RX를 고정 해제해야 할 수도 있음).

    참고:블루투스 모듈의 품질 부족으로 인해 스케치 내부에 하드코딩된 전송 속도를 항상 낮추고 9600으로 설정합니다.

    여러분, 엔진 시동을 켜십시오.

    또는 연결을 테스트하십시오...

    그렇다면 내가 Firmata를 사용하는 이유는 무엇인가요? 쉽기 때문입니다. 얼마나 쉬운가? 아주 쉽게. 그리고 프로그래밍 없이도 가능합니다. Windows Remote Arduino Experience 앱을 시작하기만 하면 됩니다(스토어에서 사용 가능하며 Windows 10 Mobile 장치에서도 작동).

    먼저 이미 페어링된 HC-6 블루투스 모듈에 연결해야 합니다.

    페어링되면 PWM 페이지로 이동합니다. 디지털 핀 5를 활성화하고 값을 128로 지정합니다.

    주의:다음 단계에서는 모터가 작동합니다. 헬멧을 쓰고 밀가루를 떼십시오. 그 이유를 보면 알 수 있습니다.

    그런 다음 디지털 페이지로 이동합니다. 그리고 디지털 핀 6의 스위치를 뒤집습니다.

    이제 모든 것이 연결되어 작동하면 모터 중 하나가 회전합니다!

    그렇다면 다른 속도(더 높거나 낮은 PWM 값 사용)를 확인하거나 방향을 변경할 수 있습니다(디지털 핀 6을 0볼트로, 디지털 핀 7을 5볼트로 설정).

    그리고 거기에 있습니다. 당신은 그 바퀴를 제어할 수 있습니다!

    그러나 핀 10(PWM)과 디지털 핀 9 및 디지털 핀 8도 마찬가지입니다.

    두 바퀴가 달리고 있습니다. 이제 코딩을 시작하세요...

    중매인으로서의 UWP 앱

    Xbox One 컨트롤러와 로버 사이에 새로운 UWP 앱이 필요하다는 것이 분명합니다.

    여기에서 Xbox One 컨트롤러를 사용하는 방법에 대해 이미 블로그에 글을 올렸습니다. 이번에는 그 지식을 아웃로버와 결합해 보겠습니다.

    UWP 앱의 인터페이스를 살펴보겠습니다.

    그것은 꽤 둔하고 두 개의 버튼과 텍스트 블록입니다. 먼저 Firmata를 사용하여 Arduino에 연결한 다음에는 더 이상 할 일이 없습니다. 연결이 완료되면 컨트롤러 버튼은 컨트롤러 입력을 읽고 유용한 명령으로 변경하기 위해 하나의 거대한 루프를 시작해야 합니다.

    그리고 우리가 만들고자 하는 것은 두 개의 손잡이가 있는 이 고전적인 탱크 컨트롤입니다. Xbox One 컨트롤러에서 두 개의 썸스틱을 확인하기만 하면 됩니다. 그것들을 앞뒤로 움직이면 해당 모터도 앞뒤로 움직이기 시작합니다:

    참고:새 UWP 앱을 시작하는 경우 Bluetooth 기능을 추가하는 것을 잊지 마십시오. 그리고 Firmata용 nuget 패키지를 설치해야 합니다.

    먼저 메인폼 그리드에 XAML 스니펫(Xaml 소스 코드에 대한 코드 섹션 참조)을 추가하여 버튼이 몇 개 있습니다.

    다음으로 기본 양식의 코드 숨김(C# 소스 코드에 대한 코드 섹션 참조)을 추가합니다. 나는 기본적으로 두 부분으로 나뉩니다. 먼저 Firmata 프로토콜을 사용하여 Bluetooth를 통해 연결합니다. 다음으로 Xbox One 컨트롤러에서 입력을 수신하기 시작합니다.

    컨트롤을 확인하기 위한 루프 내에서 썸스틱이 앞뒤를 가리키고 있는지 또는 '정지' 범위에 있는지 결정합니다. 그런 다음 PWM 핀의 값을 결정합니다.

    PWM 값을 쓰는 것이 Firmata에서 디지털 포트에 아날로그 값을 쓰는 것으로 표현된다는 점은 흥미롭습니다. 아두이노 클래스에는 특별한 PWM 방식이 없습니다.

    Arduino에 같은 값을 계속해서 쓰는 것을 방지하기 위해 "ArduinoDigitalWrite"와 "ArduinoAnalogWrite"라는 두 가지 방법을 추가했습니다. 이것은 통신을 어지럽히고 Arduino의 성능을 저하시킵니다. (훨씬 더 풍부한 디자인에서 부저를 추가했습니다. 중복된 명령을 무시하지 않으면 부저의 성능이 매우 좋지 않고 듣기에 끔찍했습니다.)

    모터가 낮은 PMW 펄스를 얻으면 모터가 직접 작동을 시작하지 않고 매우 독특한 소리로 윙윙거릴 것입니다. 이것은 정상적인 동작입니다. 그리고 그렇게 해서 두 개의 전원을 추가해야 한다는 것을 알게 되었습니다. 처음 모든 것을 연결했을 때 컨트롤러가 고장난 줄 알았습니다. 아무 일도하지. 내가 모터 중 하나의 플러그를 뽑았고 다른 하나가 윙윙거리기 시작할 때까지.

    작동 방식은 다음과 같습니다.

    각주:깜박이는 빛은 극적인 효과만을 위한 것이 아닙니다. 창작물이 움직이기 시작할 때마다 안전에 유의하십시오. 장치는 바보입니다, 당신은 그렇지 않습니다! 그래서 저는 처음에 이 조명을 그 위에 뒀습니다.

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

    코드

    <울>
  • 통신 시작을 위한 Xaml 컨트롤
  • UWP 앱 메인폼의 코드 숨김
  • 통신을 시작하기 위한 Xaml 컨트롤스니펫
    이것을 새 UWP 앱의 기본 양식에 붙여넣습니다.
     
    UWP 앱 메인폼의 코드 숨김C#
    이 코드는 Firmata를 사용하여 로버에 연결하고 Xbox One 컨트롤러 명령을 전달합니다.
    public sealing partial class MainPage :Page{ private BluetoothSerial _bluetooth; 개인 RemoteDevice _arduino; 개인 UwpFirmata _firmata =null; 개인 게임 패드 _Gamepad =null; // 255 * 0,75 이상의 PWM은 제공하지 않습니다. private double _SpeedLimit =0.75; // 이 절대값 아래의 값은 로버를 중지합니다. private double _ActionPoint =0.15; 개인 바이트 _LeftForward =6; 개인 바이트 _LeftBackward =7; 개인 바이트 _LeftValue =5; 개인 바이트 _RightForward =9; 개인 바이트 _RightBackward =8; 개인 바이트 _RightValue =10; 개인 사전 _CurrentPinStates =new Dictionary(); 개인 사전 _CurrentSpeedValues ​​=새로운 사전(); 공개 MainPage() { this.InitializeComponent(); } 개인 무효 btnStart_Click(개체 발신자, RoutedEventArgs e) { btnStart.IsEnabled =false; Gamepad.GamepadAdded +=Gamepad_GamepadAdded; Gamepad.GamepadRemoved +=Gamepad_GamepadRemoved; _bluetooth =새로운 BluetoothSerial("HC-06"); _bluetooth.ConnectionLost +=BluetoothConnectionLost; _bluetooth.ConnectionFailed +=블루투스 연결 실패; _bluetooth.ConnectionEstablished +=OnConnectionEstablished; _firmata =새로운 UwpFirmata(); _arduino =새로운 원격 장치(_firmata); _firmata.begin(_블루투스); _bluetooth.begin(9600, SerialConfig.SERIAL_8N1); _arduino.DeviceReady +=ArduinoDeviceReady; } 비공개 비동기 무효 BluetoothConnectionLost(문자열 메시지) { 대기 Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { tbRead.Text ="ConnectionLost" + 메시지; btnStart.IsEnabled =true; }); } 비공개 비동기 무효 BluetoothConnectionFailed(문자열 메시지) { 대기 Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { tbRead.Text ="ConnectionFailed" + 메시지; btnStart.IsEnabled =true; }); } 개인 비동기 무효 ArduinoDeviceReady() { 대기 Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { tbRead.Text ="장치 준비"; }); } 개인 무효 OnConnectionEstablished() { var 작업 =Dispatcher.RunAsync( CoreDispatcherPriority.Normal, new DispatchedHandler(() => { DisableEnableButtons(true); ArduinoDigitalWrite(_LeftForward, PinState.LOW); ArduinoDigitalWrite(_LeftBackward, PinState.LOW); ArduinoDigitalWrite (_RightBackward, PinState.LOW);ArduinoDigitalWrite(_RightForward, PinState.LOW); })); } private void DisableEnableButtons(bool enabled) { // 모든 버튼을 비활성화합니다. 그렇지 않으면 // 'A'는 초점이 맞춰진 것을 누릅니다. btnController.IsEnabled =활성화됨; btnStart.IsEnabled =활성화됨; } 개인 비동기 무효 Gamepad_GamepadRemoved(개체 전송자, 게임 패드 e) { _Gamepad =null; 대기 Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { tbRead.Text ="컨트롤러 제거됨"; }); } 개인 비동기 무효 Gamepad_GamepadAdded(객체 전송자, 게임 패드 e) { _Gamepad =e; 대기 Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { tbRead.Text ="컨트롤러 추가됨"; }); } 개인 비동기 무효 btnController_Click(객체 발신자, RoutedEventArgs e) { DisableEnableButtons(false); while (true) { Task.Delay(TimeSpan.FromMilliseconds(3))를 기다립니다. if (_Gamepad ==null) { 계속; } // 현재 상태 가져오기 var reading =_Gamepad.GetCurrentReading(); if (Math.Abs(reading.LeftThumbstickY) <_ActionPoint) { ArduinoDigitalWrite(_LeftForward, PinState.LOW); ArduinoDigitalWrite(_LeftBackward, PinState.LOW); sldrLeftSpeed.값 =0; } else if (reading.LeftThumbstickY>=_ActionPoint) { ArduinoDigitalWrite(_LeftForward, PinState.HIGH); ArduinoDigitalWrite(_LeftBackward, PinState.LOW); sldrLeftSpeed.Value =255 * Math.Abs(reading.LeftThumbstickY) * _SpeedLimit; } else if (reading.LeftThumbstickY <=-_ActionPoint) { ArduinoDigitalWrite(_LeftForward, PinState.LOW); ArduinoDigitalWrite(_LeftBackward, PinState.HIGH); sldrLeftSpeed.Value =255 * Math.Abs(reading.LeftThumbstickY) * _SpeedLimit; } if (Math.Abs(reading.RightThumbstickY) <_ActionPoint) { ArduinoDigitalWrite(_RightForward, PinState.LOW); ArduinoDigitalWrite(_RightBackward, PinState.LOW); sldrRightSpeed.값 =0; } else if (reading.RightThumbstickY>=_ActionPoint) { ArduinoDigitalWrite(_RightForward, PinState.HIGH); ArduinoDigitalWrite(_RightBackward, PinState.LOW); sldrRightSpeed.Value =255 * Math.Abs(reading.RightThumbstickY) * _SpeedLimit; } else if (reading.RightThumbstickY <=-_ActionPoint) { ArduinoDigitalWrite(_RightForward, PinState.LOW); ArduinoDigitalWrite(_RightBackward, PinState.HIGH); sldrRightSpeed.Value =255 * Math.Abs(reading.RightThumbstickY) * _SpeedLimit; } } } private void ArduinoDigitalWrite(byte port, PinState state) { // 중복 명령 무시 var Existing =_CurrentPinStates.ContainsKey(port); if (!존재 || _CurrentPinStates[포트] !=상태) { _CurrentPinStates[포트] =상태; _arduino.digitalWrite(포트, 상태); } } private void ArduinoAnalogWrite(byte port, ushort value) { // 중복 명령 무시 var Existing =_CurrentSpeedValues.ContainsKey(port); if (!존재 || _CurrentSpeedValues[포트] !=값) { _CurrentSpeedValues[포트] =값; _arduino.analogWrite(포트, 값); } }}

    제조공정

    1. Python과 함께 Arduino 및 RFID를 사용한 출석 시스템
    2. Arduino, 1Sheeld 및 Android를 사용한 범용 원격 제어
    3. Arduino와 스마트폰을 사용한 DIY 전압계
    4. IoT를 사용하여 로봇 팔 원격 제어
    5. Arduino를 사용한 주파수 및 듀티 사이클 측정
    6. arduino를 사용한 소나 및 IDE 처리 시 표시
    7. 볼트와 Arduino를 사용하여 LED 밝기 제어
    8. Arduino를 사용한 간단하고 스마트한 로봇 팔
    9. Alexa 및 Arduino IoT Cloud를 사용하여 TV 전체 제어
    10. Arduino 및 RDA8057M을 사용하는 FM 라디오