R4 WiFi with USB Host Shield -> Native Host Mode

I just got the R4 WiFi. I've been playing with the matrix on it. Pretty cool.

I want to use it to read and xbox controller and send commands over wifi. I expected to find libraries that weren't ready yet.

I'm compiling the XBOXUSB.ino example code from the library.

/*
 Example sketch for the Xbox 360 USB library - developed by Kristian Lauszus
 For more information visit my blog: http://blog.tkjelectronics.dk/ or
 send me an e-mail:  kristianl@tkjelectronics.com
 */

#include <XBOXUSB.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;
XBOXUSB Xbox(&Usb);

void setup() {
  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
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nXBOX USB Library Started"));
}
void loop() {
  Usb.Task();
  if (Xbox.Xbox360Connected) {
    if (Xbox.getButtonPress(LT) || Xbox.getButtonPress(RT)) {
      Serial.print("LT: ");
      Serial.print(Xbox.getButtonPress(LT));
      Serial.print("\tRT: ");
      Serial.println(Xbox.getButtonPress(RT));
      Xbox.setRumbleOn(Xbox.getButtonPress(LT), Xbox.getButtonPress(RT));
    } else
      Xbox.setRumbleOn(0, 0);

    if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
      if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) {
        Serial.print(F("LeftHatX: "));
        Serial.print(Xbox.getAnalogHat(LeftHatX));
        Serial.print("\t");
      }
      if (Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) {
        Serial.print(F("LeftHatY: "));
        Serial.print(Xbox.getAnalogHat(LeftHatY));
        Serial.print("\t");
      }
      if (Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) {
        Serial.print(F("RightHatX: "));
        Serial.print(Xbox.getAnalogHat(RightHatX));
        Serial.print("\t");
      }
      if (Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
        Serial.print(F("RightHatY: "));
        Serial.print(Xbox.getAnalogHat(RightHatY));
      }
      Serial.println();
    }

    if (Xbox.getButtonClick(UP)) {
      Xbox.setLedOn(LED1);
      Serial.println(F("Up"));
    }
    if (Xbox.getButtonClick(DOWN)) {
      Xbox.setLedOn(LED4);
      Serial.println(F("Down"));
    }
    if (Xbox.getButtonClick(LEFT)) {
      Xbox.setLedOn(LED3);
      Serial.println(F("Left"));
    }
    if (Xbox.getButtonClick(RIGHT)) {
      Xbox.setLedOn(LED2);
      Serial.println(F("Right"));
    }

    if (Xbox.getButtonClick(START)) {
      Xbox.setLedMode(ALTERNATING);
      Serial.println(F("Start"));
    }
    if (Xbox.getButtonClick(BACK)) {
      Xbox.setLedBlink(ALL);
      Serial.println(F("Back"));
    }
    if (Xbox.getButtonClick(L3))
      Serial.println(F("L3"));
    if (Xbox.getButtonClick(R3))
      Serial.println(F("R3"));

    if (Xbox.getButtonClick(LB))
      Serial.println(F("LB"));
    if (Xbox.getButtonClick(RB))
      Serial.println(F("RB"));
    if (Xbox.getButtonClick(XBOX)) {
      Xbox.setLedMode(ROTATING);
      Serial.println(F("Xbox"));
    }

    if (Xbox.getButtonClick(A))
      Serial.println(F("A"));
    if (Xbox.getButtonClick(B))
      Serial.println(F("B"));
    if (Xbox.getButtonClick(X))
      Serial.println(F("X"));
    if (Xbox.getButtonClick(Y))
      Serial.println(F("Y"));
  }
  delay(1);
}

And I get these errors for the USB_Host_Shield library:

In file included from /home/david/Arduino/libraries/USB_Host_Shield_Library_2.0/Usb.h:41:0,
                 from /home/david/Arduino/libraries/USB_Host_Shield_Library_2.0/XBOXUSB.h:21,
                 from /tmp/.arduinoIDE-unsaved2023726-254136-3tud5r.1e47o/XBOXUSB/XBOXUSB.ino:7:
/home/david/Arduino/libraries/USB_Host_Shield_Library_2.0/avrpins.h:1442:2: error: #error "Please define board in avrpins.h"
 #error "Please define board in avrpins.h"
  ^~~~~
In file included from /home/david/Arduino/libraries/USB_Host_Shield_Library_2.0/Usb.h:43:0,
                 from /home/david/Arduino/libraries/USB_Host_Shield_Library_2.0/XBOXUSB.h:21,
                 from /tmp/.arduinoIDE-unsaved2023726-254136-3tud5r.1e47o/XBOXUSB/XBOXUSB.ino:7:
/home/david/Arduino/libraries/USB_Host_Shield_Library_2.0/usbhost.h:126:2: error: #error "No SPI entry in usbhost.h"
 #error "No SPI entry in usbhost.h"
  ^~~~~

exit status 1

Compilation error: exit status 1

If anyone wants to give me a head start I'd appreciate it. Otherwise I intend to try to solve this one tomorrow.

the MCU on Uno R4 is capable of doing USB host. but on Uno R4 WiFi USB is set off in boards.txt

Arduino UNO R4 doesn't have an AVR processor. The library you try to use obviously dosen't support Arduino UNO R4 (like so many other libraries). Be patient.

1 Like

Yes I know. Please read my post.

Please make a habit of actually reading the whole thing before you reply with something boilerplate. Please. Don't just assume from the first bit you scanned what someone is asking. Take the time to read the whole thing or don't respond.

So you're saying I wouldn't need the shield? How would I make the connection?

That was my intention. If you don't appreciate my response, I have to live with it.

I mean a head start as in something that helps with the task I've set out for myself. Like if you know something about that file or those particular errors.

I'm saying that I want to try to fix something and your response was to wait around until someone else does it. How is that in any way helpful?

That's what made me answer. I apologize for not having checked your background before answering, else I would have been more cautious.

I believe I need to create a section in avrpins.h similar to this. But I'm going to wait for @juraj because it seems that there may be an easier solution that doesn't require the shield.

#elif defined(STM32F446xx)
// NUCLEO-F446RE

#define MAKE_PIN(className, port, pin) \
class className { \
public: \
  static void Set() { \
    HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET); \
  } \
  static void Clear() { \
    HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET); \
  } \
  static void SetDirRead() { \
    static GPIO_InitTypeDef GPIO_InitStruct; \
    GPIO_InitStruct.Pin = pin; \
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \
    GPIO_InitStruct.Pull = GPIO_NOPULL; \
    HAL_GPIO_Init(port, &GPIO_InitStruct); \
  } \
  static void SetDirWrite() { \
    static GPIO_InitTypeDef GPIO_InitStruct; \
    GPIO_InitStruct.Pin = pin; \
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \
    GPIO_InitStruct.Pull = GPIO_NOPULL; \
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; \
    HAL_GPIO_Init(port, &GPIO_InitStruct); \
  } \
  static GPIO_PinState IsSet() { \
    return HAL_GPIO_ReadPin(port, pin); \
  } \
};

MAKE_PIN(P0, GPIOA, GPIO_PIN_3); // D0
MAKE_PIN(P1, GPIOA, GPIO_PIN_2); // D1
MAKE_PIN(P2, GPIOA, GPIO_PIN_10); // D2
MAKE_PIN(P3, GPIOB, GPIO_PIN_3); // D3
MAKE_PIN(P4, GPIOB, GPIO_PIN_5); // D4
MAKE_PIN(P5, GPIOB, GPIO_PIN_4); // D5
MAKE_PIN(P6, GPIOB, GPIO_PIN_10); // D6
MAKE_PIN(P7, GPIOA, GPIO_PIN_8); // D7
MAKE_PIN(P8, GPIOA, GPIO_PIN_9); // D8
MAKE_PIN(P9, GPIOC, GPIO_PIN_7); // D9
MAKE_PIN(P10, GPIOB, GPIO_PIN_6); // D10
MAKE_PIN(P11, GPIOA, GPIO_PIN_7); // D11
MAKE_PIN(P12, GPIOA, GPIO_PIN_6); // D12
MAKE_PIN(P13, GPIOA, GPIO_PIN_5); // D13

MAKE_PIN(P14, GPIOA, GPIO_PIN_0); // A0
MAKE_PIN(P15, GPIOA, GPIO_PIN_1); // A1
MAKE_PIN(P16, GPIOA, GPIO_PIN_4); // A2
MAKE_PIN(P17, GPIOB, GPIO_PIN_0); // A3
MAKE_PIN(P18, GPIOC, GPIO_PIN_1); // A4
MAKE_PIN(P19, GPIOC, GPIO_PIN_0); // A5

#undef MAKE_PIN

I did something similar here: https://forum.arduino.cc/t/support-mcufriend-uno-tft-shield-on-uno-r4/1151857

USB host shield for Uno R4 in a work in progress.

There is a PR on github Updated for Arduino Uno R4 maxima and wifi by mjs513 · Pull Request #779 · felis/USB_Host_Shield_2.0 · GitHub

1 Like

Here is the link to my repository with the changes: mjs513/USB_Host_Shield_2.0: Revision 2.0 of USB Host Library for Arduino. (github.com). Just download and replace what you currently have. Note: I only tested the xbox controller on wifi so let me know if it works

Mike

1 Like

@Delta_G I have (almost) no cue.
In boards.txt there is -DNO_USB, but it looks like it only disables SerialUSB.

the core has tinyusb and that has usb host support.

Thanks. I'll look into that. It would make my project a lot neater if I could connect directly and leave the shield off. That way I can still see the pretty led matrix.

Thanks. That was what I really wanted to know. I didn't want to spend a lot of time on this if someone had already done it.

I'll let you know if I run into any issues or bugs.

@Juraj

I've been learning about tinyusb. Seems like the ESP32-S3 onboard also has support. I could use either one.

My only choice for connection though is touse the USB-C connector. So I'll need an adapter to read from an old-school x-box controller since it has a type-A connector.

If I want to use the ESP, then I have to reprogram it and mess with my serial connection. Was hoping not to jump into that right off the bat.

Pins 914 and 915 on the RA4M1 are DP and DM respectively. They're only brought out at the USB connector and to use them I have to switch from using the ESP as a bridge to serial directly to the RA4M1. I'm not sure what that entails. My intent is to send xbox controller state over wifi. If the USB can connect directly to the RA4M1 and I can still use the ESP for WiFi then I think it may be game on.

Oh cool. It looks like all I have to do is pull D40 HIGH in code and I switch to the RA4M1 USB connection. That means I can switch it in code and leave all the default bootloader on the M1 and the firmware on the ESP.

USB C OTG

I got this:

Should have it Wednesday or Thursday.

Connectors came in. I started looking for some tinyusb examples. Looks like I have my work cut out for me.

I don't see anything for the xbox360 controller I have. I do see an example for playstation controller that I can try to work from.

I can't find any tinyusb examples specific for the Arduino UNO R4. I can't find anything for the Arduino environment specifically at all.

I'm going to start with the playstation example here:

and work from there.