VirtualUsbKeyboard Arrow Keys for Atari Emulator (Stella)

I’m using the VirtualUsbKeyboard example code and I have only made a slight modification to the code. My goal is to use the Arrow Keys and the space bar to map in an old Atari joystick with a Atari emulator on a PC.

So far so good. The sketch works. The PC recognizes the HID keyboard. I wired in the joystick. Everything seems to be working.

Here is the problem:

When I bring up a game like Adventure when I move in a direction the motion is not smooth. I get a burst of movement then it stops, then bursts and stops.

If I use the regular arrow keys the motion is nice and smooth.

My thoughts are that I was clobbering the buffer with too many keystrokes but I’ve even tried only sending out a key


once every 30ms. The behavior seems to be the same.

I’m at my limit of understanding USB HID behavior so I was hoping a great mind out there can help…

Other background: I’m using the ATmega168PV-10PU with ADAboot and a 12MHz Crystal on a protoboard.

Here is the code:

* VirtualUsbKeyboard MODIFIED
* Enumerates itself as a HID (Human Interface Device) to a host
* computer using a USB shield. The Arduino then appears to the host to
* be a USB keyboard and keypress events can be sent on demand.
* This example watches the state of 6 push buttons and when a button
* is pressed it sends a matching keypress event to the host.
* Copyright 2009 Jonathan Oxer <>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.

// Requires the use of the "UsbKeyboard" library available from
#include "UsbKeyboard.h"

// Define the inputs to use for buttons
#define BUTTON_FIRE 6
#define BUTTON_UP 7
#define BUTTON_DOWN 8
#define BUTTON_LEFT 9
#define BUTTON_RIGHT 10

int i = 0;

* Configure button inputs and set up the USB connection to the host
void setup()
  // Set the button pins to inputs
  pinMode (BUTTON_UP, INPUT);
  // Enable the CPU's internal 20k pull-up resistors on the button
  // inputs so they default to a "high" state
  digitalWrite (BUTTON_FIRE, HIGH);
  digitalWrite (BUTTON_UP, HIGH);
  digitalWrite (BUTTON_DOWN, HIGH);
  digitalWrite (BUTTON_LEFT, HIGH);
  digitalWrite (BUTTON_RIGHT, HIGH);
  // Disable timer0 since it can mess with the USB timing. Note that
  // this means some functions such as delay() will no longer work.

  // Clear interrupts while performing time-critical operations

  // Force re-enumeration so the host will detect us

  // Set interrupts again

* Main program loop. Scan for keypresses and send a matching keypress
* event to the host
* FIXME: currently repeats as fast as it can. Add transition detection
void loop()


  if (digitalRead(BUTTON_FIRE) == LOW) {

  if (digitalRead(BUTTON_UP) == LOW) {

  if (digitalRead(BUTTON_DOWN) == LOW) {

  if (digitalRead(BUTTON_LEFT) == LOW) {

  if (digitalRead(BUTTON_RIGHT) == LOW) {


* Define our own delay function so that we don't have to rely on
* operation of timer0, the interrupt used by the internal delay()
void delayMs(unsigned int ms)
  for (int i = 0; i < ms; i++) {