INTRODUCTION
Even today most of the game is being played using smartphone, but we can’t argue that the gamepad is much more better for controlling game compare to the flat screen. So today I would like to try interfacing Logitech Wireless Gamepad F710 using Maker UNO (Arduino Uno compatible).
VIDEO
This video shows how to interface Logitech Wireless Gamepad F710 using Maker UNO.
HARDWARE PREPARATION
Below is the list of items used in the video.
Sample Code
This is the sample code used in the video. There have 3 files.
- le3dp_rptparser.cpp – this is supported file, please ensure the file name is same.
- le3dp_rptparser.h – this is supported file, please ensure the file name is same.
- MakerUNO_LogitechF710 – this is the main file.
#include "le3dp_rptparser.h" | |
JoystickReportParser::JoystickReportParser(JoystickEvents *evt) : | |
joyEvents(evt) | |
{} | |
void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) | |
{ | |
bool match = true; | |
// Checking if there are changes in report since the method was last called | |
for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) { | |
if( buf[i] != oldPad[i] ) { | |
match = false; | |
break; | |
} | |
} | |
// Calling Game Pad event handler | |
if (!match && joyEvents) { | |
joyEvents->OnGamePadChanged((const GamePadEventData*)buf); | |
for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) oldPad[i] = buf[i]; | |
} | |
} |
#if !defined(__HIDJOYSTICKRPTPARSER_H__) | |
#define __HIDJOYSTICKRPTPARSER_H__ | |
#include <usbhid.h> | |
struct GamePadEventData | |
{ | |
union { //axes and hut switch | |
uint32_t axes; | |
struct { | |
uint32_t x : 10; | |
uint32_t y : 10; | |
uint32_t hat : 4; | |
uint32_t twist : 8; | |
}; | |
}; | |
uint8_t buttons_a; | |
uint8_t slider; | |
uint8_t buttons_b; | |
}; | |
class JoystickEvents | |
{ | |
public: | |
virtual void OnGamePadChanged(const GamePadEventData *evt); | |
}; | |
#define RPT_GAMEPAD_LEN sizeof(GamePadEventData)/sizeof(uint8_t) | |
class JoystickReportParser : public HIDReportParser | |
{ | |
JoystickEvents *joyEvents; | |
uint8_t oldPad[RPT_GAMEPAD_LEN]; | |
public: | |
JoystickReportParser(JoystickEvents *evt); | |
virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf); | |
}; | |
#endif // __HIDJOYSTICKRPTPARSER_H__ |
/* Simplified Logitech Extreme 3D Pro Joystick Report Parser */ | |
#include <usbhid.h> | |
#include <hiduniversal.h> | |
#include <usbhub.h> | |
#include "le3dp_rptparser.h" | |
// Satisfy the IDE, which needs to see the include statment in the ino too. | |
#ifdef dobogusinclude | |
#include <spi4teensy3.h> | |
#endif | |
#include <SPI.h> | |
USB Usb; | |
USBHub Hub(&Usb); | |
HIDUniversal Hid(&Usb); | |
JoystickEvents JoyEvents; | |
JoystickReportParser Joy(&JoyEvents); | |
#define LED2 2 | |
#define LED3 3 | |
#define LED4 4 | |
#define LED5 5 | |
#define LED6 6 | |
#define LED7 7 | |
#define BUZZER 8 | |
#define NOTE_C4 262 | |
#define NOTE_E4 330 | |
#define NOTE_G4 392 | |
#define NOTE_C5 523 | |
int buttonXMelody[] = {NOTE_C4}; | |
int buttonXDurations[] = {8}; | |
int buttonAMelody[] = {NOTE_E4}; | |
int buttonADurations[] = {8}; | |
int buttonBMelody[] = {NOTE_G4}; | |
int buttonBDurations[] = {8}; | |
int buttonYMelody[] = {NOTE_C5}; | |
int buttonYDurations[] = {8}; | |
#define playButtonXMelody() playMelody(buttonXMelody, buttonXDurations, 1) | |
#define playButtonAMelody() playMelody(buttonAMelody, buttonADurations, 1) | |
#define playButtonBMelody() playMelody(buttonBMelody, buttonBDurations, 1) | |
#define playButtonYMelody() playMelody(buttonYMelody, buttonYDurations, 1) | |
volatile int ledPin = 0; | |
volatile byte F710Slider = 0x08; // Default value | |
volatile boolean beepFlag = false; | |
byte F710SliderLeft = 0x00; // Direction | |
byte F710SliderRight = 0x00; // Buttons | |
boolean F710ButtonX = false; | |
boolean F710ButtonA = false; | |
boolean F710ButtonB = false; | |
boolean F710ButtonY = false; | |
void setup() | |
{ | |
for (ledPin = 2; ledPin < 9; ledPin++) { | |
pinMode(ledPin, OUTPUT); | |
} | |
Serial.begin( 115200 ); | |
#if !defined(__MIPSEL__) | |
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection | |
#endif | |
Serial.println("Start"); | |
if (Usb.Init() == -1) | |
Serial.println("OSC did not start."); | |
delay( 200 ); | |
if (!Hid.SetReportParser(0, &Joy)) | |
ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1 ); | |
} | |
void loop() | |
{ | |
Usb.Task(); | |
// Direction button | |
F710SliderLeft = F710Slider & 0x0F; | |
if (F710SliderLeft == 0x08) { // Released all | |
} | |
else if (F710SliderLeft == 0x00) { // Up | |
digitalWrite(LED2, HIGH); | |
} | |
else if (F710SliderLeft == 0x01) { // Up + Right | |
digitalWrite(LED2, HIGH); | |
digitalWrite(LED3, HIGH); | |
} | |
else if (F710SliderLeft == 0x02) { // Right | |
digitalWrite(LED3, HIGH); | |
} | |
else if (F710SliderLeft == 0x03) { // Down + Right | |
digitalWrite(LED3, HIGH); | |
digitalWrite(LED4, HIGH); | |
} | |
else if (F710SliderLeft == 0x04) { // Down | |
digitalWrite(LED4, HIGH); | |
} | |
else if (F710SliderLeft == 0x05) { // Down + Left | |
digitalWrite(LED4, HIGH); | |
digitalWrite(LED5, HIGH); | |
} | |
else if (F710SliderLeft == 0x06) { // Left | |
digitalWrite(LED5, HIGH); | |
} | |
else if (F710SliderLeft == 0x07) { // Up + Left | |
digitalWrite(LED5, HIGH); | |
digitalWrite(LED6, HIGH); | |
} | |
// A B X Y buttons | |
F710SliderRight = F710Slider & 0xF0; | |
if (F710SliderRight == 0x00) { // No buttons | |
digitalWrite(LED7, LOW); | |
} | |
else { | |
beepFlag = true; | |
digitalWrite(LED7, HIGH); | |
F710ButtonX = F710SliderRight & 0x10; | |
F710ButtonA = F710SliderRight & 0x20; | |
F710ButtonB = F710SliderRight & 0x40; | |
F710ButtonY = F710SliderRight & 0x80; | |
if (F710ButtonX == true) { // Button X | |
if (beepFlag == true) { | |
beepFlag = false; | |
playButtonXMelody(); | |
} | |
} | |
if (F710ButtonA == true) { // Button A | |
if (beepFlag == true) { | |
beepFlag = false; | |
playButtonAMelody(); | |
} | |
} | |
if (F710ButtonB == true) { // Button B | |
if (beepFlag == true) { | |
beepFlag = false; | |
playButtonBMelody(); | |
} | |
} | |
if (F710ButtonY == true) { // Button Y | |
if (beepFlag == true) { | |
beepFlag = false; | |
playButtonYMelody(); | |
} | |
} | |
} | |
} | |
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) | |
{ | |
Serial.print("X: "); | |
PrintHex<uint16_t>(evt->x, 0x80); | |
Serial.print(" Y: "); | |
PrintHex<uint16_t>(evt->y, 0x80); | |
Serial.print(" Hat Switch: "); | |
PrintHex<uint8_t>(evt->hat, 0x80); | |
Serial.print(" Twist: "); | |
PrintHex<uint8_t>(evt->twist, 0x80); | |
Serial.print(" Slider: "); | |
F710Slider = evt->slider; | |
PrintHex<uint8_t>(F710Slider, 0x80); | |
Serial.print(" Buttons A: "); | |
PrintHex<uint8_t>(evt->buttons_a, 0x80); | |
Serial.print(" Buttons B: "); | |
PrintHex<uint8_t>(evt->buttons_b, 0x80); | |
Serial.println(""); | |
// Clear all LED for joystick buttons | |
for (ledPin = 2; ledPin < 8; ledPin++) { | |
digitalWrite(ledPin, LOW); | |
} | |
} | |
void playMelody(int *melody, int *noteDurations, int notesLength) | |
{ | |
for (int thisNote = 0; thisNote < notesLength; thisNote++) { | |
int noteDuration = 1000 / noteDurations[thisNote]; | |
tone(BUZZER, melody[thisNote], noteDuration); | |
int pauseBetweenNotes = noteDuration * 1.30; | |
delay(pauseBetweenNotes); | |
noTone(BUZZER); | |
} | |
} |
Thank You
References:
Thanks for reading this tutorial. If you have any technical inquiry, please post at Cytron Technical Forum.
3 thoughts on “Interfacing Logitech Wireless Gamepad F710 Using Arduino”
Sorry, it should be G-RC14.
Hi, I have a Logitech G-RC16 (Cordless Rumble 2). Can the USB host work it and is there a library available for it? Please advise. Thank you.
hi,
is it possible to run F710 dongle successfully at 3.3V only?
i have F710 gamepad, Teensy 3.0 (3.3V), USB Host Mini 2.0 (3.3V) and i want to run my project on the single LiPo accu and keep it very small and simple (without 3.3V to 5V StepUp…).
thanks!