Go Down

Topic: leonardo as keyboard does not wake windows 7 from sleep (Read 16620 times) previous topic - next topic

nickgammon

Quote
Do you mean pressing a key on a real keyboard or using Keyboard.print() or Keyboard.write() an Arduino emulated keyboard?


A real keyboard. I was just testing if the wake-up press got "swallowed" or not.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Mike T


I got it working when I used the code:
USBDevice.wakeupHost();
UDCON |= (1 << RMWKUP);


I don't understand, why you need this last line.

I made an updated version which handles the SUSPEND mode (at least it acknowledges SUSPEND). Install it like the previous version by replacing the original files in your Arduino installation path (see attachment USBWakup2.zip).

I also added a diagnostic sketch to show the state changes via a blink code of the internal LED (see attachment USBWakup-130702g.zip):

Meaning of the blink codes:
1x remote wakeup enabled from the PC
2x remote wakeup disabled from the PC
3x USB host signals SUSPEND state
4x USB host signals end of SUSPEND state (wakeup)
9x USB wakeup rejected because
10x USB wakeup accepted

When the Leonardo is starting (after the bootloader blinks), you should see [3x], 1x, 4x blink.
When the PC goes to standby, you should see 3x blink
When the PC wakes up, you should see 10x blink followed by 4x blink

Currently I don't understand the initial 3x blink which I see on Mac OSX.

What blink codes do you get?

  Michael


Mike T

Still looking for testers...

Here it works for

  • Mac OSX (on a MacBook Pro)

  • Windows 7 (on a MacBook Pro)

  • Windows 8 (on a Wetab)



Any comments if it is working or not and what blink codes you get are welcome.

In the pull request #1488 I added also a feature to send your computer to sleep mode or shut it down. When you are interested, you can get the code from there.

You can use it in the following way:
Code: [Select]
  Keyboard.systemControl(SYSTEM_CONTROL_POWER_DOWN);
or
Code: [Select]
  Keyboard.systemControl(SYSTEM_CONTROL_SLEEP);

There are some more commands defined in USBAPI.h, but most of the do nothing on my Mac:
Code: [Select]
#define SYSTEM_CONTROL_POWER_DOWN              1
#define SYSTEM_CONTROL_SLEEP                   2
#define SYSTEM_CONTROL_WAKEUP                  3
#define SYSTEM_CONTROL_COLD_RESTART            4
#define SYSTEM_CONTROL_WARM_RESTART            5
#define SYSTEM_CONTROL_DOCK                    6
#define SYSTEM_CONTROL_UNDOCK                  7
#define SYSTEM_CONTROL_SPEAKER_MUTE            8
#define SYSTEM_CONTROL_HIBERNATE               9
#define SYSTEM_CONTROL_DISPLAY_INVERT         10
#define SYSTEM_CONTROL_DISPLAY_INTERNAL       11
#define SYSTEM_CONTROL_DISPLAY_EXTERNAL       12
#define SYSTEM_CONTROL_DISPLAY_BOTH           13
#define SYSTEM_CONTROL_DISPLAY_DUAL           14
#define SYSTEM_CONTROL_DISPLAY_TOGGLE_INT_EXT 15
#define SYSTEM_CONTROL_DISPLAY_SWAP           16


  Michael

mackley



I got it working when I used the code:
USBDevice.wakeupHost();
UDCON |= (1 << RMWKUP);


I don't understand, why you need this last line.



Dear Michael "Mike T",
dear "harryharry",

thanks for this USB hack that saves us the Day, try to waking an old MBP 15" in a multimedia setup on a museum installation.

The command "USBDevice.wakeupHost();" itself works but the second command is useful for a strange rarely situation:
- the MBP is in sleep status
- the Arduino Leonardo is double powered (connected via USB and 12V supply)
- if the AC wall current fall down for few minutes
- and then the AC wall current return
- the Arduino try to wake the MBP with "USBDevice...etc" itself, but FAIL
- if we add the second command it never fails !


Thanks again

Greetings from Italy

M.

wolf2

sorry for this very late reply.

exchanged the 4 files in the current arduino 105 ide.

HID.cpp
USBAPI.h
USBCore.cpp
USBCore.h

put the
USBDevice.wakeupHost();
UDCON |= (1 << RMWKUP);
into my code.
works fine on my mac 10.8.
thank you so much.

when will this find its way into the official builds?

Mike T

#20
Oct 15, 2013, 08:34 pm Last Edit: Oct 15, 2013, 10:19 pm by Mike T Reason: 1

when will this find its way into the official builds?


There needs to be some cleanup, especially for the second line (UDCON |= (1 << RMWKUP)) which should not be necessary in a normal suspend/wakeup scenario.
The USB state machine must conform to the USB standard and to my understanding this second line violates the USB standard because it send a wakeup even when the bus is not in idle state or at least the Arduino USB state machine doesn't know the bus is in idle state.

I mean the following sentence in chapter 7.1.7.7. "Resume" of the USB 2.0 spec:
"A device with remote wakeup capability may not generate resume signaling unless the bus has been continuously in the Idle state for 5 ms (TWTRSM)."

And chapter 9.1.1.6 "Suspended":
"If a USB device is capable of remote wakeup signaling, the device must support the ability of the host to enable and disable this capability. When the device is reset, remote wakeup signaling must be disabled."

And chapter 9.4.5 "Get Status":
"The Remote Wakeup field indicates whether the device is currently enabled to request remote wakeup. The default mode for devices that support remote wakeup is disabled."

Unfortunately I don't have much time at the moment for this clarification. Anybody else with some USB know-how?

  Michael

dave_j


Still looking for testers...

Here it works for

  • Mac OSX (on a MacBook Pro)

  • Windows 7 (on a MacBook Pro)

  • Windows 8 (on a Wetab)



Any comments if it is working or not and what blink codes you get are welcome.

  Michael



Hi  I dont was hoping this might be the answer to my problems ...still am.

However when I replaced the 3 files you'd attached I started getting compile errors...not with those new scripts but with CDC.cpp

Code: [Select]
Arduino: 1.0.6 (Mac OS X), Board: "Arduino Leonardo"
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:117: error: prototype for 'void Serial_::begin(long unsigned int)' does not match any in class 'Serial_'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/USBAPI.h:34: error: candidate is: void Serial_::begin(uint16_t)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:122: error: prototype for 'void Serial_::begin(long unsigned int, byte)' does not match any in class 'Serial_'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/USBAPI.h:34: error: candidate is: void Serial_::begin(uint16_t)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp: In member function 'virtual int Serial_::available()':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:133: error: 'peek_buffer' was not declared in this scope
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp: In member function 'virtual int Serial_::peek()':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:141: error: 'peek_buffer' was not declared in this scope
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:143: error: 'peek_buffer' was not declared in this scope
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp: In member function 'virtual int Serial_::read()':
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:148: error: 'peek_buffer' was not declared in this scope
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp: At global scope:
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:166: error: prototype for 'size_t Serial_::write(const uint8_t*, size_t)' does not match any in class 'Serial_'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:49: error: candidates are: size_t Print::write(const char*)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:53: error:                 virtual size_t Print::write(const uint8_t*, size_t)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:54: error:                 size_t Print::write(const char*, size_t)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/CDC.cpp:161: error:                 virtual size_t Serial_::write(uint8_t)


Im not sure if its something to do with the way I copied the files across...something I should have done with them differently. Something to do with the fact I was running a newer version of arduino (10.0.6) (on mac osx 10.8.3)

Or something else...

If you have any thoughts I'd be delighted to hear them.

dave_j



However when I replaced the 3 files you'd attached I started getting compile errors...not with those new scripts but with CDC.cpp

Im not sure if its something to do with the way I copied the files across...something I should have done with them differently. Something to do with the fact I was running a newer version of arduino (10.0.6) (on mac osx 10.8.3)

Or something else...



When I also replaced the CDC.ccp with the one from https://github.com/nospam2000/Arduino/tree/master/hardware/arduino/cores/arduino the build errors stopped and it works. Wakes the sleeping mac (10.8) just like I hoped it might. I still don't quite understand what the problem was but hopefully this is helpful info for someone.

roidan

Hi Guys,
Been trying a lot to make this work but still no luck.
Hoping you could assist.

Using Arduino IDE1.06.
I've replaced the 3 files Michael posted in USBWakeup2.zip, but got the same errors as dave posted.
Replaced the CDC.cpp from the link dave shared which worked for him, but getting now other errors in CDC file:

Code: [Select]

C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:13: error: stray '\302' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:13: error: stray '\267' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:13: error: stray '\302' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:13: error: stray '\267' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:284:46: error: exponent has no digits
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:344:40: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:353:64: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:362:48: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:461:31: error: invalid digit "9" in octal constant
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:470:31: error: invalid digit "8" in octal constant
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:551:31: error: invalid digit "9" in octal constant
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:560:31: error: invalid digit "8" in octal constant
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:623:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:632:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:677:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:686:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:695:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:704:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:713:32: error: too many decimal points in number
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:902: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:906: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:910: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:919: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:923: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:932: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:936: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:940: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:944: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:948: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:1041: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:1808: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:1812: error: stray '#' in program
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:5: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:902: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:902: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:906: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:906: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:910: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:910: error: expected unqualified-id before '<' token
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:932: error: expected unqualified-id before numeric constant
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:977: error: expected unqualified-id before '<' token



Uninstalled 1.0.6 and installed 1.0.5 (which was the recent one while this post posted)
Replaced again the 3 files and now it's compiled successfully.
But, no wake up. it reaches the code (put LED on in part of code USBDevice.wakeupHost())
Tried to add 'UDCON |= (1 << RMWKUP)' but not helping.

Arduino is loaded with keyboard & mouse library.

Any suggestions?
Many thanks!
Roi

Mike T

But, no wake up. it reaches the code (put LED on in part of code USBDevice.wakeupHost())
It is really hard to guess why it is not working with too little information.

The compile errors look a bit like you saved the cpp files as HTML instead of raw cpp files. Have a look at the content of the files in an ASCII editor.

Can you please describe your scenario in detail? Which operating system are you using, what kind of hardware (notebook, desktop, Mac, PC, Tablet), when do you connect and start the Arduino, is USB wakeup enabled in your BIOS and Operating System settings, ...

Can you wakeup your PC with a USB keyboard or mouse on the same USB port in the same scenario?
Do you have any "unknown" USB devices in your system configuration? Do you see the two Arduino  HID mice and the Arduino HID keyboard in you system configuration?

USB wakeup is needs many components work together and is a bit complicated. The following preconditions must be met:
- The Arduino Leonardo must be connected to the PC before the PC goes to sleep mode. When Arduino or the PC loose power, wakeup will fail
- The Arduino (and all USB HUBs between the PC and the Arduino) must be powered when the PC goes to standby mode. You will see this when the Arduino Leonardo power LEDs still lights when in standby mode.
- Other power modes than the "standby" mode (S3) like hibernate (S4 or S5) might also work, but this depends on many factors

When it doesn't work try it without a USB hub between the PC and the Arduino. Notebook USB ports may internally be connected via a USB HUB, so try a different USB port.

I have attached an updated version of the test sketch. You might have to fiddle with the include lines (I can't test it with 1.0.5 right now).

What blink codes do you see?
1. When starting the Leonardo
2. when you activate sleep mode (wait up to 40 seconds after activating it, OSX needs 40 seconds on my Mac and 10 seconds on Windows 7)
3. When you resume from sleep mode (by connecting pin 2 to GND for a second)
4. When the operating system reacts to the resume signal


I've ported the code to Arduino 1.5.8, but Arduino V1.0.5 and V1.0.6 required the outdated (and insecure) Java 6 version on the Mac, therefore I can't use these versions at the moment. When I have it running with 1.0.6, I will attach the new files.

 Michael

Mike T

Hi,

in the attachment of this post you will find the port to Arduino 1.0.6. I've also adapted the test sketch so it hopefully compiles now without any changes.

The .h and .cpp files from the archive "cores_arduino_106.zip" need to be copied to the Arduino installation directory.
For 1.0.6 this could be for example "C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\" on Windows
or "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/" on Mac OSX.

Please make a backup copy of the original files or even better of the whole ".../cores/arduino" folder, so you can switch back.

Let me know the blink codes you see and anything which can be useful for diagnostics (see also my previous posting).

To send the PC to standby mode using the USBWakeup sketch, connect pin 4 to GND (for a short time), to wake it up connect pin 3 to GND (for a short time).
Before you can use wakeup, you have to wait until you get 2x blinks which signals that the USB bus was set to suspend mode.

 Michael

Mike T

Hi,

here the port for Arduino 1.5.8. See also the previous two posts for the sketch and description.

  Michael

lucad79

Hi!

just to inform that the modified USB library works fine also with the latest IDE... I've just published a project that makes use of it to wake up a PC at a given time:

http://www.lucadentella.it/en/2015/05/02/wakemeup/
www.lucadentella.it

bam80

In the pull request #1488 I added also a feature to send your computer to sleep mode or shut it down. When you are interested, you can get the code from there.

You can use it in the following way:
Code: [Select]
 Keyboard.systemControl(SYSTEM_CONTROL_POWER_DOWN);
or
Code: [Select]
 Keyboard.systemControl(SYSTEM_CONTROL_SLEEP);

There are some more commands defined in USBAPI.h, but most of the do nothing on my Mac:
Code: [Select]
#define SYSTEM_CONTROL_POWER_DOWN              1
#define SYSTEM_CONTROL_SLEEP                   2
#define SYSTEM_CONTROL_WAKEUP                  3
#define SYSTEM_CONTROL_COLD_RESTART            4
#define SYSTEM_CONTROL_WARM_RESTART            5
#define SYSTEM_CONTROL_DOCK                    6
#define SYSTEM_CONTROL_UNDOCK                  7
#define SYSTEM_CONTROL_SPEAKER_MUTE            8
#define SYSTEM_CONTROL_HIBERNATE               9
#define SYSTEM_CONTROL_DISPLAY_INVERT         10
#define SYSTEM_CONTROL_DISPLAY_INTERNAL       11
#define SYSTEM_CONTROL_DISPLAY_EXTERNAL       12
#define SYSTEM_CONTROL_DISPLAY_BOTH           13
#define SYSTEM_CONTROL_DISPLAY_DUAL           14
#define SYSTEM_CONTROL_DISPLAY_TOGGLE_INT_EXT 15
#define SYSTEM_CONTROL_DISPLAY_SWAP           16


 Michael
Which is the better way to wake up host from S3 suspend:
Code: [Select]
Keyboard.systemControl(SYSTEM_CONTROL_WAKEUP);
or
Code: [Select]

USBDevice.wakeupHost();

What is the difference?

Mike T

Which is the better way to wake up host from S3 suspend:
When the USB bus is suspended, the only signal which can be send is wakeupHost().
When the USB bus is not suspended, wakeupHost() will fail, you will notice by checking its return code.

Probably the best way would be:
Code: [Select]
if(!USBDevice.wakeupHost()) {
 Keyboard.systemControl(SYSTEM_CONTROL_WAKEUP);
}


It should also not hurt to send both. One of it will be ignored.


 Michael

Go Up