Esp32s3 USB keyboard vs smartphone

Hi community,
I have a strange issue on using my esp32s3 xiao like a USB keyboard.

I have connected the D+ and D- pads to a usb C connector. Obviously together with 5V and gnd.

Everything works properly on PC, where i connect this usb connector. But if i connect this usb c to a smartphone, nothing works. Also the power supply is not working.

But if i use the original usb c port, everything work good either on the smartphone.

So it’s not a problem of the script. But i am ignoring something in terms of hardware.

Can you help me please?

Hi there,
Sounds like the a code issue. are you using softserial or no?
Let’s see the code in question, we can help.
Should work? What Phone? Need more info.
HTH
GL :slight_smile: PJ
:v:

//VERSIONE 3.3
//MODIFICHE:
//compatibilità completa con terra-pirata (rb reader)
//modificata mappa 2 (RB) andando a renderla compatibile con terra-pirata. Joystick&levetta scorrono RB, rosso-blu trip, nero LP carattere Z per azzeramento trip
//INCLUSIONE LIBRERIE PER OTA
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>

const char* ssid = "WLPcom TRAX UPD";
const char* password = "123456789";

AsyncWebServer server(80);

//GESTIONE LED RGB DI STATO
/******************** definizione delle costanti **********************************/
int portarossa = D9; // porta 11 da collegare all’anodo “rosso” del modulo RGB
int portaverde = D8; // porta 10 da collegare all’anodo “verde” del modulo RGB
int portablu = D7; // porta 9 da collegare all’anodo “blu” del modulo RBG
/**********************routine di accensione del led ********************************
  nelle prossime righe viene definita la routine “colore” che, al momento del lancio, e’
  accompagnata da tre variabili (rosso, verde e blu) che contengono i valori dell’intensita’
  luminosa, di volta in volta voluta, per ogni singolo led (0 = minim0a e 255 = massima) */

//INIZIALIZZO PIN LETTURA VELOCITA
const int Vpin = D10;
int vel = LOW;
int Mvel = 0;
const int Vel_ab = 1; //se 0 allora la velocità sul pin non è abilitata, se 1 è abilitata

//GESTIONE SIMULAZIONE VELOCITA
unsigned long prevMillis = 0;
const long interval = 40;
unsigned long prevMilLP = 0;

// Keypad library to handle matrix keypad setup
#include <Keypad.h>

// For ESP32 Bluetooth keyboard HID https://github.com/T-vK/ESP32-BLE-Keyboard
//#include <BleKeyboard.h>
#include <USB.h>
#include <USBHIDKeyboard.h>

// Set up the bleKeyboard instance
USBHIDKeyboard Keyboard;
//BleKeyboard bleKeyboard("TRAX3-test", "WLP.com", 100);
// Keypad library set up
////////////////////////

// This needs to be aligned with how you wired the buttons exactly.
// see https://www.circuitbasics.com/how-to-set-up-a-keypad-on-an-arduino/ for an intro into the keypad library
const byte ROWS = 2;
const byte COLS = 5;

// for this project we'll number the keys, and use their value to 'press' the correct button
// The layout is a bit weird due to changes in the layout of the buttons, but maintaining pin compatibility
char keys[ROWS][COLS] = {
  {'6', '4', '2', '8', '5'}, //{  '6', '4', '2', '8', '5'} PER TRAX3 { '2', '8', '4', '6', '5'} PER TRAX1 { '8', '2', '6', '4', '5'} COMMON
  { '1', '7', '3', '9', 'A'}
};


// pin assignments (https://randomnerdtutorials.com/esp32-pinout-reference-gpios/)
// IMPORTANT: choose pins that are actually broken out on your board, otherwise the ESP won't boot
//////////////////

// pins for keypad library, these need to be aligned with how you wired the buttons exactly.
byte rowPins[ROWS] = {D0, D1}; // top to bottom
byte colPins[COLS] = {D2, D3, D4, D5, D6};  // left to right


//INIZIALIZZO MAPPA
// include library to read and write from flash memory
#include <EEPROM.h>
// define the number of bytes you want to access
#define EEPROM_SIZE 1
int current_keymap = 1;
int key_mem = current_keymap;

// Initialization
/////////////////

// Initialize keypad library
Keypad TRAX = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int last_keypad_state = IDLE; // Used to distinguish between button release from HOLD or PRESSED.

// Initialize variable that determines how long a key is pressed to the current time in milliseconds
unsigned long hold_time = millis();

// define time for a long press (ms)
const int long_press_time = 440;
const int long_press_repeat_interval = 80;


// How many keymaps do we have?
const int KEYMAP_COUNT = 2;


// These keys will be repeated (and also sent on initial press of the button).
// Other keys will have an alternate function on long press
// First dimension is keymap
char repeating_keys[4][10] = {
  {'1', '2', '5', '6', '7', '8', '9' },
  {'1', '2', '5', '8' },
  {'1', '2' },
  {}
};


/*
   The 2 functions below determine what key gets sent.

   See here for special keys:
   - https://github.com/T-vK/ESP32-BLE-Keyboard/blob/master/BleKeyboard.h
   - https://www.arduino.cc/en/Reference/KeyboardModifiers

   Candidates are:
   NUM_PLUS / NUM_MINUS
   KEY_MEDIA_VOLUME_UP / KEY_MEDIA_VOLUME_DOWN
   KEY_UP_ARROW / KEY_DOWN_ARROW / KEY_LEFT_ARROW / KEY_RIGHT_ARROW
   KEY_MEDIA_PLAY_PAUSE
*/


// Routine to send the keystrokes on a short press of the keypad
void send_short_press(KeypadEvent key) {


  // We're in the main menu

  switch (current_keymap) {
    case 1:
      switch (key) {
        case '1': Keyboard.write('+'); break;//ROSSO
        case '2': Keyboard.write(KEY_UP_ARROW); break;//JOY UP
        case '3': Keyboard.write('c'); break;//NERO
        case '4': Keyboard.write(KEY_LEFT_ARROW); break;//JOY LEFT
        //case '5': bleKeyboard.write('c'); break;//JOY SW
        case '6': Keyboard.write(KEY_RIGHT_ARROW); break;//JOY RIGHT
        case '7': Keyboard.write('?'); break;//BLU
        case '8': Keyboard.write(KEY_DOWN_ARROW); break;//JOY DOWN
        case '9': Keyboard.write('f'); break;//GIALLO
      }
      break;

    case 2:
      switch (key) {
        case '1': Keyboard.write(KEY_RIGHT_ARROW); break;//ROSSO
        case '2': Keyboard.write(KEY_UP_ARROW); break;//JOY UP
        case '3': Keyboard.write('z'); break;//NERO
        //case '4': bleKeyboard.write(KEY_LEFT_ARROW); break;//JOY LEFT
        //case '5': bleKeyboard.write('c'); break;//JOY SW
        //case '6': bleKeyboard.write(KEY_RIGHT_ARROW); break;//JOY RIGHT
        case '7': Keyboard.write(KEY_LEFT_ARROW); break;//BLU
        case '8': Keyboard.write(KEY_DOWN_ARROW); break;//JOY DOWN
          //case '9': bleKeyboard.write(KEY_MEDIA_VOLUME_UP); break;//GIALLO
      }
      break;

    case 3:
      switch (key) {
        case '1': Keyboard.write(KEY_UP_ARROW); break;
        case '2': Keyboard.write('+'); break;
        case '3': Keyboard.write(KEY_UP_ARROW); break;
        case '4': Keyboard.write(KEY_LEFT_ARROW); break;
        case '5': Keyboard.write('c'); break;
        case '6': Keyboard.write(KEY_RIGHT_ARROW); break;
        case '7': Keyboard.write(KEY_DOWN_ARROW); break;
        case '8': Keyboard.write('?'); break;
        case '9': Keyboard.write(KEY_DOWN_ARROW); break;
      }
      break;
      //
      //      case 4:
      //        switch (key) {
      //          case '1': bleKeyboard.write(KEY_F1); flash_led(1, 150, 0); break;
      //          case '2': bleKeyboard.write(KEY_F2); flash_led(1, 150, 0); break;
      //          case '3': bleKeyboard.write(KEY_F3); flash_led(1, 150, 0); break;
      //          case '4': bleKeyboard.write(KEY_F4); flash_led(1, 150, 0); break;
      //          case '5': bleKeyboard.write(KEY_F5); flash_led(1, 150, 0); break;
      //          case '6': bleKeyboard.write(KEY_F6); flash_led(1, 150, 0); break;
      //          case '7': bleKeyboard.write(KEY_F7); flash_led(1, 150, 0); break;
      //          case '8': bleKeyboard.write(KEY_F8); flash_led(1, 150, 0); break;
      //        }
      //        break;
  }
}

// Routine to send the keystrokes on a long press of the keypad
void send_long_press(KeypadEvent key) {

  // We're in the main menu

  switch (current_keymap) {
    case 1:
      switch (key) {
        case '1': send_repeating_key('+'); break;//ROSSO
        case '2': send_repeating_key(KEY_UP_ARROW); break;//JOY UP
        case '3': Keyboard.write('d'); break;//NERO
        case '4': send_repeating_key(KEY_LEFT_ARROW); break;//JOY LEFT
        //case '5'://JOY SW
        // cycle to next keymap
        //current_keymap = 2;
        // break;
        case '6': send_repeating_key(KEY_RIGHT_ARROW); break;//JOY RIGHT
        case '7': send_repeating_key('?'); break;//BLU
        case '8': send_repeating_key(KEY_DOWN_ARROW); break;//JOY DOWN
        //        case '9': bleKeyboard.write('g');
        case '9'://GIALLO
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_TAB);
          Keyboard.releaseAll();
          break;

      }
      break;

    case 2:
      switch (key) {
        case '1': send_repeating_key(KEY_RIGHT_ARROW); break;//ROSSO
        case '2': send_repeating_key(KEY_UP_ARROW); break;//JOY UP
        case '3': Keyboard.write('r'); break;//NERO
        case '4': send_repeating_key(KEY_LEFT_ARROW); break;//JOY LEFT
        //case '5'://JOY SW
        // cycle to next keymap
        //current_keymap = 1;
        //break;
        case '6': send_repeating_key(KEY_RIGHT_ARROW); break;//JOY RIGHT
        case '7': send_repeating_key(KEY_LEFT_ARROW); break;//BLU
        case '8':  Keyboard.write(KEY_DOWN_ARROW); break;//JOY DOWN
        case '9'://GIALLO
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_TAB);
          Keyboard.releaseAll();
          break;
      }
      break;

    case 3:
      switch (key) {
        case '1': send_repeating_key(KEY_UP_ARROW); break;//ROSSO
        case '2': send_repeating_key('+'); break;//JOY UP
        case '3': send_repeating_key('d'); break;//NERO
        case '4': send_repeating_key(KEY_LEFT_ARROW); break;//JOY LEFT
        //case '5'://JOY SW
        // cycle to next keymap
        //current_keymap = 1;
        //break;
        case '6': send_repeating_key(KEY_RIGHT_ARROW); break;//JOY RIGHT
        case '7': send_repeating_key(KEY_DOWN_ARROW); break;//BLU
        case '8': send_repeating_key('?'); break;//JOY DOWN
        case '9'://GIALLO
          Keyboard.press(KEY_LEFT_ALT);
          Keyboard.press(KEY_TAB);
          Keyboard.releaseAll();
          break;
      }
      break;
      //
      //      case 4:
      //        switch (key) {
      //          case '1': bleKeyboard.write(KEY_F11); flash_led(1, 150, 0); break;
      //          case '2': bleKeyboard.write(KEY_F12); flash_led(1, 150, 0); break;
      //          case '3': bleKeyboard.write(KEY_F13); flash_led(1, 150, 0); break;
      //          case '4': app_status = 1; break;
      //          case '5': bleKeyboard.write(KEY_F15); flash_led(1, 150, 0); break;
      //          case '6': bleKeyboard.write(KEY_F16); flash_led(1, 150, 0); break;
      //          case '7': bleKeyboard.write(KEY_F17); flash_led(1, 150, 0); break;
      //          case '8': bleKeyboard.write(KEY_F18); flash_led(1, 150, 0); break;
      //        }
      //        break;
      //
  }
  switch (current_keymap) {
    case 1:
      for (int i = 0; i < 3; i++) // Scan the whole key list.
      {
        if ( TRAX.key[i].stateChanged )   // Only find keys that have changed state.
        {
          if ((TRAX.key[0].kchar == '1') && (TRAX.key[1].kchar == '7'))
            current_keymap = 2;
        }
        //Serial.println(acumaP5.key[i].kchar);
      }
      break;
    case 2:
      for (int i = 0; i < 3; i++) // Scan the whole key list.
      {
        if ( TRAX.key[i].stateChanged )   // Only find keys that have changed state.
        {
          if ((TRAX.key[0].kchar == '1') && (TRAX.key[1].kchar == '7'))
            current_keymap = 3;
        }
        //Serial.println(acumaP5.key[i].kchar);
      }
      break;
    case 3:
      for (int i = 0; i < 3; i++) // Scan the whole key list.
      {
        if ( TRAX.key[i].stateChanged )   // Only find keys that have changed state.
        {
          if ((TRAX.key[0].kchar == '1') && (TRAX.key[1].kchar == '7'))
            current_keymap = 1;
        }
        //Serial.println(acumaP5.key[i].kchar);
      }
      break;
  }
}


// Routine that sends a key repeatedly (for single char)
void send_repeating_key(uint8_t key) {


  while (TRAX.getState() == HOLD) {
    int vel = digitalRead(Vpin); //SCOMMENTARE QUANDO NON SI VUOLE SIMULARE VELOCITA

    switch (Vel_ab) {
      case 1:
        if (vel == HIGH && Mvel == 0) {
          Keyboard.press('t');
          Keyboard.releaseAll();
          Mvel = 1;
        }
        else if (vel == LOW && Mvel == 1) {
          Mvel = 0;
        }
        break;
      case 0:
        break;
    }


    unsigned long curLPMillis = millis();

    if (curLPMillis - prevMilLP >= long_press_repeat_interval) {
      prevMilLP = curLPMillis;
      Keyboard.write(key);
    }


    //    bleKeyboard.write(key);
    //    delay(long_press_repeat_interval); // pause between presses
    TRAX.getKey(); // update keypad event handler
  }
}




// This function handles events from the keypad.h library. Each event is only called once
void keypad_handler(KeypadEvent key) {

  // State changes for the buttons
  switch (TRAX.getState()) {

    case PRESSED: // Directly on the press of a button

      if (is_key_repeating(key)) {
        send_short_press(key);
      }
      break;

    case HOLD: // When a button is held beyond the long_press_time value

      send_long_press(key);
      break;

    case RELEASED: // When a button is released

      //
      if (last_keypad_state == PRESSED) {
        if (!is_key_repeating(key)) {
          send_short_press(key);
        }
      }


      break;

    case IDLE: // not sure why this generates a callback

      break;
  }

  last_keypad_state = TRAX.getState();
}


// Arduino built-in setup loop
void setup() {

  Serial.begin(115200);

  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  // read the last LED state from flash memory
  if (EEPROM.read(0) != 1 && EEPROM.read(0) != 2 ) {
    current_keymap = 1;
    EEPROM.write(0, current_keymap);
    EEPROM.commit();
  }
  else {
    current_keymap = EEPROM.read(0);
  }


  //SETTING OTA
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  //Serial.println("");
  //
  //while (WiFi.status() != WL_CONNECTED) {
  //  delay(500);
  //  Serial.print(".");
  //}
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/plain", "Hi! I am WLP.com TRAX 1.");
  });

  AsyncElegantOTA.begin(&server);    // Start ElegantOTA
  server.begin();
  Serial.println("HTTP server started");

  // Handle all keypad events through this listener
  TRAX.addEventListener(keypad_handler); // Add an event listener for this keypad

  // set HoldTime
  TRAX.setHoldTime(long_press_time);

  // Start bluetooth keyboard module
  Keyboard.begin();
  USB.begin();

  pinMode(portarossa, OUTPUT); // dichiara la porta 11 come porta di output
  pinMode(portaverde, OUTPUT); // dichiara la porta 10 come porta di output
  pinMode(portablu, OUTPUT); // dichiara la porta 9 come porta di output


  //GESTIONE PIN VELOCITA
  pinMode(Vpin, INPUT);

  // End of setup()
}

void loop() {

  if (current_keymap != key_mem) {
    EEPROM.write(0, current_keymap);
    EEPROM.commit();
    key_mem = current_keymap;
  }

  // Need to call this function constantly to make the keypad library work
  TRAX.getKey();

  //delay(10);

  //gestione colori mappe

  switch (current_keymap) {
    case 1: colore(0, 255, 0);
      break;
    case 2: colore(0, 0, 255);
      break;
    case 3: colore(255, 255, 0);
      break;
  }


  //GESTIONE LETTURA VELOCITA CHE VIENE ATTIVATA SOLO CON MAPPA ROADBOOK


  int vel = digitalRead(Vpin); //SCOMMENTARE QUANDO NON SI VUOLE SIMULARE VELOCITA

  if (vel == HIGH && Mvel == 0) {
    Keyboard.press('t');
    Keyboard.releaseAll();
    Mvel = 1;
  }
  else if (vel == LOW && Mvel == 1) {
    Keyboard.releaseAll();
    Mvel = 0;
  }
}



// Helper function to determine if a key is supposed to be repeating, or special
int is_key_repeating(char key_pressed) {

  for ( int i = 0; i < sizeof (repeating_keys[current_keymap]); i++) {
    if ( repeating_keys[current_keymap][i] == key_pressed) {
      return true;
    }
  }
  return false;
}

void colore (unsigned char rosso, unsigned char verde, unsigned char blu)
{
  analogWrite(portarossa, rosso); //attiva il led rosso con l’intensita’ definita nella variabile rosso
  analogWrite(portablu, blu); //attiva il led blu con l’intensita’ definita nella variabile blu
  analogWrite(portaverde, verde); //attiva il led verde con l’intensita’ definita nella variabile verde
}


// This function cycles the keymap and signals the new keymap via the LED
//void switch_keymap() {
//
//  // Serial.println("Switching keymap");
//
//  // cycle to next keymap
//  current_keymap++;
//  if (current_keymap > KEYMAP_COUNT ) {
//    current_keymap = 1;
//  }
//}

Hi there,
So Looks to me as though the D+ and D- are only usb 2.0 spec so the mating wiring matters to detect it correctly. probably as an OTG port so, I couldn’t compile it as you didn’t provide the Keyboard.h you are using , is it a custom one?
So was this a BLE keyboard, shoe horned to a Keyboard emulator?
What is it for?
HTH
GL :slight_smile: PJ
:v: