description
Add general purpose input/output lines to your computer based projects. This circuit is a 12 pin digital GPIO interface using the Microchip PIC18f14k50 microcontroller which connects to an USB host port. The microcontroller is available in through-hole DIP20 and SMD packages, too.
Circuit diagram
The device is powered by the USB bus. 12 port bits can be set on a bit-by-bit basis to input or output direction. All LEDs on the schematic are optional, and are only shown for testing the device. You can find the USB connector pinouts at http://pinouts.ws/usb-pinout.html
Controlling the GPIO interface
A computer, any OpenWrt router, Raspberry Pi or other Linux development board with an USB host port can be used to control the GPIO extender. The “controlio” utility runs on all platforms.
Usage: controlio [options] <command> [value] Control an USB I/O port -d, --device <vendorid>[:productid] Select only device(s) with USB vendorid[:productid], default=0x04d8:0xf7c0 -s, --serial <serial number> Select only the device with the given serial number, default=any -o, --output <base> Set output format. Base x=hexadecimal (16), b=binary (2), d=decimal (10), default=x -v, --verbose Verbose mode -V, --version Show program version -h, --help Show usage and help
The commands are:
command line | description |
controlio getport | read the digital I/O port states |
controlio setdir <n> | set the digital I/O port directions. Use bit 1 to set direction to input, bit 0 to set direction to output <n> is a 16-bit number |
controlio setport <n> | set the digital I/O port output states. Sets all output I/O pins. Use bit value of 1 to set output to HIGH, 0 to set output to LOW <n> is a 16-bit number |
controlio setbit <n> | set the selected digital I/O port output pins to HIGH. Use bit value of 1 to select I/O pins to set <n> is a 16-bit number |
controlio clearbit <n> | set the selected digital I/O port output pins to LOW. Use bit value of 1 to select I/O pins to clear <n> is a 16-bit number |
Numbers for <vendorid>, <productid> and <n> can be given in decimal, hexadecimal or binary format. Hexadecimal numbers are prefixed with ‘0x’, binary numbers are prefixed with ‘0b’. Command output base can be also set to hexadecimal with switch -ox, decimalwith switch -od or binary with switch -ob.
Mapping of I/O port pins, directions to parameter <n> and buffer output:
controlio getport output | buffer[0] | buffer[1] | ||||||||||||||
I/O pin | RC7 | RC6 | RC5 | RC4 | RC3 | RC2 | RC1 | RC0 | RB7 | RB6 | RB5 | RB4 | – | – | – | – |
controlio setport <n> controlio setdir <n> controlio setbit <n> controlio clearbit <n> |
bit#7 | bit#6 | bit#5 | bit#4 | bit#3 | bit#2 | bit#1 | bit#0 | bit#15 | bit#14 | bit#13 | bit#12 | bit#11 | bit#10 | bit#9 | bit#8 |
Examples:
command line example | explanation |
controlio setdir 0xffff | set all I/O pins as input |
controlio getport | Read the digital I/O port states. The output is 16 bits long, and is shown in the selected base (use the -o command line switch). Output ports usually read back the state they are set to. Input ports read their externally set state. Command output is: 0xf0ff |
controlio -od getport | Read the digital I/O port states. Same as the previous command, but the output is printed in decimal:
61695 |
controlio -ob getport | Read the digital I/O port states. Same as the previous command, but the output is printed in binary:
0b1111000011111111 |
controlio setdir 0 | set all I/O pins as output |
controlio setport 0 | set all output I/O pins LOW |
controlio setport 12 or controlio setport 0xc or controlio setport 0xb1100 |
set the RC2 and RC3 I/O pins HIGH, other output pins LOW (works only on output pins) |
controlio setbit 32768 or controlio setbit 0x8000 or controlio setbit 0b1000000000000000 |
set the RB7 output pin HIGH, don’t change other output pins (works only if RB7 is an output pin) |
controlio clearbit 4097 or controlio clearbit 0x1001 or controlio clearbit 0b1000000000001 |
set the RB4 and the RC0 output pins LOW, don’t change other output pins (works only if RB4 and RC0 are output pins) |
Download
Download the full package. Contents:
bin/device_firmware | the firmware HEX file for the PIC18F14K50 device |
bin/host/linux.x86 | the Linux controlio utility executable |
bin/host/openwrt | the OpenWrt packages for the controlio utility |
bin/host/raspberry | Raspberry Pi binaries for the controlio utility |
bin/host/win.x86/driver | the drivers for using the GPIO device under Windows |
bin/host/win.x86 | the Windows controlio.exe utility |
src/device_firmware | the C18 source code for the PIC18F14K50 firmware |
src/host/openwrt | the source code for building the OpenWrt package |
src/host/posix | the source code for building the controlio utility for Linux and other POSIX compatible systems |
src/host/python | example code for accessing the GPIO device from python |
Previous, obsoleted version with assembly firmware
Installing on the PIC18F14K50 device
Program the bin/device_firmware/usbio.hex file with a Microchip Pickit 2 or Pickit 3 programmer into the chip.
Installing on the host
Linux
- install libusb-0.1 with “apt-get install libusb-0.1” or “yum install libusb”
- copy bin/host/linux.x86/99-usbio.rules to /etc/udev/rules.d/ – this lets everyone use the device
- copy bin/host/linux.x86/controlio to the host
- connect the GPIO extender to the USB port
Raspberry Pi
- install libusb-0.1 with “apt-get install libusb” on Raspbian or “yum install libusb” on Pidora
- copy bin/host/linux.x86/99-usbio.rules to /etc/udev/rules.d/ – this lets everyone use the device
- copy bin/host/raspberry/controlio to the host
- connect the GPIO extender to the USB port
For more detail: USB digital GPIO I/O extender