MHeironimus / ArduinoJoystickLibrary

An Arduino library that adds one or more joysticks to the list of HID devices an Arduino Leonardo or Arduino Micro can support.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Device always immediately wakes PC after going to sleep

hapklaar opened this issue · comments

Description of Issue

I built a simple 1 axis controller using your library and it works great. Problem is that when it is connected to USB and I put my PC to sleep, it wakes my computer after a couple of seconds.

  • When I disconnect the device before I put my PC to sleep, the PC stays asleep.
  • When I connect the device after the PC went to sleep, it stays asleep as well.

Technical Details

  • Arduino Board (e.g. Arduino Leonardo): Arduino Micro
  • Host OS (e.g. Windows 10): Windows 11
  • Arduino IDE Version (e.g. 1.8.3): latest

Sketch File that Reproduces Issue

#include <FastLED.h>
#include <Joystick.h>

#define ENABLE_ANALOG1 true

#define PIN_SLIDE_POT_A A0 // input pin of the slide pot
#define MAX_SLIDE_POT_ANALGOG_READ_VALUE 690 // maximum voltage as analog-to-digital converted value, depends on the voltage level of the VCC pin. Examples: 5V = 1023; 3.3V ~700

#define NUM_LEDS 10 // add number of LEDs of your RGB LED strip
#define PIN_LED 6 // digital output PIN that is connected to DIN of the RGB LED strip
#define LED_COLOR CRGB( 150, 0, 0)
#define LED_IDLE_COLOR CRGB( 0, 10, 20)

CRGB rgb_led[NUM_LEDS]; // color array of the LED RGB strip

int X1 = A0;
int Y1 = A1;

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK, 0, 0, 
  true, false, false, false, false, false, false, false, false, false, false);

void setup() {
  pinMode(PIN_SLIDE_POT_A, INPUT);
  FastLED.addLeds<WS2812B, PIN_LED, GRB>(rgb_led, NUM_LEDS);  

  Joystick.begin();
  if (ENABLE_ANALOG1) {
    Joystick.setXAxisRange(512, -512);
  }
}

void JButtonStates() {
  if (ENABLE_ANALOG1) {
    Joystick.setXAxis(analogRead(X1) - 512);
  }  
}

void loop() {
  JButtonStates();
  delay(50);

    // 1) Analog value of slide pot is read
  int value_slide_pot_a = analogRead(PIN_SLIDE_POT_A);

  // 2) Analog value is mapped from slide pot range (analog input value) to led range (number of LEDs)
  int num_leds_switchedon = map(value_slide_pot_a, 0, MAX_SLIDE_POT_ANALGOG_READ_VALUE, 0, NUM_LEDS);  

  // 3) Light up the LEDs
  // Only LEDs are switched on which correspond to the area left of the slide knob
  for (int i = 0; i < num_leds_switchedon; ++i) {
    rgb_led[i] = LED_COLOR;
  }  
  // LEDs are switched off which correspond to the area right of the slide knob
  for (int i = num_leds_switchedon; i < NUM_LEDS; ++i) {
    rgb_led[i] = LED_IDLE_COLOR;
  }
  FastLED.show();
}

Wiring Details

Probably not relevant.

Additional context

  • I have already disabled the 'Allow this device to wake the computer' flag in device manager. (HID-compliant game controller)
  • powercfg /lastwake shows the following when the joystick device has woken the PC
Wake Source [0]
    Type: Device
    Instance Path: PCI\VEN_8086&DEV_43ED&SUBSYS_7D081462&REV_11\3&11583659&0&A0
    Friendly Name: Intel(R) USB 3.20 eXtensible Host Controller - 1.20 (Microsoft)
    Description: USB xHCI Compliant Host Controller
    Manufacturer: Generic USB xHCI Host Controller

I have not had a chance to test this theory, but it appears you are sending a message to the host computer on every loop, even when the state of the joystick has not changed. To fix this you will need to only call setXAxis (or any other library function) when the value is different from the last time you called the function. The FunduinoJoystickShield.ino example shows how this can be done.

Thanks for following up! I added a value check to only send updates when the new value was at least 8 higher or lower than previous (the value jumps around a bit) and can see it now doesn't send updates anymore when the pot is not touched:

...
void loop()
{
  bool sendUpdate = false;
  const int currentXAxisValue = analogRead(X1);
  int difference = lastXAxisValue - currentXAxisValue;
  Serial.println(difference);

  if (difference > 8 || difference < -8)
  {
    controller.setXAxis(currentXAxisValue - 512);
    lastXAxisValue = currentXAxisValue;
    sendUpdate = true;
    Serial.println("Sending update!");
  }

  if (sendUpdate)
  {
    controller.sendState();
  }
...

But unfortunately, the device still immediately wakes the PC when connected :(

If you just load one of the sample applications to the device (like the blink example or the Keyboard Message example) does the device keep the PC awake or only when you have a program that uses the Joystick library?

or only when you have a program that uses the Joystick library?

This was it! I still had the 'Game Controllers' app open. After closing that the PC no longer woke up.

The same is happening when I leave the serial monitor open and have constant serial output from the Arduino. Didn't know this was a thing :)

Thanks!

Better late than never. I had the same problem when I wrote some joystick software for my own project. Never could figure out a solution. Now several years later I decided to update the code a bit after some modifications to the hardware and I stumble across this post. I feel like an idiot. 3 lines of extra code to check if the value has actually changed solves this issue. And to think I spent almost a week on debugging this all those years ago.
Thanks for posting for me to find!