Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BSOD and WDF_VIOLATION error on Windows 11 after connected #198

Closed
praditautama opened this issue Oct 29, 2023 · 5 comments
Closed

BSOD and WDF_VIOLATION error on Windows 11 after connected #198

praditautama opened this issue Oct 29, 2023 · 5 comments

Comments

@praditautama
Copy link

praditautama commented Oct 29, 2023

Hello,
I am building BLE Gamepad with 0.9 inch OLED display on ESP32 DEVKITC V4 WROOM-32U, I use macOS for development.

Everything works on macOS, I can test all buttons using "Controller Lite" app from AppStore, all buttons worked. But every time I connected to Windows 11 PC, I got BSOD with WDF_VIOLATION error.

I searched for WDF_VIOLATION, It's related to bad driver mostly BT driver. Is there any chance my USB dongle doesn't support for BLE?

My PC:

Added my source code

#include <Arduino.h>

#include <Keypad.h>      // https://github.com/Chris--A/Keypad
#include <BleGamepad.h>  // https://github.com/lemmingDev/ESP32-BLE-Gamepad
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP32Encoder.h>  // https://github.com/madhephaestus/ESP32Encoder

#define SCREEN_WIDTH 128     // OLED display width, in pixels
#define SCREEN_HEIGHT 64     // OLED display height, in pixels
#define OLED_RESET -1        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C  ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define BUF_SIZE 64
#define ROWS 3
#define COLS 5
uint8_t rowPins[ROWS] = { 2, 4, 13 };            // ESP32 pins used for rows      --> adjust to suit --> Pinout on board: R1, R2, R3, R4
uint8_t colPins[COLS] = { 14, 15, 16, 17, 18 };  // ESP32 pins used for columns   --> adjust to suit --> Pinout on board: Q1, Q2, Q3, Q4
uint8_t keymap[ROWS][COLS] = {
  { 1, 2, 3, 4, 5 },
  { 6, 7, 8, 9, 10 },
  { 11, 12, 13, 14, 15 }
};

uint8_t newMACAddress[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF - 0x02 };

// Create encoder objects
ESP32Encoder encoder1;
ESP32Encoder encoder2;
ESP32Encoder encoder3;

// Variables to store the current encoder count
int32_t encoder1Count = 0;
int32_t encoder2Count = 0;
int32_t encoder3Count = 0;

BleGamepad bleGamepad("Rally Button Box", "Javasim Esports", 100);  // Shows how you can customise the device name, manufacturer name and initial battery level

Keypad customKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, ROWS, COLS);

void setup() {

  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }
  delay(2000);

  printWelcomeMessage();
  delay(5000);

  // Enable the weak pull up resistors
  ESP32Encoder::useInternalWeakPullResistors = UP;

  // Attach pins to encoders
  encoder1.attachHalfQuad(5, 34);
  encoder2.attachHalfQuad(25, 26);
  encoder3.attachHalfQuad(32, 33);

  // Clear encoder counts
  encoder1.clearCount();
  encoder2.clearCount();
  encoder3.clearCount();

  // Initialise encoder counts
  encoder1Count = encoder1.getCount();
  encoder2Count = encoder2.getCount();
  encoder3Count = encoder3.getCount();

  BleGamepadConfiguration bleGamepadConfig;
  bleGamepadConfig.setButtonCount(26);
  bleGamepadConfig.setControllerType(CONTROLLER_TYPE_GAMEPAD);
  bleGamepadConfig.setWhichAxes(false, false, false, false, false, false, false, false);
  bleGamepadConfig.setAutoReport(false);  // Disable auto reports --> You then need to force HID updates with bleGamepad.sendReport()
  bleGamepadConfig.setVid(0xe502);
  bleGamepadConfig.setPid(0xabcd);

  // bleGamepadConfig.setModelNumber("1.0");
  // bleGamepadConfig.setSoftwareRevision("Software Rev 1");
  // bleGamepadConfig.setSerialNumber("9876543210");
  // bleGamepadConfig.setFirmwareRevision("2.0");
  // bleGamepadConfig.setHardwareRevision("1.7");
  bleGamepad.begin(&bleGamepadConfig);  // Begin library with default buttons/hats/axes
  // changing bleGamepadConfig after the begin function has no effect, unless you call the begin function again
  esp_base_mac_addr_set(&newMACAddress[0]); // Set new MAC address
  printConnectingMessage();
  delay(5000);
}

void loop() {
  if (bleGamepad.isConnected()) {
    printStandyMessage();
    KeypadUpdate();
    EncodersUpdate();
  } else {
    printErrorConnection();
  }
  delay(10);
}

void EncodersUpdate() {
  int32_t tempEncoderCount1 = encoder1.getCount();
  int32_t tempEncoderCount2 = encoder2.getCount();
  int32_t tempEncoderCount3 = encoder3.getCount();

  bool sendReport = false;

  if (tempEncoderCount1 != encoder1Count) {
    sendReport = true;
    Serial.println(tempEncoderCount1);
    Serial.println(encoder1Count);

    if (tempEncoderCount1 > encoder1Count) {
      bleGamepad.press(BUTTON_14);
    } else {
      bleGamepad.press(BUTTON_15);
    }
  }

  if (tempEncoderCount2 != encoder2Count) {
    sendReport = true;

    if (tempEncoderCount2 > encoder2Count) {
      bleGamepad.press(BUTTON_16);
    } else {
      bleGamepad.press(BUTTON_17);
    }
  }

  if (tempEncoderCount3 != encoder3Count) {
    sendReport = true;

    if (tempEncoderCount3 > encoder3Count) {
      bleGamepad.press(BUTTON_18);
    } else {
      bleGamepad.press(BUTTON_19);
    }
  }



  if (sendReport) {
    bleGamepad.sendReport();
    delay(400);

    bleGamepad.release(BUTTON_14);
    bleGamepad.release(BUTTON_15);
    bleGamepad.release(BUTTON_16);
    bleGamepad.release(BUTTON_17);
    bleGamepad.release(BUTTON_18);
    bleGamepad.release(BUTTON_19);
    bleGamepad.sendReport();
    delay(300);

    encoder1Count = encoder1.getCount();
    encoder2Count = encoder2.getCount();
    encoder3Count = encoder3.getCount();
  }
}

void KeypadUpdate() {
  customKeypad.getKeys();

  for (int i = 0; i < LIST_MAX; i++)  // Scan the whole key list.      //LIST_MAX is provided by the Keypad library and gives the number of buttons of the Keypad instance
  {
    if (customKeypad.key[i].stateChanged)  // Only find keys that have changed state.
    {
      uint8_t keystate = customKeypad.key[i].kstate;

      if (keystate == PRESSED) {
        bleGamepad.press(customKeypad.key[i].kchar);
      }  // Press or release button based on the current state
      if (keystate == RELEASED) {
        bleGamepad.release(customKeypad.key[i].kchar);
      }

      bleGamepad.sendReport();  // Send the HID report after values for all button states are updated, and at least one button state had changed
    }
  }
}

void printWelcomeMessage() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setFont(NULL);
  display.println("BUTTON BOX v0.1.0");
  display.println("FW: nCNNtdTEix");
  display.display();
}

void printStandyMessage() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setFont(NULL);
  // display.setCursor(0, 0);
  // display.println("BUTTON BOX v0.1.0");
  // display.println("FW: nCNNtdTEix");
  display.setTextSize(2);
  printCenter("CONNECTED", 0, 20);
  display.display();
}

void printConnectingMessage() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setFont(NULL);
  display.setTextSize(2);
  printCenter("CONNECTING", 0, 20);
  display.display();
}

void printErrorConnection() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setFont(NULL);
  // display.setCursor(0, 0);
  // display.println("BUTTON BOX v0.1.0");
  // display.println("FW: nCNNtdTEix");
  display.setTextSize(2);
  printCenter("ERROR", 0, 20);
  display.display();
}

void printCenter(const String buf, int x, int y) {
  int16_t x1, y1;
  uint16_t w, h;
  display.getTextBounds(buf, x, y, &x1, &y1, &w, &h);  //calc width of new string
  display.setCursor((x - w / 2) + (128 / 2), y);
  display.print(buf);
}
@praditautama
Copy link
Author

praditautama commented Oct 29, 2023

I tried to use #111 (comment) and it worked but connection is not stable

is it related to NimBLE?

@LeeNX
Copy link

LeeNX commented Oct 30, 2023

I have not seen this error reported in the past, can't really give you much feedback, just options on how to possible track the problem down.

Try the simpler example code first, like SingleButton. Don't forget to remove/delete/forget the device in the host manager you using, as the UUID and other BLE attribs can be cached and might not change on the host, even if you upload new code to your ESP32 device.

Another things to look at, which version of:
Arduino core for the ESP32
NimBLE-Arduino

Also, If you are able to post an example or snippet of the code showing the problem, might be easier to give more feedback.

Hope that helps.

@praditautama
Copy link
Author

Hi @LeeNX I added my source code.

@LeeNX
Copy link

LeeNX commented Oct 30, 2023

Nothing jumps out as wrong or broken.

Test the SingleButton sketch, to rule out Bluetooth hardware/OS/Drivers.

If you not using HATs, could disable them.

Interesting problem, keep us updated.

@praditautama
Copy link
Author

hi @LeeNX

I bought another BT 5.x USB dongle and I don't get WDF_VIOLATION errors anymore.

I think it's UB400 USD dongle issue.

I will close this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants