Total build cost was just $10.
I usually have at least one small project pending at all times. It's the occasional fun idea that pops into your head, and somehow sticks around a while until you say "Maybe I will create that one day". And it's not just software projects, usually it's a mix of technologies.
My latest project was to create an interactive speech-enabled Alarm Clock for my bedroom using
a cheap Windows tablet.
A tablet would not survive long if it was left on 24 hours a day, and since it is most likely equipped with a cheap MLC-based SSD drive, a power & disk preservation plan was needed: The tablet should be allowed to go into sleep mode. Once in sleep mode, it would no longer be able to display stuff. So the idea came to me: Add an infrared motion detection module to the tablet to make sure it is turned on while anyone is moving around in the bedroom.
The tablet actually has a USB port, making it easy to extend with some extra hardware. I'm not an electrical
engineer, but isn't really discouraged from fiddling with wires and knobs for tiny
Hence a few days later, a new Arduino UNO R3 and PIR Motion Sensor arrives.
Hooking up the PIR sensor with Arduino for testing is straightforward.
Everything is good.
Except maybe that this new setup needs to be able to wake a PC from sleep mode, similar to how most
USB keyboards are able to wake a PC by sending a special signal to the PC while it's
A quick web search later, and it turns out that even though the UNO R3 really is capable of acting as a USB Keyboard, the Remote Wake feature is not enabled by default. To do this, you will need to tweak the USB Keyboard HID driver built into the support-chip, ATmega16U2's firmware. Argh. Never despair. I've written USB drivers in the past albeit on Windows, but I should be able to pull this off.
And so the painful experience of compiling yet another open-source project on LINUX begins...
Don't grab the most recent virtual image of CentOS, and start installing and compiling Arduino and friends, because you will immediately be met with a barrage of dependency mismatches and compile errors. A large number of dependencies do not exist in the CentOS repositories, and the ones that do, fail with glaringly simple compile errors, such as
For me that was a few hours wasted.
We start over. This time with a system I'm guessing is similar to what the main library developers are using. Installing Debian 6, rolling on the dependencies is a somewhat smoother experience, only needing to fix a couple of compile errors and manually upgrading some defunct libraries. But eventually building the latest version of the Arduino and LUFA Driver libraries actually happens. On closer inspection, a lot of drivers for the Arduino are based on LUFA, a Lightweight USB Framework for AVRs. This even contains several keyboard driver examples. And the best part, the LUFA framework already has USB Suspend and Remote Wakeup support in the code, it just needs to be activated in the USB descriptors.
There is still one nag. I mentioned that the Arduino UNO R3 is capable of pretending of being a USB Keyboard. There are several models of Arduino boards, some better suited than other for different tasks. The UNO R3 has all of its USB device handling done on a support chip. This ATmega16U2 chip's firmware can be programmed, but it currently hosts the firmware that allows us to update the device with our new Arduino sketches (programs). Once we turn the thing into a keyboard, we won't be able to upload fixes to our code. Well, not before we re-flash with the old firmware anyway. So as long as we flash the ATmega16U2 firmware back and forth between firmwares, we are good to go. It's a bit of a bother, and it takes an awful long time to test stuff. Fortunately, your average Arduino sketches are usually humble in size.
Tweaking the USB Keyboard driver for the ATmega16U2 to enable the Remote Wake feature didn't turn
up to be a problem at all.
Add the LUFA
USB_CONFIG_ATTR_REMOTEWAKEUP flag and unfreeze the clock.
More interesting is that the ATmega16U2 chip really is an island. It talks USB protocol on one end,
and uses the USART to communicate with the main Arduino CPU. So you'll have to invent your own
protocol to talk to it from the Arduino sketch.
For a keyboard, this would simply be sending the 8 bytes that make up a raw USB scancode.
For a more complex USB Driver (which could expose both a Keyboard HID and a UART Serial interface) it
would be something more sinister.
Once you have laid out the wires to connect the PIR Motion Sensor to the Arduino,
then compiled and programmed both the Arduino sketch and ATmega16U2 firmware,
you have a little device which will wake up most Windows PCs.
However, as my device will be installed on a modern Windows tablet, the tablet will have Microsoft's new Connected Standby power configuration, rather than the traditional PC suspend and hibernate states. It turns out that sending the remote wakeup USB packet won't actually bring the display back to life, just the CPU. With a little tinkering, it seems that also sending the
POWER USB Keyboard scancode
too, faking the special keybutton press, will turn the display on. How lucky we already pretend to be a USB
So, with the provided download at the bottom of this page you will be able to avoid compiling the whole thing, and just build the device...
Acquire one Arduino UNO R3 clone,
a PIR Motion Sensor
and possibly some Male-to-Female Jump Cables.
In the Arduino IDE installation's /Drivers folder, run the "dpinst-x86.exe" or maybe the "dpinst-amd64.exe" for 64-bit Windows. Turn on the Arduino device. In the Windows Device Manager control panel app, make sure you have a "Arduino COM port". If not, find and right-click the unknown device and choose "Update software" and point it to the same folder below the Arduino software.
In the Arduino IDE, choose the "Arduino UNO" board, the "AVRISP mkii" programmer, and the correct port. Load the "Keyboard.ino" sketch from my download. Compile and upload to the device.
If everything went well you should see a LED light up whenever you move in front of the PIR. Note that these PIR sensors usually have two potentiometers that allow you to control the sensitivity and the detection range.
Now its time to program it with the new USB Keyboard driver. Open the Windows Device Manager. Bridge the left-most male pin next to the ATmega16U2 chip to GND as shown in the image to the right. Only touch it for a second or two. You should see the LEDs blink slowly. Depending on the Arduino device, you may need to reset it in a different manner.
In the Windows Device Manager you should see the Arduino COM port disappear, and a new undefined device appear. Right click on the item in Device Manager, and choose "Update driver software". Point the update location to where you installed the Atmel FLIP programmer. When done, open the FLIP software and choose the type as ATmega16U2, select medium type as USB, then from the menu "Load Hex file" and point to the "Lufa-Keyboard_atmega16u2_Uno_Rev3.hex" file from my download. Choose "Run" and then "Start Application".
Power cycle the Arduino. Find the newly attached keyboard item in the Windows Device Manager. Go into its Properties pages, and find the "Power Management" tab. Make sure the option to allow to wake the PC is enabled.
That's it. Run the "sleep.cmd" script from my download to force the PC into sleep mode and test everything.
To edit the Arduino sketch, you'll need to use FLIP to upload the "Arduino-usbserial-atmega16u2-Uno-Rev3.hex" from the Arduino IDE package to restore your Arduino back to normal.
If you're not really interested in the whole "PC Wakeup from Sleep"-part and just want to play with the Motion Sensor, you can skip the Keyboard driver step and use the Arduino sketch found in the "Use a PIR" or download below.
Source Code DependenciesArduino IDE 1.5
See AlsoFrogger on a LED display
|Arduino UNO R3 Keyboard driver (48 Kb)|