Categories
code electronics work

Simple ATTiny85 USB board

Process of creating a USB-enabled simple circuit with an ATTiny85.

IMG_20140623_121908_fixI needed to create a small, cheap USB-enabled circuit to serve as a key logger, and I’ve found some nice projects online that explain how to do this.
I found out you could use an ATTiny85 to run the V-USB software USB stack, and I only needed the one input pin to gather data (it’s going to be a USB “That was easy” button).
Since this was done so many times before, I will be brief, and try to point out problems I had instead of a regular tutorial.

For a tutorial please take a look at one of these:
http://www.obdev.at/products/vusb/easylogger.html
http://codeandlife.com/2012/02/22/v-usb-with-attiny45-attiny85-without-a-crystal/
http://www.instructables.com/id/Digispark-DIY-The-smallest-USB-Arduino/step4/Digispark-schematic/

Some products do it also:
https://www.sparkfun.com/products/9147
So I went ahead and drew out a circuit in Eagle (well, first I tried it on a breadboard):
tinyusb-sch
And created a routing for it (all through-hole components – yay!):
tinyusb-brd
I had to make sure the clearing is good for the Roland Modela machine we have in our shop at the Media Lab. The clearing should be 16mil, since the smaller bit we use is 1/64″.
Milled it out on the Modela and stuffed it:
IMG_20140623_111913_fix
NOTE: there is one air wire going from the ISP connector to the Tiny, with only top-layer routing it was hard to route it around stuff. I’ve jumped it with a wire, but it could also go on the bottom with a wire to keep things nice and clean on the top.
Programed the code from here on it, with an AVR programmer:
IMG_20140623_113001_fix
First I needed to fuse it though, to get the clock to run 16MHz:

avrdude -P usb -c stk500v2 -p attiny85 -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m

I’ve also made a little change to the code, to make the LED light up during the time it’s looking for the right OSCCAL value:

int main() {
    uchar i;
    DDRB = LED_PIN; // LED pin as output
    PORTB |= LED_PIN; // LED ON
    wdt_enable(WDTO_1S); // enable 1s watchdog timer
    usbInit();
    usbDeviceDisconnect(); // enforce re-enumeration
    for(i = 0; i<250; i++) { // wait 500 ms
        wdt_reset(); // keep the watchdog happy
        _delay_ms(2);
    }
    usbDeviceConnect();
    sei(); // Enable interrupts after re-enumeration
    PORTB &= ~LED_PIN; // LED OFF
    while(1) {
        wdt_reset(); // keep the watchdog happy
        usbPoll();
    }
    return 0;
}

Actually I first tried just the Blink sketch on Arduino, based on the tutorial by Dave Mellis: http://highlowtech.org/?p=1695
When everything is connected, USB Prober is happy and recognizes the device as “USBExample” (which is what the demo code makes it say).
IMG_20140623_121908_fix
To make this actually work as a keyboard for the PC (and not use the LibUSB interface to send low-level commands), I had to make some changes to the code based on some very good remarks here: http://codeandlife.com/2012/02/11/v-usb-tutorial-continued-hid-mouse/
The usbconfig.h file must be very accurate about defining:

#define USB_CFG_INTERFACE_CLASS     3  // this is needed in order to tell the PC this is an HID device
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    35 // this must correspond to the # of bytes of the descriptor in main.c

There are more things to do, depending on the needs, but the tutorial from before covers them pretty nicely.
I had fun doing this project! But it was frustrating too…
My lessons learned are:
– Check and then double-check your wires. Make sure everything is properly connected to the right place and there are no shorts.
– USB is fussy. It needs short, low impedance wires on the data lines, that is why I got a recommendation to make a PCB when my breadboard wasn’t working.
Enjoy,
Roy.

Leave a Reply

Your email address will not be published. Required fields are marked *