Saturday, November 21, 2009

PIC18F and PyUSB

I finally got a clearer idea on how to use the PyUSB libray. PyUSB is simply a python binding/wrapper for libusb. There are only few examples of python scripts I found on the net regarding the use of PyUSB. Also, the documentation for PyUSB is not that comprehensive yet.

On the USB device side, fortunately, Microchip has provide a LibUSB example for their PICDEM Full Speed USB demo board. Aside from the firmware for the PIC18F4550 family (includes PIC18F2550), they also provided a simple demo (Windows) application (with source codes for MSVC++ and Qt). It's a good opportunity to study LibUSB library along its generic usb device driver.
After some trial&errors on my python script, I finally made my PyQt GUI program working. (Most of my mistakes on the PyUSB module usage were the incorrect types of arguments used in the pyusb functions).

Below is my proto circuit. Basically it's the same circuit I used in my PIC18F2550 USB HID Mouse project. I only added two LEDs on RB0 and RB1 pins of pic18f2550. I also included a 10k potentiometer on RA0 pin (ADC ANA0).

I made a minimal modification on the LibUSB example firmware by Microchip so that it will be compatible with PyUSB demo python script:
 /*   
Filename: main.c
*/

/** INCLUDES *********************/
#include "Compiler.h"
#include "HardwareProfile.h"
#include "GenericTypeDefs.h"
#include "USB/usb_device.h"
#include "USB/usb.h"
#include "USB/usb_function_generic.h"
#include "usb_config.h"

/** CONFIGURATION ****************/
#pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
#pragma config FOSC = HSPLL_HS
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = ON
#pragma config BORV = 3
#pragma config VREGEN = ON //USB Voltage Regulator
#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config LPT1OSC = OFF
#pragma config PBADEN = OFF
#pragma config STVREN = ON
#pragma config LVP = OFF
#pragma config XINST = OFF // Extended Instruction Set
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CPB = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRTB = OFF // Boot Block Write Protection
#pragma config WRTC = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTRB = OFF

/** VARIABLES ******************************************************/
#pragma udata USB_VARIABLES=0x500

unsigned char OUTPacket[64]; //User application buffer for receiving and holding OUT packets sent from the host
unsigned char INPacket[64]; //User application buffer for sending IN packets to the host
#pragma udata

USB_HANDLE USBGenericOutHandle;
USB_HANDLE USBGenericInHandle;
#pragma udata

/** PRIVATE PROTOTYPES *********************************************/
static void InitializeSystem(void);
void USBDeviceTasks(void);
void YourHighPriorityISRCode(void);
void YourLowPriorityISRCode(void);
void ProcessIO(void);

/** VECTOR REMAPPING ***********************************************/
#define REMAPPED_RESET_VECTOR_ADDRESS 0x00
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x08
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x18

#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void)
{
_asm goto YourHighPriorityISRCode _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void)
{
_asm goto YourLowPriorityISRCode _endasm
}

#pragma code
//These are your actual interrupt handling routines.
#pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode()
{
USBDeviceTasks();
} //This return will be a "retfie fast", since this is in a #pragma interrupt section
#pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode()
{
}

/** DECLARATIONS ***************************************************/
#pragma code

//////////////////////////////////////////////////////////////////////
void main(void)
{
InitializeSystem();
USBDeviceAttach();
while(1)
{
ProcessIO();
}
}

static void InitializeSystem(void)
{
ADCON1 |= 0x0F; // Default all pins to digital

USBGenericOutHandle = 0;
USBGenericInHandle = 0;

InitLEDs();
InitPot();
USBDeviceInit(); //usb_device.c. Initializes USB module SFRs and firmware variables to known states.
}

////////////////////////////////////////////////////////////
void ProcessIO(void)
{
if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host.
{
switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data.
{
case 0x80: // toggle LED1 (command from PC application)
LED1 = !LED1;
break;
case 0x82: // toggle LED2
LED2 = !LED2;
break;
case 0x81: //Get potentiometer position
adc_status = 1; // start a/d conversion
INPacket[0] = 0x81;
while(adc_status); // wait for the a/d conversion to complete (or use interrupt)
INPacket[1] = ADRESH; //read only 8-bit adc value (left justified)
if(!USBHandleBusy(USBGenericInHandle))
USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE);
break;
}

USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
}
}//end ProcessIO


/*********** USB Callback Functions ****************/
void USBCBSuspend(void)
{
}

void USBCBWakeFromSuspend(void)
{
}

void USBCB_SOF_Handler(void)
{
}

void USBCBErrorHandler(void)
{
}

void USBCBCheckOtherReq(void)
{
}

void USBCBStdSetDscHandler(void)
{
}

void USBCBInitEP(void)
{
USBEnableEndpoint(USBGEN_EP_NUM,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
}

void USBCBSendResume(void)
{
static WORD delay_count;
USBResumeControl = 1; // Start RESUME signaling
delay_count = 1800U; // Set RESUME line for 1-13 ms
do{
delay_count--;
}while(delay_count);
USBResumeControl = 0;
}

BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
{
switch(event)
{
case EVENT_CONFIGURED:
USBCBInitEP();
break;
case EVENT_SET_DESCRIPTOR:
USBCBStdSetDscHandler();
break;
case EVENT_EP0_REQUEST:
USBCBCheckOtherReq();
break;
case EVENT_SOF:
USBCB_SOF_Handler();
break;
case EVENT_SUSPEND:
USBCBSuspend();
break;
case EVENT_RESUME:
USBCBWakeFromSuspend();
break;
case EVENT_BUS_ERROR:
USBCBErrorHandler();
break;
case EVENT_TRANSFER:
Nop();
break;
default:
break;
}
return TRUE;
}

then, the generated hex code for PIC18F2550 device using C18 compiler:
 :020000040000FA  
:060000008AEF0AF0120075
:0600080073EF08F0120086
:06001800BEEF08F012002B
:02002A000000D4
:04002C00D9CFE6FF43
:10003000E1CFD9FFE6526A6A686A160E6F6E9F0EAC
:100040006B6E7B0E696E6D8C6E6A000EE66EE66AF4
:10005000E66A710EE66E0F0EE66E70EC0AF00B6E3D
:10006000050EE15E0B506D9CDF6ADF500B6E0C6A73
:10007000080E0B5C000E0C5810E2DF50040DF3CF9D
:10008000E9FFF4CFEAFF000EE926040EEA22EE6A49
:10009000EE6AEE6AEE6ADF2AE8D7160E706E68A680
:1000A0000CD0030EE66E680EE66E0F0EE66E39ECAF
:1000B00008F0E552E552E552F2D70001736B786B18
:1000C000796B7A6B6D98080E6B6F040E6C6F616BB9
:1000D000606BE552E552E7CFD9FF1200D9CFE6FFBA
:1000E000E1CFD9FFE6520001600507E16DBA05D006
:1000F000686A69806988020E606F6850040B0FE0BF
:100100006950040B0CE0020EE66E680EE66E0F0EF0
:10011000E66E39EC08F0E552E552E552E9D86DA2F9
:1001200002D0A19AA1D06850010B1BE06950010BCD
:1001300018E07CDF0001040E606F0401200E026FE6
:10014000040E036F080E016F006B8C0E0013E66A3D
:10015000680EE66E0F0EE66E39EC08F0E552E552D9
:10016000E5526850100B0FE06950100B0CE0A4D85A
:10017000040EE66E680EE66E0F0EE66E39EC08F0C1
:10018000E552E552E5526850400B1DE06950400BC6
:100190001AE0010EE66EE66A000EE66EE66A020EF0
:1001A000E66EE66A7DEC09F00B6E060EE15E0B5022
:1001B000060EE66E680EE66E0F0EE66E39EC08F07F
:1001C000E552E552E5526850200B04E06950200BDF
:1001D00001E04FD86850020B12E06950020B0FE0AB
:1001E000010EE66EE66A000EE66EE66AE668E6680E
:1001F0007DEC09F00B6E060EE15E0B506A6A040E90
:100200000001605D02E2A19A2FD069A62CD0DF6ABE
:10021000040EDF5C28E268A625D06CCF80F0030EC8
:10022000E66E680EE66E0F0EE66E39EC08F0E552EB
:10023000E552E552780E0001801502E178D810D021
:10024000000EE66EE66A800EE66E000EE66E010EA9
:10025000E66EE66A7DEC09F00B6E060EE15E0B5071
:10026000DF2AD6D700D0A19AE552E552E7CFD9FFD1
:10027000120070A015D063C0E9FF64C0EAFFEF5020
:1002800080080DE16BC0E9FF6CC0EAFFEF50840805
:1002900006E163C0E9FF64C0EAFF8C0EEF6E709068
:1002A000050EE66E680EE66E0F0EE66E39EC08F08F
:1002B000E552E552E55212006984040EE66E680EBE
:1002C000E66E0F0EE66E39EC08F0E552E552E552A7
:1002D0006D82000EE66EE66AE66EE66A040EE66E73
:1002E000E66A7DEC09F00B6E060EE15E0B50120023
:1002F000000EE66EE66AE66EE66A030EE66EE66AF3
:100300007DEC09F00B6E060EE15E0B506D92699468
:1003100068A40CD0020EE66E680EE66E0F0EE66E56
:1003200039EC08F0E552E552E552F2D71200D9CF88
:10033000E6FFE1CFD9FFE652FD0E000180155AE13C
:100340007E0E8015E8407F0B040DF3CF63F0F4CFF1
:1003500064F0000E6327040E642363C065F064C07C
:1003600066F0657563C0E9FF64C0EAFFEF503C0BBF
:10037000E842E8420D083CE163C0E9FF64C0EAFFDF
:10038000020EE926000EEA22EECF0BF0EFCF0CF0C2
:10039000280E0B1802E1040E0C1828E163C0E9FFD7
:1003A00064C0EAFF020EE926000EEA22200EEE6E7D
:1003B000040EED6EDF6ADF500B6E0C6A080E0B5CEC
:1003C000000E0C5813E2DF50EA6A280FE96E040EA3
:1003D000EA22EF50E66EDF50EA6A200FE96E040E63
:1003E000EA22E552E750EF6EDF2AE5D70DD801D0BB
:1003F0002ED805D0FD0E8015040801E14ED8E55237
:10040000E552E7CFD9FF12006BC0E9FF6CC0EAFFED
:10041000EF50800B05E06BC0E9FF6CC0EAFFEF6AAC
:1004200000016F6B706B746B756B736BB6D8000EDD
:10043000E66EE66AE66EE66A170EE66EE66A7DEC42
:1004400009F00B6E060EE15E0B5079EF04F0020E20
:100450000001705D02E1ADDB1FD06CD8000181515D
:100460001AE165C0E9FF66C0EAFFEE52080EEF6EC2
:1004700065C0E9FF66C0EAFF020EE926000EEA2227
:10048000200EEE6E040EED6E65C0E9FF66C0EAFF59
:100490008C0EEF6E01D0816B1200D9CFE6FFE1CF59
:1004A000D9FFE6526BC0E9FF6CC0EAFFEF50400B8A
:1004B00001E0010EDF6E00016B75080E605D0AE160
:1004C00022C46EFF6E50000803E2100E606F02D06F
:1004D000040E606F700528E16BC0E9FF6CC0EAFF95
:1004E000020EE926000EEA22280EEE6E040EED6ED4
:1004F000D5DA020E00016F5D07E16BC0E9FF6CC049
:10050000EAFF840EEF6E0FD0DF5007E16BC0E9FF0A
:100510006CC0EAFFC80EEF6E06D06BC0E9FF6CC07E
:10052000EAFF880EEF6E01D005D8E552E552E7CF1D
:10053000D9FF1200D9CFE6FFE1CFD9FF020EE126A5
:100540000001706B6BC0E9FF6CC0EAFFEF6A040E3C
:100550006B190B6E6CC00CF00BC0DEFF0CC0DDFF26
:10056000DECFE9FFDDCFEAFFEF6A78AF0CD07B5139
:100570007C1107E005D07CC0FAFF00017B51F96EC9
:10058000FADF0001789F020EE15C02E2E16AE552C7
:10059000E16EE552E7CFD9FF120004012051600B54
:1005A000E842E842E842E842E842000901E058D067
:1005B00021510C0A54E00B0A43E00C0A35E0010A11
:1005C00026E00B0A22E0020A20E0030A1CE0080AE7
:1005D00010E0010A0CE00F0A08E0030A01E03FD036
:1005E0000001738F080E606F3BD0C8D839D07FDB15
:1005F00037D00001610E716F000E726F7381010EB2
:10060000746F738F2DD014D92BD02BD829D02451AF
:100610000001716F726B620E7127000E722373817D
:10062000010E746F738F1CD00001738F040124516D
:10063000EA6A620FE96E000EEA2222C4EFFF10D0D0
:10064000000EE66EE66AE66EE66A160EE66EE66A8C
:100650007DEC09F00B6E060EE15E0B5001D000D070
:100660001200D9CFE6FFE1CFD9FF040EE126040145
:10067000220510E120511F0B00090CE10001738FCE
:10068000030E0401215D04E10001010E7F6F02D021
:1006900000017F6B0401225167E120511F0B02080A
:1006A00063E124510F0B00095FE00001738F040127
:1006B00024BF10D024510F0BE96EEA6AD890E936B6
:1006C000EA36670EE926000EEA22EECFDEFFEDCF16
:1006D000DDFF0FD024510F0BE96EEA6AD890E9369E
:1006E000EA366B0EE926000EEA22EECFDEFFEDCFF2
:1006F000DDFF030E215D07E1DECFE9FFDDCFEAFF7D
:10070000840EEF6E31D024510F0B0C6A700F0B6EFC
:100710000F0E0C22020E0BC0DBFF030E0CC0DBFF22
:10072000020EDBCFE9FF030EDBCFEAFFEE90ED52C6
:1007300024AF0DD0DECFE9FFDDCFEAFFEF6ADF7433
:10074000DECFE9FFDDCFEAFF400EEF6E0DD0DECF4A
:10075000E9FFDDCFEAFF880EEF6EDF74DECFE9FF41
:10076000DDCFEAFFC80EEF6E040EE15C02E2E16A43
:10077000E552E16EE552E7CFD9FF1200800E040189
:10078000205D55E10001C00E736F04012351030A7F
:100790002EE0010A0EE0030A03E00001736B47D06C
:1007A0000001900E716F130E726F120E746F756BE5
:1007B0003ED02251F66EF76AD890F636F7363A0EEA
:1007C000F626140EF7220900F5CF71F00A00F5CFD6
:1007D00072F0020E0001F76A7125F66E7251F7226F
:1007E0000900F5CF74F00A00F5CF75F020D0030EA4
:1007F000225D1AE22251F66EF76AD890F636F73685
:100800003C0EF626140EF7220900F5CF71F00A000F
:10081000F5CF72F071C0F6FF72C0F7FF0800F55017
:100820000001746F756B02D00001736B00D0120071
:10083000D9CFE6FFE1CFD9FF020EE1260401286BF4
:10084000296B20511F0B020A12E0030A0DE0010A76
:1008500001E03BD00001738F0401288100017F0576
:1008600002E10401288331D00001738F2ED00001F2
:10087000738F040124BF10D024510F0BE96EEA6A74
:10088000D890E936EA36670EE926000EEA22EECF66
:10089000DEFFEDCFDDFF0FD024510F0BE96EEA6ACA
:1008A000D890E936EA366B0EE926000EEA22EECF42
:1008B000DEFFEDCFDDFFDECFE9FFDDCFEAFFEF505A
:1008C000040B02E0010E286F00D0000173AF07D0C7
:1008D000280E716F040E726F7381020E746F020E18
:1008E000E15C02E2E16AE552E16EE552E7CFD9FF51
:1008F00012006D98000173BF4AD078AF28D0020E65
:10090000706F6BC0E9FF6CC0EAFFEE52EF6A6BC01C
:10091000E9FF6CC0EAFFC80EEF6E65C0E9FF66C074
:10092000EAFFEE52080EEF6E65C0E9FF66C0EAFF0F
:10093000020EE926000EEA22280EEE6E040EED6E7F
:1009400065C0E9FF66C0EAFFC80EEF6E1FD065C044
:10095000E9FF66C0EAFFEE52080EEF6E65C0E9FFE0
:1009600066C0EAFF020EE926000EEA22200EEE6EB5
:10097000040EED6E65C0E9FF66C0EAFF8C0EEF6EF7
:100980006BC0E9FF6CC0EAFF840EEF6E86D078BFC3
:1009900084D0040120AF59D0000174510401265DB8
:1009A000000175510401275904E226C474F027C4DC
:1009B00075F074D80001010E706F65C0E9FF66C064
:1009C000EAFFEE52080EEF6E65C0E9FF66C0EAFF6F
:1009D000020EE926000EEA22200EEE6E040EED6EE7
:1009E00065C0E9FF66C0EAFF800EEF6E816B63C0F1
:1009F000E9FF64C0EAFFEE52080EEF6E63C0E9FF44
:100A000064C0EAFF020EE926000EEA22200EEE6E16
:100A1000040EED6E63C0E9FF64C0EAFF840EEF6E62
:100A2000010E816F6BC0E9FF6CC0EAFF020EE92680
:100A3000000EEA22280EEE6E040EED6E6BC0E9FF8A
:100A40006CC0EAFFC80EEF6E28D00001020E706F76
:100A50006BC0E9FF6CC0EAFFEE52EF6A6BC0E9FFC2
:100A60006CC0EAFFC80EEF6E65C0E9FF66C0EAFF22
:100A7000EE52080EEF6E65C0E9FF66C0EAFF020E97
:100A8000E926000EEA22280EEE6E040EED6E65C019
:100A9000E9FF66C0EAFFC80EEF6E1200D9CFE6FF8D
:100AA000E1CFD9FF020EE1260001080E745D000EB1
:100AB00075590EE274C0DEFF75C0DDFF6F5103E1B2
:100AC000010E6F6F04D06F0502E1020E6F6F03D04D
:100AD000080EDE6EDD6A6BC0E9FF6CC0EAFFEF92C4
:100AE0006BC0E9FF6CC0EAFFEF906BC0E9FF6CC020
:100AF000EAFF010EDB50EF126BC0E9FF6CC0EAFFAA
:100B0000EE52DFCFEFFF000EDB50745F010EDB50C3
:100B1000755B280E7D6F040E7E6F73B121D0D9CF27
:100B2000E9FFDACFEAFFEE50ED1019E071C0F6FFF1
:100B300072C0F7FF712B000E72230800F550E66EAD
:100B40007DC0E9FF7EC0EAFF7D2B000E7E23E552CB
:100B5000E750EF6EDF06010E01E2DB06E0D71FD0A3
:100B6000D9CFE9FFDACFEAFFEE50ED1018E071C0FF
:100B7000E9FF72C0EAFF712B000E7223EF50E66EA0
:100B80007DC0E9FF7EC0EAFF7D2B000E7E23E5528B
:100B9000E750EF6EDF06010E01E2DB06E1D7020E41
:100BA000E15C02E2E16AE552E16EE552E7CFD9FF8E
:100BB0001200D9CFE6FFE1CFD9FF020EE12663C0D4
:100BC000E9FF64C0EAFFEE52EFCFDFFFDFCF0BF0AB
:100BD0000B500001795D000E7A5903E279C0DFFF06
:100BE00009D0DF500B6E0C6A0B50795D796F0C5099
:100BF0007A597A6F010EDB6ADF50F36E010EDBCF9C
:100C0000F4FFF350F45C16E2010EDB50EA6A280FA1
:100C1000E96E040EEA22EF50E66E76C0E9FF77C077
:100C2000EAFF762B000E7723E552E750EF6E010EB8
:100C3000DB2AE2D7000ED8807955000E7A5528E2DB
:100C400065C0E9FF66C0EAFFEE52080EEF6E65C0B0
:100C5000E9FF66C0EAFF020EE926000EEA22280E2E
:100C6000EE6E040EED6E63C0E9FF64C0EAFFEF5064
:100C7000400B07E165C0E9FF66C0EAFFC80EEF6EF2
:100C800006D065C0E9FF66C0EAFF880EEF6E25D08A
:100C900065C0E9FF66C0EAFFEE52080EEF6E65C060
:100CA000E9FF66C0EAFF020EE926000EEA22200EE6
:100CB000EE6E040EED6E65C0E9FF66C0EAFF840EBD
:100CC000EF6E7B517C1107E005D07CC0FAFF00017C
:100CD0007B51F96EFADF0001789F020EE15C02E2BF
:100CE000E16AE552E16EE552E7CFD9FF120000015B
:100CF000738F000EE66EE66AE66A710EE66E0F0E00
:100D0000E66E70EC0AF00B6E050EE15E0B50010E04
:100D1000E66EE66AE66A620EE66E000EE66E70EC5D
:100D20000AF00B6E050EE15E0B5022C461F0040167
:100D3000225104E10001100E606F11D00001200E5D
:100D4000606F000EE66EE66AE66EE66A150EE66E07
:100D5000E66A7DEC09F00B6E060EE15E0B501200A8
:100D6000D9CFE6FFE1CFD9FF020EE126000EDE6EFD
:100D7000040EDD6EFD0EDB50E8240D6EFE0EDB5022
:100D8000040DF3500D24040DF3500B6E0C6A020E8B
:100D90000F0B05E0D8900C320B32E806FBE1D8903F
:100DA0000B360C36D8900B360C36D9CFE9FFDACF9C
:100DB000EAFF0B50EE260C50ED22DECFE9FFDDCF2F
:100DC000EAFFEF9EFD0EDB500FE1FE0EEA6ADB3418
:100DD000FE0BEA36E96E670EE926000EEA22DECF48
:100DE000EEFFDDCFEDFF0ED0FE0EEA6ADB34FE0B28
:100DF000EA36E96E6B0EE926000EEA22DECFEEFF40
:100E0000DDCFEDFFDECFE9FFDDCFEAFFEF9CDECFE8
:100E1000E9FFDDCFEAFF040EE926000EEA22EF8C9F
:100E2000020EE15C02E2E16AE552E16EE552E7CFD3
:100E3000D9FF1200D9CFE6FFE1CFD9FF020EE1269C
:100E4000FE0EDB500C6A700F0B6E0F0E0C220BC0E7
:100E5000DEFF0CC0DDFFDECFE9FFDDCFEAFFFD0ED8
:100E6000DBCFEFFFDBA407D0E66AFE0EDBCFE6FFA9
:100E700077DFE552E552FD0EDBA208D0010EE66EEB
:100E8000FE0EDBCFE6FF6CDFE552E552020EE15CC1
:100E900002E2E16AE552E16EE552E7CFD9FF1200C6
:100EA000D9CFE6FFE1CFD9FF020EE126FE0EDB50DF
:100EB00020E165C0E9FF66C0EAFFEE52080EEF6E62
:100EC00065C0E9FF66C0EAFF020EE926000EEA22CD
:100ED000200EEE6E040EED6E65C0E9FF66C0EAFFFF
:100EE0008C0EEF6E6BC0E9FF6CC0EAFF840EEF6EF4
:100EF0003DD0FD0EDB50E8240D6EFE0EDB50040DE0
:100F0000F3500D24040DF3CF0BF0F4CF0CF0000ED2
:100F10000B26040E0C220BC0DEFF0CC0DDFF840E7E
:100F20000B6EDECFE9FFDDCFEAFF0B50EF12FD0EB7
:100F3000DB50E8240D6EFE0EDB50040DF3500D2443
:100F4000010F040DF3CF0BF0F4CF0CF0000E0B26C5
:100F5000040E0C220BC0DEFF0CC0DDFF840E0B6EF6
:100F6000DECFE9FFDDCFEAFF0B50EF12020EE15CAE
:100F700002E2E16AE552E16EE552E7CFD9FF1200E5
:100F8000D9CFE6FFE1CFD9FF020EE126FD0EDB50FF
:100F90000FE0FE0EEA6ADB34FE0BEA36E96E6B0EFA
:100FA000E926000EEA22EECFDEFFEDCFDDFF0ED008
:100FB000FE0EEA6ADB34FE0BEA36E96E670EE926BE
:100FC000000EEA22EECFDEFFEDCFDDFFDECFE9FF40
:100FD000DDCFEAFF020EE926000EEA22FB0EDBCF90
:100FE000EEFFFC0EDBCFEDFFDECFE9FFDDCFEAFF4A
:100FF000EE52FA0EDBCFEFFF400E0B6EDECFE9FFB5
:10100000DDCFEAFF0B50EF16880E0B6EDECFE9FF47
:10101000DDCFEAFF0B50EF12FD0EDB500CE0FE0EB1
:10102000EA6ADB34FE0BEA36E96E6B0EE926000E47
:10103000EA22EF740BD0FE0EEA6ADB34FE0BEA36CE
:10104000E96E670EE926000EEA22EF74DECF0BF0A0
:10105000DDCF0CF00BC0F3FF0CC0F4FF020EE15C1F
:1010600003E200D0E16AE552E16EE552E7CFD9FF35
:101070001200D9CFE6FFE1CFD9FF010EF36EFC0ECF
:10108000DB5004E0D890F336E806FCE1F350E81CAE
:101090000B6EFD0EDBCFE9FFFE0EDBCFEAFF0B5040
:1010A000EF16E552E7CFD9FF120005D06D6A696AE5
:1010B0000001606B00D012000001605113E16D6A05
:1010C000696A160E6F6E9F0E6B6E7B0E696ED08E08
:1010D000A28AA08AF28E6DB602D06D86FCD700017E
:0610E000010E606F12001A
:0A10E600DACFE4FFE2CFDAFFE9CF32
:1010F000E4FFEACFE4FFF6CFE4FFF7CFE4FFF5CF5C
:10110000E4FFF3CFE4FFF4CFE4FFFACFE4FF00EE17
:1011100000F00B0EE80403E3EECFE4FFFBD700EE94
:101120000BF0030EE80403E3EECFE4FFFBD7E65237
:101130006EEC00F0E55200EE0DF0030EE80403E360
:10114000E5CFEDFFFBD700EE0AF00B0EE80403E35A
:10115000E5CFEDFFFBD7E5CFFAFFE5CFF4FFE5CF15
:10116000F3FFE5CFF5FFE5CFF7FFE5CFF6FFE5CFDE
:10117000EAFFE5CFE9FFE5CFDAFF1100D8CFE4FFC2
:10118000E0CFE4FFE46EDACFE4FFE2CFDAFFE6522D
:10119000E552E5CFDAFFE550E5CFE0FFE5CFD8FF38
:1011A000100005D85CEC08F014D8FED712000F0E22
:1011B000C1120001906B916B926B936BFC0E8A16BF
:1011C000931692800E0EC16EC06E010EC26E16EFA7
:1011D00000F0200E0001605D03E36D50020B01E0A2
:1011E0005BD000019051911102E1000E08D090C037
:1011F000E9FF91C0EAFFEF50800B01E0010E00090A
:101200004BE105010051810A09E0030A05E0020AE9
:1012100001E02FD08A702DD08A722BD0C282810E2D
:10122000406FC2B2FED7C4CF41F500019251931175
:1012300002E1000E08D092C0E9FF93C0EAFFEF5030
:10124000800B01E0010E000913E1400EE66E400E36
:10125000E66E050EE66E010EE66EE66EC0EC07F079
:101260000B6E050EE15E0B50F3CF92F0F4CF93F0CE
:1012700000D0400EE66E000EE66E050EE66EE66AE3
:10128000010EE66EC0EC07F00B6E050EE15E0B5032
:10129000F3CF90F0F4CF91F0120012001200120080
:1012A0001200120012001E0EE66E010EE66E1AEC1F
:1012B00007F0E552E552400EE66E000EE66E050EB2
:1012C000E66EE66A010EE66EC0EC07F00B6E050EE8
:1012D000E15E0B50F3CF90F0F4CF91F012006D84EB
:1012E0000001080E946F070E956F9407000E955B32
:1012F00094519511FAE16D941200D9CFE6FFE1CF38
:10130000D9FFFD0EDBCF06F0FE0EDBCF07F0010E9E
:10131000061801E1075033E0E868061802E1E868C2
:1013200007182BE0030E061801E1075024E0040E15
:10133000061801E107501DE0020E061801E10750F2
:1013400016E0170E061801E107500FE0160E0618FA
:1013500001E1075008E0150E061801E1075001E011
:1013600010D0A1DF0FD09EDF0DD09BDF0BD097DF19
:1013700009D093DF07D092DF05D092DF03D00000C1
:1013800001D000D0010E00D0E552E7CFD9FF120006
:101390001201000200000008D8040402000001024B
:1013A000000109022000010100C03209040000020E
:1013B000FFFFFF0007050102400001070581024011
:1013C00000010403090434034D0069006300720046
:1013D0006F00630068006900700020005400650021
:1013E000630068006E006F006C006F00670079009A
:1013F000200049006E0063002E0040034D0069008C
:10140000630072006F0063006800690070002000D4
:101410004C00690062007500730062002000450006
:10142000780061006D0070006C00650020004400D1
:1014300065007600690063006500A213C213C6133D
:02144000FA139D
:0E1442002A0EF66E000EF76E000EF86E000118
:101450000900F5508B6F0900F5508C6F03E18B6725
:1014600001D03DD00900F550866F0900F550876F17
:101470000900F550886F09000900F550E96E090070
:10148000F550EA6E090009000900F550896F09005E
:10149000F5508A6F09000900F6CF8DF0F7CF8EF076
:1014A000F8CF8FF086C0F6FF87C0F7FF88C0F8FF3F
:1014B0000001895302E18A5307E00900F550EE6EFE
:1014C0008907F8E28A07F9D78DC0F6FF8EC0F7FFCB
:1014D0008FC0F8FF00018B07000E8C5BBFD7120096
:1014E000FE0EE3CFE9FFFF0EE3CFEAFFE9CFF3FF04
:1014F000EACFF4FFFB0EE35003E1FC0EE35009E0FA
:10150000FB0EE30602E2FC0EE306FD0EE350EE6E78
:04151000F1D71200FD
:0C15140013EE00F023EE00F0F86A0A9CD1
:1015200021EC0AF098EC0AF0D1EC08F0FBD712009D
:021530001200A7
:020000040030CA
:0100000024DB
:010001000EF0
:010002003FBE
:010003001EDE
:010005008179
:010006008178
:010008000FE8
:01000900C036
:01000A000FE6
:01000B00E014
:01000C000FE4
:01000D0040B2
:00000001FF


here's my python script for PyUSB (also uses PyQt for the GUI):
 ###########################################  
# PyUSB and PIC18F2550 demo (first revision) #
# Julius 'yus' Constante Nov. 21, 2009 #
###########################################

import sys, usb
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class UsbPic:
def __init__(self, vendor_id, product_id):
busses = usb.busses() # enumerate busses
self.handle = None
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor==vendor_id and dev.idProduct==product_id: # device matches
self.dev = dev
self.conf = self.dev.configurations[0]
self.intf = self.conf.interfaces[0][0]
self.endpoints = []
for endpoint in self.intf.endpoints:
self.endpoints.append(endpoint)
return

def open(self):
if self.handle:
self.handle = None
try:
self.handle = self.dev.open()
self.handle.detachKernelDriver(0)
self.handle.detachKernelDriver(1)
self.handle.setConfiguration(self.conf)
self.handle.claimInterface(self.intf)
self.handle.setAltInterface(self.intf)
return True
except:
return False

def write(self, ep, buff, timeout = 100):
try:
return self.handle.interruptWrite(ep, buff, timeout) #return bytes written
except:
return 0
def read(self, ep, size, timeout = 100):
try:
return self.handle.interruptRead(ep, size, timeout) # return data read
except:
return []
def getDeviceName(self):
return self.handle.getString(2, 40)

class SimpleForm(QDialog):
def __init__(self, parent = None):
super(SimpleForm, self).__init__(parent)
self.setWindowTitle('PIC18F and PyUSB')
self.setMinimumSize(270, 180)
# create widgets/controls
self.connect_btn = QPushButton('Connect')
self.toggle1_btn = QPushButton('Toggle LED1')
self.toggle2_btn = QPushButton('Toggle LED2')
self.pot_position = QDial()
self.pot_label = QLabel('Potentiometer Position')
self.status_label = QLabel(' press "Connect" button')
self.update_timer = QTimer()
# form layout and widgets location
layout = QGridLayout()
layout.addWidget(self.connect_btn, 9, 0, 2, 1)
layout.addWidget(self.pot_position, 0, 0, 8, 7)
layout.addWidget(self.pot_label, 8, 0, 1, 7)
layout.addWidget(self.toggle1_btn, 4, 7)
layout.addWidget(self.toggle2_btn, 5, 7)
layout.addWidget(self.status_label, 9, 1, 2, 7)
self.setLayout(layout)
# widgets initial condition
self.toggle1_btn.setEnabled(False)
self.toggle2_btn.setEnabled(False)
self.pot_position.setEnabled(False) #read only
self.pot_position.setNotchesVisible(True)
self.pot_position.setRange(0, 255) # for PIC 8-bit ADC value
self.pot_label.setAlignment(Qt.AlignHCenter)
# signals
self.connect(self.connect_btn, SIGNAL("clicked()"), self.DeviceConnect)
self.connect(self.toggle1_btn, SIGNAL("clicked()"), self.toggleLED1)
self.connect(self.toggle2_btn, SIGNAL("clicked()"), self.toggleLED2)
self.connect(self.update_timer, SIGNAL("timeout()"), self.updatePotPosition)

def DeviceConnect(self):
self.device = UsbPic(0x04d8, 0x0204) # Microchip Vendor ID and Product ID
if self.device.open():
self.toggle1_btn.setEnabled(True)
self.toggle2_btn.setEnabled(True)
self.update_timer.start(200) # update every 200ms
self.status_label.setText('Connected to:\n %s' %self.device.getDeviceName())
else:
self.toggle1_btn.setEnabled(False)
self.toggle2_btn.setEnabled(False)
self.update_timer.stop()
self.status_label.setText('Warning:\n No Device Found!')

def toggleLED1(self):
self.device.write(1, [0x80], 1000)

def toggleLED2(self):
self.device.write(1, [0x82], 1000)

def updatePotPosition(self):
self.device.write(1, [0x81])
byteread = self.device.read(0x81, 64)
if len(byteread)>1:
self.pot_position.setValue(byteread[1])

if __name__ == '__main__':
app = QApplication(sys.argv)
form = SimpleForm()
form.show()
sys.exit(app.exec_())



And finally, the actual circuit in action:
video

additional useful links:
Microchip USB Framework for PIC18, PIC24 & PIC32
LibUSB Win32

Sunday, November 15, 2009

PIC18F2550 USB HID Mouse

As my first step in learning on how to interface on PC USB ports, I copied the example source code for usb hid mouse by CCS C compiler. It's just a simple demo, moving the mouse pointer into a circular pattern, but it already gave me enough confidence because this example code works on my simple circuit. Since there's no problem with the circuit, I've continued with the next step which is the familiarization with the code routines/functions by modifying them (i.e. experimenting with the example code).

CCS C uses the usb_put_packet() command to send one packet to the usb host(PC), e.g. usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE). The out_data parameter is an array of 4 elements (i.e. int8 out_data[4]). The first byte of out_data correspond to the state of mouse buttons, the second and third are for the x and y directions, while the last byte is for mouse wheel.

After experimenting with the usb_put_packet() function, I came up with this modified demo code for usb hib mouse. Instead of only moving the mouse pointer, I've configured it to 'draw some lines' on Microsoft Paint. And this was the result:
video

Here's the code used in that demo video:
 // USB HID Mouse draws "usb pic18F2550" on MS Paint
#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

#define USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE 8
#include <pic18_usb.h>
#include <usb_desc_mouse.h>
#include <usb.c>

#define delay 20
#define scale 17
void draw_vertical(int8 direction)
{
int8 data[4], count = 0;
data[0] = 1;
data[1] = 0;
data[2] = direction;
data[3] = 0;
while(count<scale){
 if(usb_put_packet(1, data,4,USB_DTS_TOGGLE)) count++;
 delay_ms(delay);
}
}
void draw_horizontal(int8 direction)
{
int8 data[4], count = 0;
data[0] = 1;
data[1] = direction;
data[2] = 0;
data[3] = 0;
while(count<scale){
 if(usb_put_packet(1, data,4,USB_DTS_TOGGLE)) count++;
 delay_ms(delay);
}
}
void move_pointer(int8 x_direction, int8 y_direction)
{
int8 data[4], count = 0;
data[0] = 0;
data[1] = x_direction;
data[2] = y_direction;
data[3] = 0;
while(count<scale){
 if(usb_put_packet(1, data,4,USB_DTS_TOGGLE)) count++;
 delay_ms(delay);
}
}
void main(void)
{
usb_init_cs();

while (TRUE) {
 usb_task();
 if (usb_enumerated())
 {
   // 'u'
   draw_vertical(5);
   draw_horizontal(4);
   draw_vertical(-5);
   // 's'
   move_pointer(1,5);
   draw_horizontal(5);
   draw_vertical(-3);
   draw_horizontal(-4);
   draw_vertical(-3);
   draw_horizontal(4);
   // 'b'
   move_pointer(2,-4);
   draw_vertical(8);
   draw_horizontal(4);
   draw_vertical(-5);
   draw_horizontal(-4);
   // 'p'
   move_pointer(7,4);
   draw_horizontal(4);
   draw_vertical(-3);
   draw_horizontal(-4);
   draw_vertical(6);
   // 'i'
   move_pointer(5,-3);
   draw_vertical(-4);
   // 'c'
   move_pointer(4,3);
   draw_horizontal(-3);
   draw_vertical(-3);
   draw_horizontal(3);
   // '1'
   move_pointer(2,-4);
   draw_vertical(6);
   // '8'
   move_pointer(2,-3);
   draw_vertical(-3);
   draw_horizontal(3);
   draw_vertical(3);
   draw_horizontal(-3);
   draw_vertical(3);
   draw_horizontal(3);
   draw_vertical(-3);
   // 'F'
   move_pointer(2,4);
   draw_vertical(-7);
   draw_horizontal(4);
   move_pointer(-1,3);
   draw_horizontal(-3);
   // '2'
   move_pointer(4,-1);
   draw_horizontal(3);
   draw_vertical(3);
   draw_horizontal(-3);
   draw_vertical(3);
   draw_horizontal(3);
   // '5'
   move_pointer(2,0);
   draw_horizontal(3);
   draw_vertical(-3);
   draw_horizontal(-3);
   draw_vertical(-3);
   draw_horizontal(3);
   // '5'
   move_pointer(5,0);
   draw_horizontal(-3);
   draw_vertical(3);
   draw_horizontal(3);
   draw_vertical(3);
   draw_horizontal(-3);
   // '0'
   move_pointer(5,0);
   draw_vertical(-5);
   draw_horizontal(3);
   draw_vertical(5);
   draw_horizontal(-3);
   // line
   move_pointer(0,7);
   draw_horizontal(-22);
   draw_vertical(2);
   draw_horizontal(22);
  
  
   delay_ms(5000);
 }
}
}

then the HEX file generated using CCS Microchip C PCH v4.088 compiler:
 :020000040000FA  
 :040000005EEF07F0B8  
 :08000800056ED8CF06F0E0CF31  
 :1000100007F00001E9CF0DF0EACF08F0E1CF09F0D9  
 :10002000E2CF0AF0D9CF0BF0DACF0CF0F3CF14F017  
 :10003000F4CF15F0FACF16F000C00FF001C010F0A9  
 :1000400002C011F003C012F004C013F0A0AA2CEFFC  
 :1000500000F0A1BA2EEF06F00FC000F010C001F0C2  
 :1000600011C002F012C003F013C004F00DC0E9FF8C  
 :1000700008C0EAFF088E09C0E1FF0AC0E2FF0BC01A  
 :10008000D9FF0CC0DAFF14C0F3FF15C0F4FF16C08F  
 :10009000FAFF055007C0E0FF06C0D8FF1000F76A5E  
 :1000A000AE0FF66E000EF7220900F55012000403A1  
 :1000B0000000000000000000000000000000F76ADF  
 :1000C000CE0FF66E000EF7220900F5501200040064  
 :1000D0000000000000000000000000000000F76ABF  
 :1000E000EE0FF66E000EF7220900F55012004000E8  
 :1000F00008000000000000000000000000000000F8  
 :100100000000000000000000000000000000F76A8E  
 :100110001E0FF66E010EF7220900F5501200400086  
 :1001200000000000000000000000000000000000CF  
 :100130000000000000000000000000000000F76A5E  
 :100140004E0FF66E010EF7220900F5501200050160  
 :100150000902A1010901A1000509190129031500DE  
 :100160002501950375018102950175058101050140  
 :100170000930093109381581257F750895038106F5  
 :10018000C0C0F76A920FF66E010EF7220900F55013  
 :1001900012000000F76AA40FF66E010EF7220900A4  
 :1001A000F55012003400F76AB60FF66E010EF72212  
 :1001B0000900F550120009022200010100C03209B5  
 :1001C00004000001030102000921000100012234A2  
 :1001D000000705810308000AF76AE80FF66E010EB2  
 :1001E000F7220900F55012000100F76AFA0FF66EC7  
 :1001F000010EF7220900F550120012011001000053  
 :10020000004061042200000101020001F76A1C0F96  
 :10021000F66E020EF7220900F550120000040C00E1  
 :10022000F76A300FF66E020EF7220900F550120041  
 :100230000403090408034300430053001C03430064  
 :1002400043005300200055005300420020004D00A1  
 :100250006F007500730065006D926994689439EFC2  
 :1002600006F06A6A689242EF06F03E6A3E520AE180  
 :10027000036A3E50240FE96E000E0320EA6EEF6A17  
 :100280003E2AF4D71A6A010E1B6E196A000C010E81  
 :10029000476E47500F080EE3700E4724016E0F0E95  
 :1002A000036ED8B0032A01C0E9FF03C0EAFFEF6A7A  
 :1002B000472AEFD71E6A1D6A000C400E0401016F29  
 :1002C000050E036F026B880E006F046B050E076F3F  
 :1002D000400E066F0001000C6A6A686A9F0E6B6E22  
 :1002E000390E696E6E6AC1DFD2DF160E706E68A6B7  
 :1002F00002D06896FCD76D98E0DF030E1F6E48EFC2  
 :1003000006F0698468986D824EEF06F0689C54EFA1  
 :1003100006F070A002D0D1DF7090689A5AEF06F014  
 :1003200042C020F0000CFF0E206E000C406A2352E9  
 :100330003EE040503F083BE31C50FC0F2BE2040F13  
 :10034000E1EF01F0036A2250F2CF42F0F29E2BDF80  
 :1003500042BEF28E416E1ED0036A2250F2CF42F0AE  
 :10036000F29EEDDE42BEF28E416E14D0036A225040  
 :10037000F2CF42F0F29E54DF42BEF28E416E0AD0BE  
 :10038000036A2250F2CF42F0F29E2FDF42BEF28E7D  
 :10039000416E00D0222A23064050402A036A400FB3  
 :1003A000E96E050E0320EA6E41C0EFFFC0D723526D  
 :1003B00004E14050400801E0196A40C042F0B0DF5B  
 :1003C000000CE824F76AF736DD0FF66E030EF7220D  
 :1003D0000A00F550FA6E0800F550F96E4403580310  
 :1003E0006C038003226A1C6A05010351010A0001A3  
 :1003F00009E0030A0CE0010A0DE0220A22E0030AE8  
 :1004000032E058D0120E236E030E1C6E55D0220E11  
 :10041000236E52D0020E1C6E036A05010251F2CF08  
 :1004200040F0F29E0001F2DE40BEF28E226E036AC0  
 :100430002250F2CF40F0F29EF3DE40BEF28E236EE9  
 :100440003BD0120E226E223C01D00BD0036A225008  
 :10045000F2CF40F0F29EA7DE40BEF28E236E2CD08B  
 :1004600002D061DF35D0D89005010435036AF2CFA0  
 :1004700040F0F29E000185DE0900F5CF03F040BE9A  
 :10048000F28E226E223C01D013D0010E1C6ED89049  
 :1004900005010435036AF2CF40F0F29E00017ADED6  
 :1004A0000900F5CF03F040BEF28E236E05D002D0D6  
 :1004B0003ADF0ED038DF0CD00501075305E1235099  
 :1004C000065D02E206C523F0010E196E00012EDF63  
 :1004D000000C3F5204E1040E1F6ED9DEC1D0050EA0  
 :1004E0001F6E426E800E416E010E406E40500F082E  
 :1004F000D8A0B6D0436A036A4050F2CF47F0F29ECC  
 :10050000DEDD47BEF28E000A51E0040E436ED89045  
 :100510004034036AF2CF47F0F29EF9DD0900F5CFCF  
 :1005200003F047BEF28E446E03C045F04050080D04  
 :10053000F350010F016E040E036ED8B0032A01C000  
 :10054000E9FF03C0EAFF44C0EFFF4050080DF3503D  
 :10055000020F016E040E036ED8B0032A01C0E9FF3A  
 :1005600003C0EAFF42C0ECFFED5241C0EFFFD8905C  
 :100570004034036AF2CF47F0F29EC9DD0900F5CF9F  
 :1005800003F047BEF28E412603504222880E466E8B  
 :1005900045B0468045B246824050080DF3CF01F089  
 :1005A000040E01C0E9FFEA6E46C0EFFF036A405047  
 :1005B000F2CF47F0F29E73DD47BEF28E000A31E0C3  
 :1005C00043824050080DF350060F016E040E036E77  
 :1005D000D8B0032A01C0E9FF03C0EAFF42C0ECFF24  
 :1005E000ED5241C0EFFFD8904034036AF2CF47F09C  
 :1005F000F29E75DD0900F5CF03F047BEF28E41266D  
 :10060000035042224050080DF350040F016E040EB7  
 :10061000036ED8B0032A01C0E9FF03C0EAFF400E11  
 :10062000EF6E4350060802E10E0E436E036A40501F  
 :10063000F2CF47F0F29E33DD47BEF28E020801E0B2  
 :100640004388700E4024016E0F0E036ED8B0032A4B  
 :1006500001C0E9FF03C0EAFF43C0EFFF402A46D7CD  
 :100660007CEF03F00501015100010DE0010A14E0E7  
 :10067000020A1EE0060A27E0030A2CE00E0A2CE01C  
 :10068000010A30E03DD01BC040F50501416B020E70  
 :10069000426E000145DE36D00501022D06D0010E66  
 :1006A0001B16426A00013CDE02D000013CDE2AD06B  
 :1006B0000501022D05D01B82426A000131DE02D005  
 :1006C000000131DE1FD0020E196E02C521F0426A10  
 :1006D00027DE18D087DE16D01AC040F5010E426E14  
 :1006E0001FDE10D005010251010808E302C51AF00F  
 :1006F00002C53FF00001EDD6426A12DE000102D0D1  
 :1007000012DE00D0B2EF04F01AC03FF00501015133  
 :10071000000107E00A0A0DE0010A2DE00D0A3DE0A4  
 :100720003ED00501406B416B020E426E0001F8DDC8  
 :1007300038D03F521EE0010E3F5C036AF2CF40F01A  
 :10074000F29E4ADD40BEF28E016E0501045DD8A026  
 :1007500002D000010ED0036A0451240FE96E000E8E  
 :100760000320EA6EEFCF40F5010E426E0001D8DDA6  
 :1007700001D0D9DD16D03F520EE0036A05010451C5  
 :10078000240FE96E000E0320EA6E02C5EFFF426AF5  
 :100790000001C6DD01D0C7DD04D024DE02D0C3DDF8  
 :1007A00000D0B2EF04F040903FBE40803F9E40A09A  
 :1007B00010D0036A3F50F2CF41F0F29E70DC41BE90  
 :1007C000F28E000A02E1000E01D0010E016E10D07F  
 :1007D0000FD0036A3F50F2CF41F0F29E70DC41BE71  
 :1007E000F28E000A02E1000E01D0010E016E00D06F  
 :1007F0006AEF04F040903FBE40803F9E40A010D082  
 :100800003F50080DF350040F016E040E036ED8B074  
 :10081000032A01C0E9FF03C0EAFF880EEF6E09D08A  
 :100820003F50080DF3CF01F0040E01C0E9FFEA6E5E  
 :10083000EF6A79EF04F040903FBE40803F9E40A0B9  
 :1008400010D03F50080DF350040F016E040E036EDC  
 :10085000D8B0032A01C0E9FF03C0EAFF840EEF6E9F  
 :100860000AD03F50080DF3CF01F0040E01C0E9FF9C  
 :10087000EA6E840EEF6E7FEF04F040903FBE408042  
 :100880003F9E40A010D03F50080DF350040F016E62  
 :10089000040E036ED8B0032A01C0E9FF03C0EAFFCB  
 :1008A000EFCF41F00AD03F50080DF3CF01F0040E16  
 :1008B00001C0E9FFEA6EEFCF41F041AE02D041B492  
 :1008C00002D0000E01D0010E016E89EF04F004C5C4  
 :1008D0003FF069D7015229E005010151010A0001E9  
 :1008E00005E0020A09E0030A0DE01DD004C53FF04F  
 :1008F00081D7426A15DD19D004C53FF09CD7426A02  
 :100900000FDD13D00501406B416B04C53FF00001C2  
 :10091000B4D7015204E0010E0501406F0001020E40  
 :10092000426EFEDC02D0FFDC00D0B2EF04F0050125  
 :10093000015100D00001F7DC00D0B2EF04F0196AD9  
 :10094000050100517F0B000107E0010A06E0030AE0  
 :1009500005E0230A04E004D085D6D6D6B8D7E7D779  
 :10096000E2DC00D0D9EF05F03F50080DF3CF01F0E5  
 :10097000040E01C0E9FFEA6EEFCF41F040500208DB  
 :1009800006E141AC02D0406A02D0010E406E4050F8  
 :10099000030812E1840E416E3F50080DF350040F1E  
 :1009A000016E040E036ED8B0032A01C0E9FF03C034  
 :1009B000EAFF840EEF6E09D0402C03D0C80E416EC2  
 :1009C00004D0405202E1880E416E036A010E026EAD  
 :1009D0003F50006E05E0D89002360336002EFBD75C  
 :1009E0000250FF0A006EFF0E031A00501D1603503E  
 :1009F0001E16D8903F34036AF2CF44F0F29E87EC83  
 :100A000000F00900F5CF03F044BEF28E426E03C041  
 :100A100043F03F50080DF350010F016E040E036EBA  
 :100A2000D8B0032A01C0E9FF03C0EAFF42C0EFFFCC  
 :100A300043B0418043B241823F50080DF3CF01F0F3  
 :100A4000040E01C0E9FFEA6E41C0EFFF000C3F5009  
 :100A5000080DF350040F016E040E036ED8B0032A84  
 :100A600001C0E9FF03C0EAFFEFCF43F043BE5BD014  
 :100A70003F50080DF350050F016E040E036ED8B001  
 :100A8000032A01C0E9FF03C0EAFF40C0EFFF425064  
 :100A9000020816E13F50080DF350040F016E040EDA  
 :100AA000036ED8B0032A01C0E9FF03C0EAFFEFCF0D  
 :100AB00043F043AC02D0426A02D0010E426E13D022  
 :100AC0004250040810E13F50080DF3CF01F0040E2E  
 :100AD00001C0E9FFEA6EEFCF43F043AC03D0010E53  
 :100AE000426E01D0426A422C03D0C80E436E04D03D  
 :100AF000425202E1880E436E41B0438041B24382CC  
 :100B00003F50080DF350040F016E040E036ED8B071  
 :100B1000032A01C0E9FF03C0EAFF43C0EFFF010E53  
 :100B2000016E03D000D0000E016E000C3F5203E1B5  
 :100B30005DEC01F00FD0036A010E026E3F50006EB3  
 :100B400005E0D89002360336002EFBD702501D1266  
 :100B500003501E12000C40C06EFF405203E0040E12  
 :100B60001F6E02D0020E1F6EBBEF05F01A6A196AE3  
 :100B700021C040F0F0D7C8EF05F03F5209E1192C31  
 :100B800003D096EC01F004D01950020801E1EED731  
 :100B9000000C6C303E6E3E323E321F0E3E166C52E2  
 :100BA0003BE1040100513C0B34081BE1046B0001E4  
 :100BB000C6D6203C05D03F6A030E406ED5DE0ED06F  
 :100BC0003F6A020E406ED0DE2050FE0807E03F6A0A  
 :100BD000416A20C040F0040E426E39DF6D9819D092  
 :100BE000040100513C0B040815E13F6A00019EDF3F  
 :100BF0003F6A020E406EB8DE2050FE080AE0203C3C  
 :100C000001D007D03F6A416A20C040F0010E426E19  
 :100C10001EDF040120D000016C50040812E1FF0E19  
 :100C2000206E3F6AAADF203C01D008D03F6A416AAB  
 :100C300020C040F0020E426E0ADF02D05DEC01F0EF  
 :100C400009D06CB404D03EC03FF070DF03D03EC08A  
 :100C50003FF093DF040100015FEF06F01F5201E156  
 :100C60002FD068522DE068A404D069A402D02CEFE4  
 :100C700001F06DA201D024D068A204D069A202D0F4  
 :100C800031EF01F068A004D069A002D06CEF01F050  
 :100C900068A804D069A802D081EF01F068AC04D044  
 :100CA00069AC02D086EF01F068AA04D069AA02D02C  
 :100CB00089EF01F068A604D069A602D06AD76896C9  
 :100CC000A19A2CEF00F06D6A696A080E6F6E94505D  
 :100CD0003009946E1F6A186AF2BE188EF29E35ECC7  
 :100CE00001F018BEF28E1E6A1D6A6CEF07F0186ADA  
 :100CF000F2BE188EF29E35EC01F018BEF28E6D6ACF  
 :100D0000140E6F6E696A6D86010E1F6E8BEF06F012  
 :100D10006DB601D0ECD71F2C0BD06DBA09D0686A24  
 :100D2000696AA08AC00EF212110E696E020E1F6E61  
 :100D30006DEF07F02C50080DF350040F016E040EF8  
 :100D4000036ED8B0032A01C0E9FF03C0EAFFEFCF6A  
 :100D500034F034BE45D02C50080DF350060F016E10  
 :100D6000040E036ED8B0032A01C0E9FF03C0EAFFF6  
 :100D7000ECCF03F0ED52EFCF35F003C036F0336A1D  
 :100D8000326A3350305C1AE303E12F50325C16E2D2  
 :100D90002DC0E9FF2EC0EAFFEFCF39F036C0EAFFE1  
 :100DA00035C0E9FF39C0EFFF352AD8B4362A2D2ADD  
 :100DB000D8B42E2A322AD8B4332AE3D7186AF2BE1E  
 :100DC000188EF29E2CC03FF030C041F02FC040F092  
 :100DD00031C042F03CDE18BEF28E015003D000D08C  
 :100DE000000E016E000CEA6A2C0EE96EEF500EE068  
 :100DF0000F0E016E006A002EFED7012EFBD78F0E5C  
 :100E0000006E002EFED70000EF2EF2D7000C2A6AEB  
 :100E1000010E266E276A25C028F0296A2A5010087C  
 :100E200012E3010E2C6E2E6A260E2D6E306A040E11  
 :100E30002F6E020E316E7EDF0152D8A42A2A140EC4  
 :100E40002C6ED1DFEBD7000C2A6A010E266E25C06E  
 :100E500027F0286A296A2A50100812E3010E2C6E26  
 :100E60002E6A260E2D6E306A040E2F6E020E316E23  
 :100E700061DF0152D8A42A2A140E2C6EB4DFEBD7FE  
 :100E8000000C2B6A276A25C028F026C029F02A6AA0  
 :100E90002B50100812E3010E2C6E2E6A270E2D6EB9  
 :100EA000306A040E2F6E020E316E44DF0152D8A458  
 :100EB0002B2A140E2C6E97DFEBD7000CF86AD09E0D  
 :100EC000088EEA6AE96AC150C00B0F09C16E070EAD  
 :100ED000B46E1F6A236AF7D61BD71A52D8B4E8D06B  
 :100EE000050E256E94DF040E256EAEDFFB0E256E1B  
 :100EF0008EDF010E256E050E266EC3DF050E256EF4  
 :100F0000A3DFFD0E256E83DFFC0E256E9DDFFD0E3B  
 :100F1000256E7DDF040E256E97DF020E256EFC0E1A  
 :100F2000266EAFDF080E256E72DF040E256E8CDF95  
 :100F3000FB0E256E6CDFFC0E256E86DF070E256E20  
 :100F4000040E266E9EDF040E256E7EDFFD0E256EDE  
 :100F50005EDFFC0E256E78DF060E256E58DF050E6F  
 :100F6000256EFD0E266E8DDFFC0E256E50DF040E05  
 :100F7000256E030E266E85DFFD0E256E65DFFD0EE8  
 :100F8000256E45DF030E256E5FDF020E256EFC0E1B  
 :100F9000266E77DF060E256E3ADF020E256EFD0EF9  
 :100FA000266E6FDFFD0E256E32DF030E256E4CDFE1  
 :100FB000030E256E2CDFFD0E256E46DF030E256E1B  
 :100FC00026DF030E256E40DFFD0E256E20DF020EAC  
 :100FD000256E040E266E55DFF90E256E18DF040E01  
 :100FE000256E32DFFF0E256E030E266E4ADFFD0EE4  
 :100FF000256E2ADF040E256EFF0E266E42DF030EDD  
 :10100000256E22DF030E256E02DFFD0E256E1CDF2E  
 :10101000030E256EFCDE030E256E16DF020E256E16  
 :10102000266A2FDF030E256E0FDFFD0E256EEFDE25  
 :10103000FD0E256E09DFFD0E256EE9DE030E256E21  
 :1010400003DF050E256E266A1CDFFD0E256EFCDE15  
 :10105000030E256EDCDE030E256EF6DE030E256E16  
 :10106000D6DEFD0E256EF0DE050E256E266A09DF42  
 :10107000FB0E256ECCDE030E256EE6DE050E256E1C  
 :10108000C6DEFD0E256EE0DE256A070E266EF9DE51  
 :10109000EA0E256ED9DE020E256EB9DE160E256E1D  
 :1010A000D3DE140E256EFA0E2C6E9DDE252EFBD798  
 :0410B00013D703004F  
 :020000040030CA  
 :0E000000240E3E1E008381000FC00FE00F4053  
 :00000001FF  
 ;PIC18F2550  
 ;CRC=1458 CREATED="15-Nov-09 13:45"  


Also, the first hex code that worked on my circuit
(mouse pointer in circular movement):
 :020000040000FA
:040000001EEF07F0F8
:08000800056ED8CF06F0E0CF31
:1000100007F00001E9CF0DF0EACF08F0E1CF09F0D9
:10002000E2CF0AF0D9CF0BF0DACF0CF0F3CF14F017
:10003000F4CF15F0FACF16F000C00FF001C010F0A9
:1000400002C011F003C012F004C013F0A0AA2CEFFC
:1000500000F0A1BA43EF06F00FC000F010C001F0AD
:1000600011C002F012C003F013C004F00DC0E9FF8C
:1000700008C0EAFF088E09C0E1FF0AC0E2FF0BC01A
:10008000D9FF0CC0DAFF14C0F3FF15C0F4FF16C08F
:10009000FAFF055007C0E0FF06C0D8FF1000F76A5E
:1000A000AE0FF66E000EF7220900F55012000403A1
:1000B0000000000000000000000000000000F76ADF
:1000C000CE0FF66E000EF7220900F5501200040064
:1000D0000000000000000000000000000000F76ABF
:1000E000EE0FF66E000EF7220900F55012004000E8
:1000F00008000000000000000000000000000000F8
:100100000000000000000000000000000000F76A8E
:100110001E0FF66E010EF7220900F5501200400086
:1001200000000000000000000000000000000000CF
:100130000000000000000000000000000000F76A5E
:100140004E0FF66E010EF7220900F5501200050160
:100150000902A1010901A1000509190129031500DE
:100160002501950375018102950175058101050140
:100170000930093109381581257F750895038106F5
:10018000C0C0F76A920FF66E010EF7220900F55013
:1001900012000000F76AA40FF66E010EF7220900A4
:1001A000F55012003400F76AB60FF66E010EF72212
:1001B0000900F550120009022200010100C03209B5
:1001C00004000001030102000921000100012234A2
:1001D000000705810308000AF76AE80FF66E010EB2
:1001E000F7220900F55012000100F76AFA0FF66EC7
:1001F000010EF7220900F550120012011001000053
:10020000004061042200000101020001F76A1C0F96
:10021000F66E020EF7220900F550120000040C00E1
:10022000F76A300FF66E020EF7220900F550120041
:100230000403090408034300430053001C03430064
:1002400043005300200055005300420020004D00A1
:100250006F00750073006500F2CF0EF0F29EF76A32
:10026000720FF66E020EF7220900F5500EBEF28EE6
:100270001200000103040404030100FFFDFCFCFC68
:10028000FDFF6D92699468944EEF06F06A6A689279
:1002900057EF06F03E6A3E520AE1036A3E50240FD1
:1002A000E96E000E0320EA6EEF6A3E2AF4D71A6A5E
:1002B000010E1B6E196A000C010E476E47500F08A5
:1002C0000EE3700E4724016E0F0E036ED8B0032AA2
:1002D00001C0E9FF03C0EAFFEF6A472AEFD71E6AB1
:1002E0001D6A000C400E0401016F050E036F026BC6
:1002F000880E006F046B050E076F400E066F00013D
:10030000000C6A6A686A9F0E6B6E390E696E6E6ABF
:10031000C1DFD2DF160E706E68A602D06896FCD7D9
:100320006D98E0DF030E1F6E5DEF06F0698468983C
:100330006D8263EF06F0689C69EF06F070A002D052
:10034000D1DF7090689A6FEF06F042C020F0000C89
:10035000FF0E206E000C406A23523EE040503F08E2
:100360003BE31C50FC0F2BE2040FF6EF01F0036A95
:100370002250F2CF42F0F29E16DF42BEF28E416E64
:100380001ED0036A2250F2CF42F0F29ED8DE42BE67
:10039000F28E416E14D0036A2250F2CF42F0F29EE8
:1003A0003FDF42BEF28E416E0AD0036A2250F2CF86
:1003B00042F0F29E1ADF42BEF28E416E00D0222A37
:1003C00023064050402A036A400FE96E050E0320C1
:1003D000EA6E41C0EFFFC0D7235204E1405040080D
:1003E00001E0196A40C042F0B0DF000CE824F76A6F
:1003F000F736070FF66E040EF7220A00F550FA6E74
:100400000800F550F96E6E0382039603AA03226A70
:100410001C6A05010351010A000109E0030A0CE00E
:10042000010A0DE0220A22E0030A32E058D0120E3F
:10043000236E030E1C6E55D0220E236E52D0020E78
:100440001C6E036A05010251F2CF40F0F29E0001DA
:10045000DDDE40BEF28E226E036A2250F2CF40F003
:10046000F29EDEDE40BEF28E236E3BD0120E226E76
:10047000223C01D00BD0036A2250F2CF40F0F29E12
:1004800092DE40BEF28E236E2CD002D061DF35D0DA
:10049000D89005010435036AF2CF40F0F29E0001C6
:1004A00070DE0900F5CF03F040BEF28E226E223CD2
:1004B00001D013D0010E1C6ED89005010435036ADB
:1004C000F2CF40F0F29E000165DE0900F5CF03F0A7
:1004D00040BEF28E236E05D002D03ADF0ED038DF58
:1004E0000CD00501075305E12350065D02E206C565
:1004F00023F0010E196E00012EDF000C3F5204E1C3
:10050000040E1F6ED9DEC1D0050E1F6E426E800E26
:10051000416E010E406E40500F08D8A0B6D0436A1D
:10052000036A4050F2CF47F0F29EC9DD47BEF28E1B
:10053000000A51E0040E436ED8904034036AF2CFB3
:1005400047F0F29EE4DD0900F5CF03F047BEF28EDE
:10055000446E03C045F04050080DF350010F016E8A
:10056000040E036ED8B0032A01C0E9FF03C0EAFFFE
:1005700044C0EFFF4050080DF350020F016E040E0F
:10058000036ED8B0032A01C0E9FF03C0EAFF42C0EE
:10059000ECFFED5241C0EFFFD8904034036AF2CF38
:1005A00047F0F29EB4DD0900F5CF03F047BEF28EAE
:1005B000412603504222880E466E45B0468045B221
:1005C00046824050080DF3CF01F0040E01C0E9FF50
:1005D000EA6E46C0EFFF036A4050F2CF47F0F29E4A
:1005E0005EDD47BEF28E000A31E043824050080DC6
:1005F000F350060F016E040E036ED8B0032A01C03B
:10060000E9FF03C0EAFF42C0ECFFED5241C0EFFF3B
:10061000D8904034036AF2CF47F0F29E60DD0900C3
:10062000F5CF03F047BEF28E4126035042224050E0
:10063000080DF350040F016E040E036ED8B0032AA8
:1006400001C0E9FF03C0EAFF400EEF6E4350060809
:1006500002E10E0E436E036A4050F2CF47F0F29E65
:100660001EDD47BEF28E020801E04388700E402472
:10067000016E0F0E036ED8B0032A01C0E9FF03C05C
:10068000EAFF43C0EFFF402A46D791EF03F0050190
:10069000015100010DE0010A14E0020A1EE0060A01
:1006A00027E0030A2CE00E0A2CE0010A30E03DD0DE
:1006B0001BC040F50501416B020E426E000145DE94
:1006C00036D00501022D06D0010E1B16426A00012C
:1006D0003CDE02D000013CDE2AD00501022D05D00F
:1006E0001B82426A000131DE02D0000131DE1FD0E0
:1006F000020E196E02C521F0426A27DE18D087DE8D
:1007000016D01AC040F5010E426E1FDE10D0050152
:100710000251010808E302C51AF002C53FF00001CA
:10072000EDD6426A12DE000102D012DE00D0C7EF21
:1007300004F01AC03FF005010151000107E00A0A68
:100740000DE0010A2DE00D0A3DE03ED00501406BB1
:10075000416B020E426E0001F8DD38D03F521EE0C0
:10076000010E3F5C036AF2CF40F0F29E35DD40BEE1
:10077000F28E016E0501045DD8A002D000010ED0FA
:10078000036A0451240FE96E000E0320EA6EEFCFD6
:1007900040F5010E426E0001D8DD01D0D9DD16D042
:1007A0003F520EE0036A05010451240FE96E000E6A
:1007B0000320EA6E02C5EFFF426A0001C6DD01D0E8
:1007C000C7DD04D024DE02D0C3DD00D0C7EF04F0C3
:1007D00040903FBE40803F9E40A010D0036A3F50F3
:1007E000F2CF41F0F29E5BDC41BEF28E000A02E1E4
:1007F000000E01D0010E016E10D00FD0036A3F50E1
:10080000F2CF41F0F29E5BDC41BEF28E000A02E1C3
:10081000000E01D0010E016E00D07FEF04F0409079
:100820003FBE40803F9E40A010D03F50080DF35087
:10083000040F016E040E036ED8B0032A01C0E9FF55
:1008400003C0EAFF880EEF6E09D03F50080DF3CFCA
:1008500001F0040E01C0E9FFEA6EEF6A8EEF04F0CA
:1008600040903FBE40803F9E40A010D03F50080DBA
:10087000F350040F016E040E036ED8B0032A01C0BA
:10088000E9FF03C0EAFF840EEF6E0AD03F50080D67
:10089000F3CF01F0040E01C0E9FFEA6E840EEF6EA3
:1008A00094EF04F040903FBE40803F9E40A010D0A7
:1008B0003F50080DF350040F016E040E036ED8B0C4
:1008C000032A01C0E9FF03C0EAFFEFCF41F00AD0DD
:1008D0003F50080DF3CF01F0040E01C0E9FFEA6EAE
:1008E000EFCF41F041AE02D041B402D0000E01D0B2
:1008F000010E016E9EEF04F004C53FF069D701526E
:1009000029E005010151010A000105E0020A09E0A0
:10091000030A0DE01DD004C53FF081D7426A15DD02
:1009200019D004C53FF09CD7426A0FDD13D00501F2
:10093000406B416B04C53FF00001B4D7015204E0A5
:10094000010E0501406F0001020E426EFEDC02D076
:10095000FFDC00D0C7EF04F00501015100D0000119
:10096000F7DC00D0C7EF04F0196A050100517F0BD6
:10097000000107E0010A06E0030A05E0230A04E09B
:1009800004D085D6D6D6B8D7E7D7E2DC00D0EEEFD4
:1009900005F03F50080DF3CF01F0040E01C0E9FF50
:1009A000EA6EEFCF41F04050020806E141AC02D0C0
:1009B000406A02D0010E406E4050030812E1840EDE
:1009C000416E3F50080DF350040F016E040E036E8C
:1009D000D8B0032A01C0E9FF03C0EAFF840EEF6E1E
:1009E00009D0402C03D0C80E416E04D0405202E121
:1009F000880E416E036A010E026E3F50006E05E0E4
:100A0000D89002360336002EFBD70250FF0A006E44
:100A1000FF0E031A00501D1603501E16D8903F34C7
:100A2000036AF2CF44F0F29E87EC00F00900F5CFA4
:100A300003F044BEF28E426E03C043F03F50080DF7
:100A4000F350010F016E040E036ED8B0032A01C0EB
:100A5000E9FF03C0EAFF42C0EFFF43B0418043B269
:100A600041823F50080DF3CF01F0040E01C0E9FFB1
:100A7000EA6E41C0EFFF000C3F50080DF350040F29
:100A8000016E040E036ED8B0032A01C0E9FF03C053
:100A9000EAFFEFCF43F043BE5BD03F50080DF35069
:100AA000050F016E040E036ED8B0032A01C0E9FFE2
:100AB00003C0EAFF40C0EFFF4250020816E13F507A
:100AC000080DF350040F016E040E036ED8B0032A14
:100AD00001C0E9FF03C0EAFFEFCF43F043AC02D00F
:100AE000426A02D0010E426E13D04250040810E157
:100AF0003F50080DF3CF01F0040E01C0E9FFEA6E8C
:100B0000EFCF43F043AC03D0010E426E01D0426AF6
:100B1000422C03D0C80E436E04D0425202E1880E2C
:100B2000436E41B0438041B243823F50080DF350C1
:100B3000040F016E040E036ED8B0032A01C0E9FF52
:100B400003C0EAFF43C0EFFF010E016E03D000D0E7
:100B5000000E016E000C3F5203E172EC01F00FD069
:100B6000036A010E026E3F50006E05E0D890023617
:100B70000336002EFBD702501D1203501E12000C2C
:100B800040C06EFF405203E0040E1F6E02D0020E02
:100B90001F6ED0EF05F01A6A196A21C040F0F0D735
:100BA000DDEF05F03F5209E1192C03D0ABEC01F069
:100BB00004D01950020801E1EED7000C6C303E6EF3
:100BC0003E323E321F0E3E166C523BE10401005194
:100BD0003C0B34081BE1046B0001C6D6203C05D059
:100BE0003F6A030E406ED5DE0ED03F6A020E406EA5
:100BF000D0DE2050FE0807E03F6A416A20C040F086
:100C0000040E426E39DF6D9819D0040100513C0B7F
:100C1000040815E13F6A00019EDF3F6A020E406E44
:100C2000B8DE2050FE080AE0203C01D007D03F6A21
:100C3000416A20C040F0010E426E1EDF040120D048
:100C400000016C50040812E1FF0E206E3F6AAADF1B
:100C5000203C01D008D03F6A416A20C040F0020E1B
:100C6000426E0ADF02D072EC01F009D06CB404D0FD
:100C70003EC03FF070DF03D03EC03FF093DF040181
:100C8000000174EF06F01F5201E12FD068522DE0F1
:100C900068A404D069A402D041EF01F06DA201D094
:100CA00024D068A204D069A202D046EF01F068A067
:100CB00004D069A002D081EF01F068A804D069A82F
:100CC00002D096EF01F068AC04D069AC02D09BEF83
:100CD00001F068AA04D069AA02D09EEF01F068A6CC
:100CE00004D069A602D06AD76896A19A2CEF00F0CA
:100CF0006D6A696A080E6F6E94503009946E1F6AAF
:100D0000186AF2BE188EF29E4AEC01F018BEF28EFE
:100D10001E6A1D6A30EF07F0186AF2BE188EF29E46
:100D20004AEC01F018BEF28E6D6A140E6F6E696A9D
:100D30006D86010E1F6EA0EF06F06DB601D0ECD7E8
:100D40001F2C0BD06DBA09D0686A696AA08AC00EE0
:100D5000F212110E696E020E1F6E31EF07F02C5069
:100D6000080DF350040F016E040E036ED8B0032A71
:100D700001C0E9FF03C0EAFFEFCF34F034BE45D035
:100D80002C50080DF350060F016E040E036ED8B000
:100D9000032A01C0E9FF03C0EAFFECCF03F0ED52E4
:100DA000EFCF35F003C036F0336A326A3350305C2F
:100DB0001AE303E12F50325C16E22DC0E9FF2EC08A
:100DC000EAFFEFCF39F036C0EAFF35C0E9FF39C09E
:100DD000EFFF352AD8B4362A2D2AD8B42E2A322A43
:100DE000D8B4332AE3D7186AF2BE188EF29E2CC00C
:100DF0003FF030C041F02FC040F031C042F03CDE47
:100E000018BEF28E015003D000D0000E016E54EFD8
:100E100007F0EA6A2C0EE96EEF500EE00F0E016E3D
:100E2000006A002EFED7012EFBD78F0E006E002E1B
:100E3000FED70000EF2EF2D768EF07F0F86AD09ED9
:100E4000088EEA6AE96AC150C00B0F09C16E070E2D
:100E5000B46E1F6A236A296A2A6A040E2B6E48D769
:100E60006CD71A5235E0256A036A2A50F2CF2CF06B
:100E7000F29E2CEC01F02CBEF28E266E036A2B50F3
:100E8000F2CF2CF0F29E2CEC01F02CBEF28E276EED
:100E9000286A010E2C6E2E6A250E2D6E306A040E05
:100EA0002F6E020E316E5BD7015201E0292A2950C4
:100EB0000A080BE22A2A2A500F08D8A02A6A2B2AED
:100EC0002B500F08D8A02B6A296A0A0E2C6EA1D7C6
:040ED000C7D703007D
:020000040030CA
:0E000000240E3E1E008381000FC00FE00F4053
:00000001FF
;PIC18F2550
;CRC=A06D CREATED="15-Nov-09 11:02"

Saturday, November 7, 2009

Scrolling Message Display on a DMM

Recently, I came across this Python package for GPIB interfacing. It's called PyVISA, and it's relatively easy to use even if you don't have backgrounds on Python programming language. As part of my experiments on Python PC interfacing, I managed to borrow an equiptment having a GPIB port.The Agilent (HP)34410A Digital Multimeter (DMM), it's one of the commonly used equipments in our workplace. While reading the 'remote programming' manual of this DMM, I found out that it is capable of displaying text (e.g. alphanumerics) on its front panel display. The GPIB command is fairly simple, just send DISPlay:TEXT + the qouted message. (e.g. DISP:TEXT "hello" ). The message to be displayed is up to 12 characters long.


the PyVISA python script for scrolling message:
 import visa, time  

hp = visa.Instrument('GPIB::2')

def display(msg):
hp.write('DISP:TEXT ' + '"' + msg + '"')

message = ' scrolling message display on Agilent HP34410A using Python PyVISA. by yus Electronicslab.ph'

for count in range(100):
for i in range( len(message)):
#display(message[i:(i+12)])
display(message[i:(i+12)].upper())
time.sleep(0.3)


demo:
video

forum link: GPIB (General Purpose Interface Bus, IEEE-488)

Monday, November 2, 2009

PySerial DTR and RTS Manipulation

Another application using (Python) PyQt and PySerial: a simple serial port LED blinker program.

two LEDs connected to DTR and RTS of a COM port (pins 4 and 7 of DB9):

simple python py script:
 import sys, serial  
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyForm(QDialog):
def __init__(self, parent = None):
super(MyForm, self).__init__(parent)
self.setWindowTitle('PySerial DTR and RTS Manipulation')
self.setMinimumSize(300, 100)
# widgets
DTRlabel, RTSlabel = QLabel(), QLabel()
self.DTRbutton = QPushButton('set to Logic "True"')
self.RTSbutton = QPushButton('set to Logic "True"')
self.DTRcheckbox = QCheckBox('continuous toggle')
self.RTScheckbox = QCheckBox('continuous toggle')
# layout
layout = QGridLayout()
layout.addWidget(DTRlabel, 0, 0)
layout.addWidget(RTSlabel, 0, 1)
layout.addWidget(self.DTRbutton, 1, 0)
layout.addWidget(self.RTSbutton, 1, 1)
layout.addWidget(self.DTRcheckbox, 2, 0)
layout.addWidget(self.RTScheckbox, 2, 1)
self.setLayout(layout)
# serial port
self.port = serial.Serial('COM1')
DTRlabel.setText("<font size = 5 color = darkred><b> " +self.port.name + " DTR pin:</b></font>")
RTSlabel.setText("<font size = 5 color = darkred><b> " +self.port.name + " RTS pin:</b></font>")
self.DTRlogic, self.RTSlogic = False, False
self.port.setDTR(self.DTRlogic)
self.port.setRTS(self.RTSlogic)
# events
self.connect(self.DTRbutton, SIGNAL('clicked()'), self.toggleDTR)
self.connect(self.RTSbutton, SIGNAL('clicked()'), self.toggleRTS)
self.DTRtimer , self.RTStimer = QTimer(), QTimer()
self.connect(self.DTRtimer, SIGNAL('timeout()'), self.eventDTRtimer)
self.DTRtimer.start(250) # in milliseconds
self.connect(self.RTStimer, SIGNAL('timeout()'), self.eventRTStimer)
self.RTStimer.start(100) # in milliseconds

def toggleDTR(self):
self.DTRbutton.setText('set to Logic "' + str(self.DTRlogic) + '"')
self.DTRlogic = not self.DTRlogic # invert logic
self.port.setDTR(self.DTRlogic)
def toggleRTS(self):
self.RTSbutton.setText('set to Logic "' + str(self.RTSlogic) + '"')
self.RTSlogic = not self.RTSlogic # invert logic
self.port.setRTS(self.RTSlogic)
def eventDTRtimer(self):
if self.DTRcheckbox.isChecked():
self.toggleDTR()
def eventRTStimer(self):
if self.RTScheckbox.isChecked():
self.toggleRTS()

if __name__ == '__main__':
app = QApplication(sys.argv)
form = MyForm()
form.show()
sys.exit(app.exec_())


demo:
video
*the 'blink' rate depends on QTimer timeout period

forum link: serial port LED blinker