PDA

View Full Version : i cant get 18f2550 work as HID



Ahmadabuomar
- 6th October 2009, 13:43
Hi every body

i m trying to blink some leds with pic 18f2550 using usb connection to my labtop

i have some problems

1- when i open vb2008 interface, it doesnt identify that usb is plugged untill i touch Vusb with my hand. i aready put 200nf capacitor to ground on Vusb. i is very strange.

2- when i send data to pic, i doesnt blink the leds. i revised vb code many times. and i revised my controller code also. i just cant find what is wrong.

plz help me. it driven me crazy. espicially when it needs my to provide a path to ground with my body on Vusb!!! :)

pic code


DEFINE OSC 48

USBBufferSizeMax con 8 ' maximum buffer size
USBBufferSizeTX con 8 ' input
USBBufferSizeRX con 8 ' output

' the USB buffer...
USBBuffer Var Byte[USBBufferSizeMax]
USBBufferCount Var Byte

' ************************************************** **********
' * main program loop - remember, you must keep the USB *
' * connection alive with a call to USBService every couple *
' * of milliseconds or so... *
' ************************************************** **********
usbinit ' initialise USB...
ProgramStart:
USBBUFFER[0] = 0
USBBUFFER[1] = "P"
USBBUFFER[2] = "="
USBBUFFER[3] = 15
USBBUFFER[4] = "T"
gosub DoUSBOut
gosub DoUSBIn

portb = usbbuffer[3]


goto ProgramStart

' ************************************************** **********
' * receive data from the USB bus *
' ************************************************** **********
DoUSBIn:
USBBufferCount = USBBufferSizeRX ' RX buffer size
USBService ' keep connection alive
USBIn 1, USBBuffer, USBBufferCount, DoUSBIn ' read data, if available
return

' ************************************************** **********
' * wait for USB interface to attach *
' ************************************************** **********
DoUSBOut:
USBBufferCount = USBBufferSizeTX ' TX buffer size
USBService ' keep connection alive
USBOut 1, USBBuffer, USBBufferCount, DoUSBOut ' if bus available, transmit data
return

vb code

Public Class frmUSB
' vendor and product IDs
Private Const VendorID As Short = 4660 'Replace with your device's
Private Const ProductID As Short = 1 'product and vendor IDs

' read and write buffers
Private Const BufferInSize As Short = 8 'Size of the data buffer coming IN to the PC
Private Const BufferOutSize As Short = 8 'Size of the data buffer going OUT from the PC
Dim BufferIn(BufferInSize) As Byte 'Received data will be stored here - the first byte in the array is unused
Dim BufferOut(BufferOutSize) As Byte 'Transmitted data is stored here - the first item in the array must be 0

' ************************************************** **************
' when the form loads, connect to the HID controller - pass
' the form window handle so that you can receive notification
' events...
'************************************************* ****************
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' do not remove!
ConnectToHID(Me)
Label2.Text = "Connected to HID"
End Sub

'************************************************* ****************
' disconnect from the HID controller...
'************************************************* ****************
Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
DisconnectFromHID()
End Sub

'************************************************* ****************
' a HID device has been plugged in...
'************************************************* ****************
Public Sub OnPlugged(ByVal pHandle As Integer)
If hidGetVendorID(pHandle) = VendorID And hidGetProductID(pHandle) = ProductID Then
' ** YOUR CODE HERE **
Label2.Text = " USB plugged"

End If
End Sub

'************************************************* ****************
' a HID device has been unplugged...
'************************************************* ****************
Public Sub OnUnplugged(ByVal pHandle As Integer)
If hidGetVendorID(pHandle) = VendorID And hidGetProductID(pHandle) = ProductID Then
hidSetReadNotify(hidGetHandle(VendorID, ProductID), False)
' ** YOUR CODE HERE **
Label2.Text = "USB unplugged"

End If
End Sub

'************************************************* ****************
' controller changed notification - called
' after ALL HID devices are plugged or unplugged
'************************************************* ****************
Public Sub OnChanged()
' get the handle of the device we are interested in, then set
' its read notify flag to true - this ensures you get a read
' notification message when there is some data to read...
Dim pHandle As Integer
pHandle = hidGetHandle(VendorID, ProductID)
hidSetReadNotify(hidGetHandle(VendorID, ProductID), True)
End Sub

'************************************************* ****************
' on read event...
'************************************************* ****************
Public Sub OnRead(ByVal pHandle As Integer)
' read the data (don't forget, pass the whole array)...
If hidRead(pHandle, BufferIn(0)) Then
' ** YOUR CODE HERE **
TextBox2.Text = Str$(BufferIn(3))
Label2.Text = "Data recieved"
' first byte is the report ID, e.g. BufferIn(0)
' the other bytes are the data from the microcontroller...
End If
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
End

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BufferOut(0) = 0 'first byte is always the report ID
BufferOut(1) = Asc("P") 'first data item
BufferOut(2) = Asc("=") 'second data item
BufferOut(3) = Val(TextBox1.Text) 'third data item to be send ober usb
BufferOut(4) = Asc("T") 'fourth data item
'write the data, dont forget to send the whole array
hidWriteEx(VendorID, ProductID, BufferOut(0))
hidWriteEx(VendorID, ProductID, BufferOut(1))
Label2.Text = "Data sent"

End Sub
End Class

Darrel Taylor
- 6th October 2009, 23:46
Have you ENABLED the USB voltage regulator in the Configs?

_VREGEN_ON_2L
<br>

Ahmadabuomar
- 7th October 2009, 12:43
hi

yeah i did activated internal voltage regulator. he is a pic for fuse configuration in my programmer. it shows what i used

Ahmadabuomar
- 8th October 2009, 19:59
please help me

pedja089
- 8th October 2009, 20:11
You yust should set USBPPL and PPLDIV to 48MHz, or divide by 12 if you use 48MHz resonator.
I think that code is good.

Darrel Taylor
- 8th October 2009, 22:05
Ahmadabuomar,

Another possible problem ...

According to your picture ...
Low Voltage Programming (LVP) is Enabled.
You could put a pull-down resistor on RB5/PGM, but you probably want to disable it completely since you are using the full PORTB in your program.

And pedja089, you can't use a 48Mhz resonator with the 4550's.
Maximum frequency using the main oscillator is 25Mhz.
You can use an external TTL (canned) 48Mhz oscillator with EC mode.
<br>

pedja089
- 9th October 2009, 10:13
I know that. But look to top line of his pic code.

Darrel Taylor
- 9th October 2009, 10:32
The top line says DEFINE OSC 48

Which seems correct from the image of the configs which shows an 8Mhz crystal with HS_PLL that gives 96Mhz.

The USBPLL is /2 so the USB gets 48Mhz, and the CPUDIV is also /2 so it's running at 48Mhz.

Except for the LVP, it all seems good.

Well, might want to disable XINST too.
<br>

Ahmadabuomar
- 10th October 2009, 02:11
thx for ur reply

i ll try to disable lvp and xinst and see what happen

brb

Ahmadabuomar
- 10th October 2009, 02:28
OMG, it worked

thaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaank you Darrel for taking time to read the code and reply me. thank u very much

and thx pedja for trying to help.

Darrel, why LVP is so important in this case?

i thought LVP stands for low voltage programming. and since i used k128 usb programmer i thought lvp must be enabled ( i read once that k128 uses low voltage programming for usb compatible pics).

Darrel Taylor
- 10th October 2009, 05:29
Great News! And you're welcome.

I'm not familiar with the K128 ...
But with a quick look at the schematic in the datasheet (http://kitsrus.com/pdf/k128.pdf), it seems to use a series of diodes and capacitors to increase the voltage and applies it to VPP.

They have several different programmers.
The LVP comment might have been directed at a different product.

But when LVP is enabled ... anytime RB5/PGM goes HIGH ... it's just like taking MCLR/VPP to 13V.
If it's left floating, the PIC could be constantly entering Program Mode from input noise.
<br>

Ahmadabuomar
- 10th October 2009, 16:05
Great News! And you're welcome.


But when LVP is enabled ... anytime RB5/PGM goes HIGH ... it's just like taking MCLR/VPP to 13V.
If it's left floating, the PIC could be constantly entering Program Mode from input noise.
<br>

well, thats something new to learn. thx Darrel

i m now trying to control a robtic arm using USB communication. i m reading about intruppts. i ll report my work in this thread.

Ahmadabuomar
- 11th October 2009, 18:35
hi

i need to know more about interrupts. when using usb communication i have to excute usbservice every milisecond or so. should interrupts help me ?

Darrel Taylor
- 11th October 2009, 18:47
... i have to excute usbservice every milisecond or so. should interrupts help me ?
They will indeed.

Here's an include file that can do all the servicing for you in the background using the USB interrupts.
And it adds a few handy features ...

USB_ASM_Service.pbp
http://www.picbasic.co.uk/forum/showpost.php?p=78306&postcount=6

HTH,

Ahmadabuomar
- 11th October 2009, 22:48
hi Darrel

thx alot for ur help. this code was very important to me.

my problem now is that i want to control a robotic arm after i made my pc talk to my pic. the problem is that servo control in pic basic is carried by pulsout , and i should pause for 18 milisecond to complet a period.

pulsout portb.0, period
pause 18
...
etc

it seems that is a wrong way to do it since usbservice must be called every 1ms or so. i tried this method and it didnt work. i also tried to make a for loop like this
for vr = 1 to 18
pause 1
usbservice
next vr

but it didnt work. is there a way to control a servo motor by a slider on my vb software? and how can i avoid pausing in pulsout ?

Ahmadabuomar
- 12th October 2009, 16:13
hi Darrel,

i found a good code for controlling 8 servo motors and i tried it.

its very awsome and it contains a pc sofware too.

unfortunatily, it is written in mokrobasic and it contains some assembly codes.

since i m new to pic microcontrollers and i use only PBP, i didnt understand the code and its procedure.

i wish i can understand it so i can make my own code using PBP and microcode studio. and also to programm my own vb software.

could u explain this code and how it define 20ms periods.. etc.

u can find attached the full folder containing pc software and also pic firmware.

here is the code:


program SERVO8_USB_18F2550
'************************************************* *****************************************
'* 18F2550 PIC USB_HID 50Hz PWM SERVO CONTROLLER *
'* by W. Schroeder alias "xor" -- July 4, 2006 *
'* *
'* Compiles with mikroBASIC 4.03 and tested on the EasyPIC3 Development Board *
'* Uses mikroBASIC USB_HID Library and must include "USBdsc.pbas" and "HIDconstant.pbas" *
'* *
'* Also required is the free Visual Basic Servo Controller Demo program included with *
'* this file. This program has been tested on Windows XP with USB2.0. *
'* * *
'* Configuration settings for the 18F2550 are the same as the mikroBASIC 18F2550 HID *
'* example found in the mikroBASIC Examples folder in the mikroBASIC directory. *
'* These configurations are set up for an 8MHz crystal oscillator and through internal *
'* PLL settings this is increased to 48MHz. This also produces a very fast 12 MIPS. *
'* *
'* The EasyPIC3 board provides an easy connection to the PIC via a USB port. Please *
'* refer to the board schematic for ideas for your own circuit connections. *
'* *
'* For the purposes of this demo all output pins of PORTB are utilized. *
'* Servo0 is PORTB.0, Servo1 is PORTB.1, ......, Servo7 is PORTB.7 *
'* *
'* The range of PWM on-time is 800us to 2200us analogous with a resolution of 0 to 255 *
'* A value of 127/128 is considered 50% of servo rotation with an on-time of 1500us *
'* Timer0 in 16-bit mode is used to establish an accurate 20ms (50Hz) PWM interval *
'* *
'************************************************* *****************************************
'************************************************* *****************************************

include "USBdsc" ' this module must be included in the same folder as the main program

dim T0 as word absolute $FD6
dim old as byte
dim servoport as ^byte
dim _s0,_s1,_s2,_s3,_s4,_s5,_s6,_s7 as byte
dim
wrbuf as byte[2]
servo as byte[9]
wr_adr as word

sub procedure delay_810us
delay_us(810)
end sub

sub procedure interrupt
If INTCON.TMR0IF = 1 Then ' if 20ms interval
servoport^ = 255 ' turn on all servos
_s0 = servo[0] + 1 ' set up temp variables
_s1 = servo[1] + 1
_s2 = servo[2] + 1
_s3 = servo[3] + 1
_s4 = servo[4] + 1
_s5 = servo[5] + 1
_s6 = servo[6] + 1
_s7 = servo[7] + 1
old = 0
FSR0L = servoport
FSR0H = hi(servoport)
delay_810us ' this delay to hold position 0
TMR0L = 0
For old = 0 to 255 ' manage 8 outputs with 256 positions each
ASM ' very efficient PWM masking routine
movlw 0
decfsz main_global__s0, 1,0
iorlw 1
decfsz main_global__s1, 1,0
iorlw 2
decfsz main_global__s2, 1,0
iorlw 4
decfsz main_global__s3, 1,0
iorlw 8
decfsz main_global__s4, 1,0
iorlw 16
decfsz main_global__s5, 1,0
iorlw 32
decfsz main_global__s6, 1,0
iorlw 64
decfsz main_global__s7, 1,0
iorlw 128
andwf INDF0, 1,0
END ASM
While TMR0L = old ' wait until TMR0 increments
Wend
Next old ' all outputs are off at this point
T0= -3600 ' balance of time for 20ms cycle
INTCON.TMR0IF = 0 ' be ready to interrupt again for next interval
Else
HID_InterruptProc
End If
end sub

sub procedure Init_Main
INTCON2 = 0xF5
INTCON3 = 0xC0
RCON.IPEN = 0 ' disable Priority Levels on interrupts
PIE1 = 0 ' clear all interrupt enables
PIE2 = 0
PIR1 = 0
PIR2 = 0
ADCON1 = 15 ' digital IO
TRISA = 0
TRISB = 0
TRISC = 0
LATA = 0
LATB = 0
LATC = 0
end sub


sub procedure SERVO8_INIT(dim byref servo_port as byte,
dim port_config as byte)
servoport = @servo_port + 18 ' PORT TRIS ADDRESS
servoport^ = servoport^ And Not(port_config) ' SET TRIS
servoport = servoport - 9 ' PORT OUTPUT LATCH ADDRESS
T0CON = %00000101 ' prescaler = 64 or ~5us per increment
T0 = -4000 ' preset for 20ms
INTCON = %10100000 ' Timer0 Interrupt Enabled and Flag Cleared
T0CON.7 = 1 ' Timer0 On
end sub

main:
Init_Main
SERVO8_INIT(PORTB, 255)
HID_Enable(@servo, @wrbuf) ' @servo is equivalent to the Read_Buffer
Delay_mS(1000)

while true
If HID_READ <> 0 Then ' if USB package has arrived...servo positions are in Read_Buffer
wrbuf[0] = 255 ' 255 is verification value
HID_WRITE(@wrbuf, 1) ' reply to host with verification
End If
wend

HID_Disable
'** This code is necessary in order to make linker load the variables and HID_InterruptProc routine.
'** In real time it will never execute.
if false then
HID_InterruptProc
wr_adr = @DeviceDescr
wr_adr = @ConfigDescr
wr_adr = @InterfaceDescr
wr_adr = @HID_Descriptor
wr_adr = @EP1_RXDescr
wr_adr = @EP1_TXDescr
wr_adr = @HID_ReportDesc
wr_adr = @LangIDDescr
wr_adr = @ManufacturerDescr
wr_adr = @ProductDescr
wr_adr = @StrUnknownDescr
end if
end.

Darrel Taylor
- 12th October 2009, 21:30
I'm not familiar with MikroBasic.

But it appears to be using Timer1 Interrupts to generate the servo signals.

How many servos are you running?
<br>

Ahmadabuomar
- 12th October 2009, 23:48
hi Darrel,

thx for ur reply.

i m using 6 servo motors ( may be modified to be 8 ) to control the robotic arm. i read about getting 2 PWM signals from 18f2550 but it didnt help since i need more.

i m sure there is a way to do it. the main problem is the i must not use pause or pausus. i must use timers and interrupts to generate servo signals. but i didnt know how to start. the code i sent you is a good example to do it. i tried it and it works very nice. but i wish i can do it with PBP. any ideas?

Darrel Taylor
- 13th October 2009, 00:24
That might be a little more than you want to tackle at this point.

Take a look at this page ...

Robo-Ware Robotics Control Software
http://www.rentron.com/Robo-Ware.htm

With the Mini SSC II and Robo-Ware you can drive 8 servos, and the software allows you to do all kinds of different programmed motions with a PC program, or a PIC (with PicBasic Pro).

It's not USB, but it's still cool.
<br>

Ahmadabuomar
- 13th October 2009, 16:39
thank you Darrel for ur help. i ll m reading the codes now and i ll try to understand the main thoughts of controlling servos. thank you so much