Week 12 - Apr 4th 2012 - Interface and Application Programming
Weekly Assignment - write an application that interfaces with an input &/or output device
This week I wanted to experiment with directly interfacing through USB, sidestepping the need for the serial FTDI interface. To impliment this I worked with the V-USB software USB implementation for AVR microcontrollers.
The first stage was to build one of the examples included with the V-USB package. The LEDcontrol module attaches an LED to an output pin and allows it to be switched on or off using USB control messages, and also includes a message that requests the module send back the status of the LED. I was using the attiny45 microcontroller with 8 pins, so some had to double between ISP and USB (two lines are required, D+ and D-) duties, as seen in the schematic.
I used the makefile provided with the example to program the board. The setup required several files were edited:
- the makefile to correct the microcontroller, speed, programmer and fuses
- usbconfig.h to indicate the pins connected to D+ and D- from the USB socket
- main.c to indicate the pin the LED is connected to
To interface with the board, I wrote a python script that sends the various control commands to switch the LED on and off, and to request the LED status. Note that the
Next I wanted to adapt the LEDcontrol example to reaad an input. I adapted the board to have a push button instead of an LED, as seen in the schematic. NB. the schematic includes a 10k pull-up resistor pulling the input pin (PB1) high. This is also the pin used as the ISP MISO connection so I intended to program the board then add this resistor. While writing the program, however, it occurred to me I could activate the internal pull-up resistor so in the end didn't need to solder on the resistor at all.
For the hardware programming I adapted the LEDcontrol example code by editing the following files:
- makefile for the programming settings as above
- usbconfig.h to change the USB pins and device and vendor names. I could also have changed the identifier codes that the client-side software uses to ensure it is connected to the correct device in this file.
- resquests.h to define one custom command,
CUSTOM_RQ_POLL_STATUS , instruction index zero, that will be used to poll the button status. - main.c to set PB1 as an input and activate the internal pull-up resistor, and to define the action for
CUSTOM_RQ_POLL_STATUS - return the state of the button as shown in this snippet:if(rq->bRequest == CUSTOM_RQ_POLL_STATUS){ /*request status of button */ dataBuffer[0] = ((BUTTON_PORT_INPUT & _BV(BUTTON_BIT)) != 0); /* determine status of button */ usbMsgPtr = dataBuffer; /* prepare data to return */ return 1; /* send one byte */
I wrote another python script to continually poll the button by asking the USB device to send back the status, and then to display a label indicating the result. The frequency at which the script is polling the button is once per 100ms as determined by the