AVRUSB running on Arduino hardware with minishield

I manage to build the board according to Followers specs and followed his instructions, unfortunately it does not work as well. Out of frustration, I reinstalled my mac using the recovery disk. Downloaded a fresh version of Arduino (0015) and started the program. Amazingly when I plugged my device, the Mac Keyboard assist and did acknowledge I plugged in a Keyboard. Since I only have the sample program that came with Follower's work I can not proceed in answering the question of Mac (like press the button on the left shift button and right shift button) I canceled this task and now the keyboard assist does not pop out anymore.

I would like to ask anyone knowledgeable in making the Mac Keyboard Assistant pop out again. I think this is the way for me to let mac completely acknowledge my arduino as a keyboard.

Your response is highly appreciated.

Thanks :)

Alex,

I had a similar problem when I first got it fired up.

It is almost certainly looping in sendMessage() waiting for the interrupt to trigger.

to see if this is the case write to a LED wired to a digital pin like this:

__ void sendMessage(byte count, byte data)__ * {** ** if( count > BUFFER_SIZE )** ** count = BUFFER_SIZE;** ** memcpy( reportBuffer, data, count);** ** while (!usbInterruptIsReady())** ** {** digitalWrite(redLedPin,HIGH); ** usbPoll();** digitalWrite(redLedPin,LOW); ** }**

** usbSetInterrupt(reportBuffer, sizeof(reportBuffer));** // I don't use this wait loop. ** //while (!usbInterruptIsReady())** ** //{** ** // usbPoll();** ** //}**

** }**

If so I think your setup may be missing a response (check your config.h), or you may not have usbPoll() called inside the loop.

I ended up using the UsbHid version of the library because I wanted more than a keyboard.

cheers, Robert

This is probably just something dumb because I’m new to the Arduino but I’m having trouble when I include <Wconstants.h> in the UsbKeyboard.h header file.

In file included from /Users/alexevangelou/Documents/Arduino/hardware/cores/arduino/WProgram.h:4,

/Users/alexevangelou/Documents/Arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'

/Users/alexevangelou/Documents/Arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/include/stdlib.h:111: error: expected `)' before 'int'

/Users/alexevangelou/Documents/Arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/include/stdlib.h:111: error: expected `)' before 'int'

In file included from /Users/alexevangelou/Documents/Arduino/hardware/cores/arduino/WProgram.h:6,

What is the UsbHid version you’re talking about robbo?

My email is: lizard2033 -at- aol -dot- com Maybe if you could send me the files you’re using because they seem to be different than this library.

doh, my bad...

I made a version of UsbKeyboard kust for HID use, and called it UsbHid, because I needed it for the device I am working on.

I had to put

include "WProgram.h"

in my Usbkeyboard/UsbHid file in order to use digitalWrite()

This is the code I used: UsbHid.h

/*
 * Based on Obdev's V-USB code and under the same license.  This code is used for demonstration
 * purposes only. See www.obdev.at
 *
 * Extended to provide a HID device that sends a message of 4-16 bytes using the report mechanism.
 *
 */
#ifndef __UsbHid_h__
#define __UsbHid_h__

#include <avr/pgmspace.h>
#include <avr/interrupt.h>
//#include <avr/wdt.h>
#include <string.h>

#include "usbdrv.h"

#include "WProgram.h"
#define redLedPin    6 //--RL
#define greenLedPin  7 //--RL
#define blueLedPin   5 //--RL


typedef uint8_t byte;


#define BUFFER_SIZE 8 // for data


static uchar    idleRate;           // in 4 ms units 


/* We use a simplifed report descriptor which does not support the
 * boot protocol.
 * The report descriptor has been created with usb.org's "HID Descriptor Tool"
 * which can be downloaded from http://www.usb.org/developers/hidpage/.
 */

PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */
  0x05, 0x01,                    // USAGE_PAGE (Generic Desktop) 
  0x09, 0x06,                    // USAGE (Keyboard) 

  0xa1, 0x01,                    // COLLECTION (Application) 
        0x95, BUFFER_SIZE,             //   REPORT_COUNT (buffer length)
        0x75, 0x08,                    //   REPORT_SIZE (8) // bits in a byte
        0x15, 0x00,                    //   LOGICAL_MINIMUM (0) 
        0x26, 0xff,  0x00,             //   LOGICAL_MAXIMUM (255)
        0x09, 0x00,                    //   USAGE (undefined)
        0x81, 0x00,                    //   INPUT (Data,Ary,Abs) 
        0x91, 0x00,                               //   OUTPUT (Data,Ary,Abs)
  0xc0                           // END_COLLECTION 
};




class UsbHidDevice 
{
 public:
  UsbHidDevice () 
  {
    PORTD = 0; // TODO: Only for USB pins?
    DDRD |= ~USBMASK;


   cli();
    usbInit();
      
//   usbDeviceDisconnect();
//   usbDeviceConnect();

    sei();

    memset(reportBuffer, 0, sizeof(reportBuffer));      
//    usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
  }
    
  void update() 
  {
    usbPoll();
  }
    
  void sendMessage(byte count, byte *data) 
  {
        if( count > BUFFER_SIZE )
              count = BUFFER_SIZE;

      memcpy( reportBuffer, data, count);

      while (!usbInterruptIsReady()) 
      {
//digitalWrite(redLedPin,HIGH);
         //wdt_reset();
         usbPoll();
//digitalWrite(redLedPin,LOW);
      }
        
    usbSetInterrupt(reportBuffer, sizeof(reportBuffer));

      //while (!usbInterruptIsReady())
      //{
      //   //wdt_reset();
      //   usbPoll();
      //}
      
  }
    
  uchar    reportBuffer[BUFFER_SIZE];    // buffer for HID reports

};

UsbHidDevice UsbHid = UsbHidDevice();

#endif // __UsbHid_h__

this links with the VUSB stuff (from ObDev) just as you had done with UsbKeyboard.h. and then within the sketch, you’ll need to initialize this, and make use of it.

void setup()
{
  // disable timer 0 overflow interrupt (used for millis)
  TIMSK0&=!(1<<TOIE0); // ++
  
  Serial.begin(19200);
  delayMs(350);
  Serial.println("Wake up USB");
  
  cli();
    usbInit();
  sei();
  delayMs(125);

    Serial.println("Attempt enumeration - disconnect/connect.");
    delayMs(150);
    cli();
      usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
      delayMs(250);
      usbDeviceConnect();
    sei();
    Serial.println("Ready.");
}

to use it, you need to call update() in your loop(), and sendMessage() to send data.

byte buffer[BUFFER_SIZE];

void loop() 
{
  
  UsbHid.update();

// do anything else you need to do to prep the data or blink LEDs etc...
// then send the data when its ready.

    UsbHid.sendMessage(BUFFER_SIZE, buffer);
//

}

IIRC the 250ms delay between disconnect and connect was pretty important. Some systems needed more than just a pulse disconnect.

hope this helps,
Robbo

On a mac:

sudo tail -f /var/log/system.log
The IOUSBFamily is having trouble enumerating a USB device that has been plugged in.  It will keep retrying.  (Port 1 of hub @ location: 0x1d000000)

Thanks

robbo, thanks for the help so far. It was WProgram.h I needed not WConstants.h.

So now I can confirm that it’s getting stuck waiting for the usbPoll() as the led stays lit. Am I correct in assuming this is waiting to hear back from the master?

This seems like it was the same problem you described having before. Any idea how I can solve this?

Hey Alex,

As I remember, the delay between disconnect and reconnect at startup is important. The example shows a near instant (only a few microseconds) and this isn't enough for some hosts.

This disconnect forces the host (USB bus master) to re-enumerate this device (i.e "hey! pay attention to me")

If the device doesn't get enumerated it will not receive any messages, and you'll be stuck waiting for something to happen.

cheers, Robbo

As an aside, the correct response to the Keyboard Assistant is to close it and it should never run again. It is not relevant for this device.

I need to revisit AVRUSB/ V-USB with the current Arduino version but haven't done so yet.

--Phil.

Well as an update: I'm still having trouble with the sendKeyStroke function. The usbInterruptIsReady() is never triggering and it just gets stuck in the while loop forever.

For reference I'm talking about here specifically:

  void sendKeyStroke(byte keyStroke, byte modifiers) {
      
    while (!usbInterruptIsReady()) {
      usbPoll();
      // Note: We wait until we can send keystroke
      //       so we know the previous keystroke was
      //       sent.
    }
      
    memset(reportBuffer, 0, sizeof(reportBuffer));

Any idea how I can fix that? I'm really not sure how to fix it. The device re-enumeration in the setup does have a delay in it.

Hi Trying to get USBMouse library working on a Mac OS X.5. Compilation goes fine but when I pug in my board I get similiar errors to what Phil got with his USB keyboard in MAc OS X.... :

" kernel USBF: 93641.362 [0x40a6600] The IOUSBFamily is having trouble enumerating a USB device that has been plugged in. It will keep retrying. (Port 2 of hub @ location: 0x1d000000) kernel USBF: 93646.417 [0x40a6600] The IOUSBFamily was not able to enumerate a device. "

Anyone had any luck with USBMouse or USBKeyboard libraries on Mac OS X ?? Thanks! Sam

The code compiles on the Arduino 16 IDE with the modified header for Arduino 12... However, I get the "IOUSBFamily is having trouble enumerating..." error on my Mac.

I am also using the Atmega328p, not the 168, and don't know if that makes a difference.

I'm excited about getting this project working, though! Great work, follower, and thanks for sharing!

So I decided to dismantle an existing project so that I can try to get this project working with the Atmega168... and it works some of the time and is very inconsistent.

I followed the updates on your Feb 23, 2009 update as follows: - Connect the D- line from the original schematic's Digital Pin 3 to Digital Pin 4. - Connect a 2.2k resistor (I couldn't find a 1.5k) between Digital Pins 4 & 5 - Updated usbconfig.h, UsbKeyboard.h, and the UsbKeyboardDemo1.pde sketch file - Recompile the libraries with: avr-g++ -Wall -Os -I. -DUSB_CFG_CLOCK_KHZ=16000 -mmcu=atmega168 -c usbdrvasm.S -c usbdrv.c - Upload the sketch to the atmega168

When I connect it to my USB port initially, there are no logs added to the system.log file. However, once I press the button (connecting pin 12 to ground), I will get the error message:

The IOUSBFamily is having trouble enumerating a USB device that has been plugged in. It will keep retrying. (Port 1 of hub @ location: 0x1d000000) The IOUSBFamily has successfully enumerated the device.

And the device will continue to work... although it seems to be pressing the Enter key twice so the output looks like:

Hello World

Hello World

Hello World

instead of:

Hello World Hello World Hello World

After a few times of successfully enumerating the device, I will get this error:

The IOUSBFamily is having trouble enumerating a USB device that has been plugged in. It will keep retrying. (Port 1 of hub @ location: 0x1d000000) [0x7f81a00] The IOUSBFamily was not able to enumerate a device.

And the device will stop working until I unplug and replug the USB port.

Sometimes, I'll get this error message in the logs, too:

[0x7f81a00] The IOUSBFamily is having trouble enumerating a USB device that has been plugged in. It will keep retrying. (Port 1 of hub @ location: 0x1d000000) [0x7f81a00] The IOUSBFamily has successfully enumerated the device. IOUSBHIDDriver[0xa890600]::start - super::start returned false! IOUSBHIDDriver[0xa890600]::start - aborting startup

Any ideas as to why this is not working consistently?

Thank you!

I did get it running with the Atmega168! :) Sweet!

However, I'm still unable to get it working with the Atmega328p. Has anyone been successful getting the code to run on a 328?

I tried precompiling the UsbKeyboard library from:

avr-g++ -Wall -Os -I. -DUSB_CFG_CLOCK_KHZ=16000 -mmcu=atmega168 -c usbdrvasm.S -c usbdrv.c

to

avr-g++ -Wall -Os -I. -DUSB_CFG_CLOCK_KHZ=16000 -mmcu=atmega328p -c usbdrvasm.S -c usbdrv.c

And, of course, change the Board type in the Arduino IDE to "Arduino Duemilanove w/ ATmega328"

Is there anything else I need to do?

Thanks!

For the purposes of the V-USB library, the 168 and 328 are the same. So you should be able to use the library compiled with the 168 flags.

(It's what I've used for both 168 and 328)

cheers,

Thanks, robbo! I just found that out on another website, too, and got the code running on my 328 :slight_smile:

Just out of curiosity, will this be a problem when your code becomes too large for the 168, since the 328 has double the flash memory?

:-)

I'm keeping an eye on it!

Hello there, I am new to arduino and I was trying to use this library for my project with acoustic guitar to act as an usb keyboard. I am using windows and the problem is that I can't compile even the demo example. I read the Arduino notes and found:

  • At present the IDE won't compile our library so it needs to be pre-compiled with:

avr-g++ -Wall -Os -I. -DF_CPU=16000000 -mmcu=atmega168 -c usbdrvasm.S -c usbdrv.c

I really don't know how to do that (I guess it is a linux thing). can someone help? I would really apperciate it. Or is there any step by step tutorial for windows users? Thanks a lot for a reply

I really don't know how to do that (I guess it is a linux thing).

It should be possible to get it to work on Windows but in fact the code is pre-compiled for you--but unfortunately it won't work at all with IDE version 0017 due to a change in how libraries are compiled--so you would need to use version 0016.

If you are comfortable building the IDE from SVN then the code in there will work with the library with no extra work on your part. If that is not possible then you will need to wait for version 0018 to be released.

--Philip;

As an aside, I discovered (relatively) recently that the USB port you plug the device into has a large impact as to whether it will work or not. For example on my Apple laptop it will work when plugged into the USB port on one side but not the other.

--Philip;