Aufgabenstellung
Es wird eine Lösung benötigt, um einen Arduino Microcontroller als USB Host zu betreiben, welcher selber die Stromversorgung der angeschlossenen USB-Geräte übernimmt. Für die einfache Erweiterung des Bausatzes existieren sogenannte „Shields“, welche eine preiswerte Lösung ohne die Notwendigkeit eines eigenen Platinenentwurfs zur Verfügung stellen.
Ansatz
Durch die Verwendung des USB Host Shields von DFRobot.com lässt sich über eine Aufsteckvariante über die SPI Schnittstelle und existierender, fertiger Bibliotheken eine solche Konfiguration schnell umsetzen.
Im Nachfolgebeispiel wird der bereits existierende Roboter (siehe Kategorie Mikrocontroller) mit einem Arduino Duemilanove (Arduino UNO kombatibel) und dem USB Host Shield ausgestattet. Dieser wird über eine USB Tastatur gesteuert.
Lösung
Arduino Duemilanove mit USB Host Shield (Pan&Tilt Servos, Tamiya Twin Motor Gear Box…)
Code
Der Code benutzt die downloadbare Bibliothek des USB Host Shields, welche sich nach dem Kopieren in die Arduino IDE verwenden lässt. Darüber hinaus wird der Pan and Tilt Servo über die Servo-Bibliothek gesteuert.
#include <avr/pgmspace.h> #include <avrpins.h> #include <max3421e.h> #include <usbhost.h> #include <usb_ch9.h> #include <Usb.h> #include <usbhub.h> #include <avr/pgmspace.h> #include <address.h> #include <hidboot.h> #include <printhex.h> #include <message.h> #include <hexdump.h> #include <parsetools.h> #include <Servo.h> int E1 = 6; //M1 Speed Control int E2 = 5; //M2 Speed Control int M1 = 8; //M1 Direction Control int M2 = 7; //M2 Direction Control Servo myservo; // create servo object to control a servo Servo myservo2; // create servo object to control a servo int horizontal=64; int vertical=64; boolean servoLeft = false; boolean servoRight = false; boolean servoUp = false; boolean servoDown = false; class KbdRptParser : public KeyboardReportParser { void PrintKey(uint8_t mod, uint8_t key); protected: virtual void OnKeyDown (uint8_t mod, uint8_t key); virtual void OnKeyUp (uint8_t mod, uint8_t key); virtual void OnKeyPressed(uint8_t key); }; void KbdRptParser::PrintKey(uint8_t m, uint8_t key) { MODIFIERKEYS mod; *((uint8_t*)&mod) = m; Serial.print((mod.bmLeftCtrl == 1) ? "C" : " "); Serial.print((mod.bmLeftShift == 1) ? "S" : " "); Serial.print((mod.bmLeftAlt == 1) ? "A" : " "); Serial.print((mod.bmLeftGUI == 1) ? "G" : " "); Serial.print(" >"); PrintHex<uint8_t>(key); Serial.print("< "); Serial.print((mod.bmRightCtrl == 1) ? "C" : " "); Serial.print((mod.bmRightShift == 1) ? "S" : " "); Serial.print((mod.bmRightAlt == 1) ? "A" : " "); Serial.println((mod.bmRightGUI == 1) ? "G" : " "); }; void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) { Serial.print("DN "); PrintKey(mod, key); uint8_t c = OemToAscii(mod, key); int leftspeed = 255; //255 is maximum speed int rightspeed = 255; switch(key) { case 0x50: { horizontal-=10; } break; case 0x4F: { horizontal+=10; } break; case 0x52: { vertical-=10; } break; case 0x51: { vertical+=10; } break; case 0x5C: { left (leftspeed,rightspeed); } break; case 0x5E: { right (leftspeed,rightspeed); } break; case 0x60: { forward (leftspeed,rightspeed); } break; case 0x5A: { reverse (leftspeed,rightspeed); } break; case 0x5D: { stop(); } break; } if (horizontal <= 1 || horizontal >=128) horizontal=64; if (vertical <= 1 || vertical >=128) vertical=64; if (c) OnKeyPressed(c); } void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) { Serial.print("UP "); PrintKey(mod, key); } void KbdRptParser::OnKeyPressed(uint8_t key) { Serial.print("ASCII: "); Serial.println((char)key); }; USB Usb; //USBHub Hub(&Usb); HIDBoot<HID_PROTOCOL_KEYBOARD> Keyboard(&Usb); uint32_t next_time; KbdRptParser Prs; void setup() { // attaches the servo on pin 2 to the servo object myservo.attach(2); // attaches the servo on pin 3 to the servo object myservo2.attach(3); Serial.begin( 9600 ); Serial.println("Start"); if (Usb.Init() == -1) Serial.println("OSC did not start."); delay( 200 ); next_time = millis() + 5000; Keyboard.SetReportParser(0, (HIDReportParser*)&Prs); } void loop() { /* if(servoLeft) horizontal-=10; if(servoRight) horizontal+=10; if(servoUp) vertical-=10; if(servoDown) vertical+=10; */ // sets the servo position according to the scaled value myservo.write(horizontal); // sets the servo position according to the scaled value myservo2.write(vertical); Serial.println("Horizontal: "+horizontal ); Serial.println("Vertical: "+vertical ); Usb.Task(); } void stop(void) //Stop { digitalWrite(E1,LOW); digitalWrite(E2,LOW); } void forward(char a,char b) { analogWrite (E1,a); digitalWrite(M1,LOW); analogWrite (E2,b); digitalWrite(M2,LOW); } void reverse (char a,char b) { analogWrite (E1,a); digitalWrite(M1,HIGH); analogWrite (E2,b); digitalWrite(M2,HIGH); } void left (char a,char b) { analogWrite (E1,a); digitalWrite(M1,HIGH); analogWrite (E2,b); digitalWrite(M2,LOW); } void right (char a,char b) { analogWrite (E1,a); digitalWrite(M1,LOW); analogWrite (E2,b); digitalWrite(M2,HIGH); }