USB digital GPIO I/O extender using pic microcontoller

Summary of USB digital GPIO I/O extender using pic microcontoller


This article describes a 12-pin digital GPIO interface project using the Microchip PIC18F14K50 microcontroller, connecting to a USB host port. It details circuit power sourcing, control via the "controlio" utility on Linux, OpenWrt, or Raspberry Pi, and provides installation instructions for firmware and host software across various operating systems.

Parts used in the USB digital GPIO I/O extender:

  • Microchip PIC18f14k50 microcontroller
  • USB connector
  • LEDs (optional)
  • Microchip Pickit 2 or Pickit 3 programmer
  • libusb-0.1 library
  • 99-usbio.rules file

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

Quick Solutions to Questions related to USB digital GPIO I/O extender:

  • How is the device powered?
    The device is powered by the USB bus.
  • Can I use this with a Raspberry Pi?
    Yes, any Linux development board with a USB host port, including Raspberry Pi, can be used to control the GPIO extender.
  • What command reads the digital I/O port states?
    The controlio getport command reads the digital I/O port states.
  • How do I set all I/O pins as input?
    Use the command controlio setdir 0xffff to set all I/O pins as input.
  • How can I set specific output pins to HIGH?
    You can use controlio setbit followed by a number representing the bit value of the pin you want to set high.
  • What tool is required to program the firmware?
    You need a Microchip Pickit 2 or Pickit 3 programmer to install the firmware onto the chip.
  • Does the project support Windows?
    Yes, drivers and a controlio.exe utility are available for Windows.
  • What is the default USB vendor ID for this device?
    The default USB vendor ID is 0x04d8.

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter