Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Bedien Arduino Rover met Firmata en Xbox One Controller

Componenten en benodigdheden

Microsoft Xbox-controller en draadloze adapter voor Windows
Deze controller kan worden toegevoegd aan een Windows-pc met behulp van de adapter
× 1
SparkFun Bluetooth-modem - BlueSMiRF Zilver
Of een identieke (HC-05, HC-06) Bluetooth-module
× 1
Arduino UNO
× 1

Apps en online services

Microsoft Windows 10 IoT Core
Deze app is het tussenproduct tussen de standaard Firmata-schets en de Xbox One-controller

Over dit project

Een paar maanden geleden kocht ik een kleine rover (bestuurd door een Arduino Uno) voor een zeer goede prijs. De kit was zeer compleet:autochassis, 2 autowielen, 2 DC-reductiemotoren, een UNO R3, een L298N Dual H-Bridge-motorcontroller en verschillende andere componenten.

Deze rover is bedoeld om te worden geprogrammeerd voor autonoom rijden. Daarom is er ook een ultrasone sensor en een servo in de kit toegevoegd. Ook zit er een mooie Arduino sensor shield 5 in de kit. Ja, het was echt een koopje;-)

Maar mijn idee was om zowel een Xbox One-controller als het Firmata-protocol te gebruiken om deze alleen of een van mijn zonen te besturen. En het werkt erg goed!

Hier is een video van de uiteindelijke oplossing:

De belangrijkste onderdelen die in dit project worden gebruikt, zijn:

  • Een rover-kit (we gebruiken voor deze demonstratie slechts een subset van de onderdelen:de grondplaat, de wielen, de motoren, de Arduino Uno, de 9 volt batterijhouder en de L298N Dual H-Bridge Motor Controller)
  • li>
  • Een extra batterijhouder voor 6 AA-batterijen
  • Een Bluetooth-module (HC-06)
  • Een Xbox One-controller met draadloze adapter voor Windows (om hem op een laptop aan te sluiten)
  • Een laptop (met Windows 10 + VS2015 + Bluetooth-dongle)
  • Alleen een knipperend licht voor een dramatisch effect

De kit bouwen

Het bouwen van de kit is niet zo moeilijk. Hoewel de bouwhandleiding in het Chinees was, lijkt het allemaal vrij logisch. Er is maar één bodemplaat, dus ik moest er wat componenten bovenop plaatsen en een aantal onderaan (nu de motorcontroller):

Op deze foto zijn twee verschillende batterijhouders toegevoegd. Tijdens het programmeren kwam ik erachter dat ik een aparte voeding moest gebruiken om de motoren aan de praat te krijgen.

De motoren aansluiten - pinlay-out van de controller

Het hart van de hardware is deze keer niet de Arduino Uno maar de motorcontroller.

“De L298 is een dubbele H-bridge driver voor DC brushed motoren en stappenmotoren. Het ondersteunt een breed bedrijfsspanningsbereik en kan 2 A per kanaal leveren in een doorlopende verpakking die toegankelijk is voor doe-het-zelfprojecten.'

Deze controller regelt de snelheid en richting van elk van de twee motoren, met behulp van signalen afkomstig van de Arduino.

De pinlay-out van de L298N Dual H-Bridge-motorcontroller  is:

  • Plus + van DC-motor 1
  • Minus – van gelijkstroommotor 1
  • Voeding IN. Ik lever 9 volt uit een aparte batterijhouder
  • Gemeenschappelijke grond. Verbonden met zowel mijn aparte batterijhouder als de Arduino
  • Stroom uit . Kan 5 volt produceren (niet gebruikt . Mijn Arduino krijgt stroom van een andere batterijhouder)
  • ENA aangesloten op Arduino D10. Deze poort is geschikt voor PWM (wit)
  • IN1 aangesloten op Arduino D9. (grijs)
  • IN2 aangesloten op Arduino D8. (paars)
  • IN3 aangesloten op Arduino D7. (blauw)
  • IN4 aangesloten op Arduino D6. (groen)
  • ENB aangesloten op Arduino D5. Deze poort is geschikt voor PWM (geel)
  • Plus + van DC-motor 2
  • Minus – van gelijkstroommotor 2
  • De jumper naast 2 en 3 is NIET verwijderd omdat ik het ingangsvermogen niet overschrijd boven 12 volt (tot 35 volt) (jumper niet gemarkeerd op de afbeelding)

Let op:de controller heeft een eigen voeding. De Arduino heeft er ook een. Om dingen draaiende te houden (zonder de boel op te blazen, geef ze een gemeenschappelijke basis . Zie opsommingsteken 4 hierboven)

De motoren aansluiten - pinlay-out van Arduino

Het aansluiten van de Arduino is vrij eenvoudig. We verbinden de aarde en de 5 volt van de voeding met de Arduino. En we verbinden de zes lijnen (ENA, IN1-4 en ENB) met pin D10 t/m D5.

Het mag duidelijk zijn dat poort 7 en 8 (en 9 en 10 voor de andere motor) gewoon een gewone GPIO-poort zijn. Deze worden gebruikt voor de richting van de motor. Als beide poorten (bijv. 7 en 8) LAAG zijn, doet de motor niets (hij stopt). Als de ene HOOG is en de andere LAAG, zal de motor in één richting draaien. Als de motor andersom is aangesloten (de eerste is ingesteld op LAAG en de andere op HOOG), zal de aangesloten motor in de andere richting draaien.

Maar... alleen het instellen van deze pinnen levert niets op. Nog geen bewegende delen!

De magie komt van pin 5 en 10. Dit zijn ‘speciale’ pinnen die een PWM-signaal kunnen genereren. Als u een waarde tussen 0 en 255 instelt, zal de motor ZEER langzaam (gestopt) of op hoge snelheid lopen.

Opmerking:elke poort op de Arduino Uno die PWM kan, is gemarkeerd met een tilde (de ~).

De Bluetooth verbinden

De Bluetooth-module die ik gebruik, hoeft alleen te worden aangesloten op de RX- en TX-poort (kruis de lijnen) en heeft 5 volt stroom en aarde van de Arduino nodig.

Firmata-schets op de Arduino

De Firmata-schets "StandardFirmata" is alles wat we nodig hebben op de Arduino! Haal het gewoon uit de Arduino IDE-voorbeelden en upload het (misschien moet je eerst de TX/RX losmaken om de upload te voltooien).

Opmerking:vanwege het gebrek aan kwaliteit van mijn Bluetooth-module, verlaag ik altijd de baudrate die hard gecodeerd is in de schets en stel deze in op 9600.

Heren, start uw motoren

Of test de verbinding...

Dus waarom gebruik ik Firmata? omdat het gemakkelijk is. Hoe makkelijk? Erg makkelijk. En het kan zelfs zonder programmeren. Start gewoon de Windows Remote Arduino Experience-app (verkrijgbaar in de winkel en werkt ook op een Windows 10 Mobile-apparaat).

Eerst moet je verbinding maken met de reeds gekoppelde HC-6 Bluetooth-module.

Ga na het koppelen naar de PWM-pagina. Schakel digitale pin 5 in en geef deze een waarde van bijvoorbeeld 128.

Let op:bij de volgende stap gaat je motor draaien. Helm op en wielen eraf. Als je het ziet, weet je waarom.

Ga dan naar de Digitale pagina. En zet de schakelaar van digitale pin 6 om.

Nu, als alles is aangesloten en draait, zal een van de motoren draaien!

Als dit het geval is, kunt u andere snelheden bekijken (met een hogere of lagere PWM-waarde) of de richting wijzigen (zet digitale pin 6 op 0 volt en digitale pin 7 op 5 volt).

En daar heb je het. Jij kunt dat stuur besturen!

Maar er is meer, hetzelfde geldt voor pin 10 (PWM) en digitale pin 9 en digitale pin 8.

Beide wielen draaien. Begin nu met coderen...

De UWP-app als matchmaker

Het moet duidelijk zijn dat we een nieuwe UWP-app nodig hebben tussen de Xbox One-controller en de rover.

Ik heb hier al geblogd over het gebruik van de Xbox One-controller. Deze keer zullen we die kennis combineren met onze rover.

Laten we eens kijken naar de interface van onze UWP-app:

Het is behoorlijk saai, twee knoppen en een tekstblok. Ik heb niets meer te doen dan eerst verbinding maken met de Arduino met behulp van Firmata. En als de verbinding eenmaal tot stand is gebracht, moet de controllerknop een gigantische lus starten om de controllerinvoer te lezen en deze om te zetten in bruikbare opdrachten.

En wat we willen creëren is deze klassieke tankbediening met twee handgrepen. Het enige dat we nodig hebben, is de twee thumbsticks op de Xbox One-controller te controleren. Door ze naar voren en naar achteren te bewegen, wordt ook de bijbehorende motor vooruit en achteruit gestart:

Opmerking:als u een nieuwe UWP-app start, vergeet dan niet de Bluetooth-mogelijkheid toe te voegen. En je zult het nuget-pakket voor Firmata moeten installeren.

Eerst voegen we het XAML-fragment (zie codegedeelte voor Xaml-broncode) toe aan het hoofdformulierraster, zodat we enkele knoppen hebben.

Vervolgens voegen we de code toe achter (zie codesectie voor C#-broncode) van het hoofdformulier. I is eigenlijk verdeeld in twee delen. Eerst maken we een verbinding via Bluetooth met het Firmata-protocol. Vervolgens beginnen we te luisteren naar invoer op de Xbox One-controller.

Binnen de lus voor het controleren van de bedieningselementen beslissen we of een thumbstick naar voren of naar achteren wijst of zich in het 'stop'-bereik bevindt. Daarna beslissen we wat de waarde voor de PWM-pin zal zijn.

Het is interessant om te zien dat het schrijven van een PWM-waarde in Firmata wordt weergegeven als het schrijven van een analoge waarde naar een digitale poort. Er is geen speciale PWM-methode in de Arduino-klasse.

Ik heb twee methoden "ArduinoDigitalWrite" en "ArduinoAnalogWrite" toegevoegd om te voorkomen dat dezelfde waarde steeds opnieuw naar de Arduino wordt geschreven. Dit vertroebelt de communicatie en verslechtert de prestaties van de Arduino. (In een veel rijker ontwerp heb ik een zoemer toegevoegd. Zonder dubbele opdrachten te negeren, was de prestatie van de zoemer extreem slecht en verschrikkelijk om te horen).

Wanneer de motoren de lage PMW-pulsen krijgen, begint de motor niet direct te draaien, maar jankt met een zeer kenmerkend geluid. Dit is normaal gedrag. En zo kwam ik erachter dat ik twee stroombronnen moest toevoegen. De eerste keer dat ik alles aansloot, dacht ik dat de controller kapot was. Er is niks gebeurd. Totdat ik een van de motoren loskoppelde en de andere begon te janken.

Dus zo werkt het:

Voetnoot:het knipperlicht is niet alleen voor een dramatisch effect. Wanneer uw creaties beginnen te bewegen, moet u zich bewust zijn van de veiligheid. Het ding is dom, jij niet! Daarom had ik deze lamp er in eerste instantie bovenop gezet.

Code

  • Xaml-bedieningselementen om de communicatie te starten
  • Code-Achter van het hoofdformulier van de UWP-app
Xaml-besturingselementen om de communicatiefragmenten te starten
Plak dit in het hoofdformulier van uw nieuwe UWP-app
 
Code-Achter van het hoofdformulier van de UWP-appC#
Deze code maakt verbinding met de rover met behulp van Firmata en geeft de opdrachten van de Xbox One Controller door
openbare verzegelde gedeeltelijke klasse MainPage :Page{ private BluetoothSerial _bluetooth; privé RemoteDevice _arduino; privé UwpFirmata _firmata =null; privé Gamepad _Gamepad =null; // Wij leveren nooit een PWM van meer dan 255 * 0,75 private double _SpeedLimit =0,75; // waarden onder deze absolute waarde stoppen de rover private double _ActionPoint =0.15; privébyte _LeftForward =6; privébyte _LeftBackward =7; privébyte _LeftValue =5; privébyte _RightForward =9; privébyte _RightBackward =8; privébyte _RightValue =10; privé Woordenboek _CurrentPinStates =nieuw Woordenboek(); privé Woordenboek _CurrentSpeedValues ​​=nieuw woordenboek(); public MainPage() { this.InitializeComponent(); } private void btnStart_Click (object afzender, RoutedEventArgs e) { btnStart.IsEnabled =false; Gamepad.GamepadAdded +=Gamepad_GamepadAdded; Gamepad.GamepadRemoved +=Gamepad_GamepadRemoved; _bluetooth =nieuwe BluetoothSerial ("HC-06"); _bluetooth.ConnectionLost +=BluetoothConnectionLost; _bluetooth.ConnectionFailed +=BluetoothConnectionFailed; _bluetooth.ConnectionEstablished +=OnConnectionEstablished; _firmata =nieuwe UwpFirmata(); _arduino =nieuw RemoteDevice(_firmata); _firmata.begin(_bluetooth); _bluetooth.begin (9600, SerialConfig.SERIAL_8N1); _arduino.DeviceReady +=ArduinoDeviceReady; } private async void BluetoothConnectionLost (string message) { wait Dispatcher.RunAsync ( CoreDispatcherPriority.Normal, () => { tbRead.Text ="ConnectionLost" + bericht;      btnStart.IsEnabled =true; }); } private async void BluetoothConnectionFailed (string message) { wait Dispatcher.RunAsync ( CoreDispatcherPriority.Normal, () => { tbRead.Text ="ConnectionFailed" + bericht;       btnStart.IsEnabled =true; }); } private async void ArduinoDeviceReady() { wacht op Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => { tbRead.Text ="Device Ready"; }); } private void OnConnectionEstablished() {var action =Dispatcher.RunAsync( CoreDispatcherPriority.Normal, new DispatchedHandler(() => { DisableEnableButtons(true); ArduinoDigitalWrite(_LeftState, PinState.LOW); ArduinoDigitalWrite,(_LeftWrite,(_Digital.Backward); (_RightBackward, PinState.LOW); ArduinoDigitalWrite(_RightForward, PinState.LOW); })); } private void DisableEnableButtons (bool ingeschakeld) { // Schakel alle knoppen uit. Anders // drukt de 'A' op degene die is gefocust. btnController.IsEnabled =ingeschakeld; btnStart.IsEnabled =ingeschakeld; } private async void Gamepad_GamepadRemoved (object afzender, Gamepad e) { _Gamepad =null; wacht op Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () => { tbRead.Text ="Controller verwijderd"; }); } private async void Gamepad_GamepadAdded (object afzender, Gamepad e) { _Gamepad =e; wacht op Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => { tbRead.Text ="Controller toegevoegd"; }); } private async void btnController_Click (object afzender, RoutedEventArgs e) { DisableEnableButtons (false); while (true) { wacht op Task.Delay (TimeSpan.FromMilliseconds (3)); if (_Gamepad ==null) { doorgaan; } // Haal de huidige staat op var reading =_Gamepad.GetCurrentReading(); if (Math.Abs ​​(reading.LeftThumbstickY) <_ActionPoint) { ArduinoDigitalWrite (_LeftForward, PinState.LOW); ArduinoDigitalWrite(_LeftBackward, PinState.LOW); sldrLeftSpeed.Value =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.Value =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-poort, PinState-status) {// negeer dubbele opdrachten var exist =_CurrentPinStates.ContainsKey (poort); if (!bestaat || _CurrentPinStates[poort]!=staat) { _CurrentPinStates[poort] =staat; _arduino.digitalWrite(poort, staat); } } private void ArduinoAnalogWrite (byte-poort, ushort-waarde) {// negeer dubbele opdrachten var bestaat =_CurrentSpeedValues.ContainsKey (poort); if (!exists || _CurrentSpeedValues[poort]!=waarde) { _CurrentSpeedValues[poort] =waarde; _arduino.analogWrite(poort, waarde); } }}

Productieproces

  1. Aanwezigheidssysteem met Arduino en RFID met Python
  2. Universele afstandsbediening met Arduino, 1Sheeld en Android
  3. DIY voltmeter met Arduino en smartphone
  4. Ioed gebruiken om een ​​robotarm op afstand te bedienen
  5. Frequentie- en werkcyclusmeting met Arduino
  6. Sonar met arduino en weergave op verwerkings-IDE
  7. LED-helderheid regelen met Bolt en Arduino
  8. Eenvoudige en slimme robotarm met Arduino
  9. Volledige controle over uw tv met Alexa en Arduino IoT Cloud
  10. FM-radio met Arduino en RDA8057M
  11. Bedien uw lichtsysteem met een smartphone