PDA

View Full Version : USB, PIC18F2550 and VB



Tissy
- 26th November 2005, 20:25
I think i have 75% of my code working except for the following:

The main purpose of the PIC is to look for button pushes on the PIC inputs and perform a specific task depending on which buttons are pushed. However, when a VB application is loaded, any of the variables which are set in the VB program and sent to the PIC via USB are then used by the PIC for timing functions.

Its basically a programmable timer, where the VB program is being used to set the timing variables.

However, the PIC code at the moment is ignoring the button inputs until you send the data from VB to the PIC.

So, push a button, nothing happens. Keep a button held AND send data from VB to the PIC and it recognises the button push. Push button again on its own and nothing happens, until of course you hold the button down AND send data again.

Can anyone figure out whats going wrong by looking at this code.



DEFINE OSC 20
DEFINE LOADER_USED 1


' ---------- [ I/O Definition ] ----------
TRISA = %11111111 ' Set PORTA to all input
TRISB = %10000001 ' Set PORTB (0)INPUT (1-5)OUTPUTS
TRISC = %00000111 ' Set PORTC (0-2 input) rest Outputs
PORTB = 0


' ----- [ Variable Definitions ] ----------
Loop Var Byte
MaskSwitch Var Byte
DelayOut Var Byte
Seconds Var byte ' 0-59
SecondsDelay Var byte
Minutes Var byte ' 0-59
MinutesDelay Var byte
Hours Var byte ' 0-23
HoursDelay Var byte
SecondsDelayOut Var Byte
MinutesDelayOut Var Byte
HoursDelayOut Var Byte


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

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


' ----- [ Variable Constants ] ----------
HoursDelay = 0
MinutesDelay = 2 '1 To 60
SecondsDelay = 0 '1 To 60


' ---------- [ System Inputs ] ----------
SW1 Var PORTC.0
SW2 Var PORTC.1


' ---------- [ System Outputs ] ----------
Red VAR PORTB.1 ' All LEDs connected
' between RC pins and
' ground via resistor

' ************************************************** **********
' * Main Program Section *
' * 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...

Main:
Gosub DoUSBIN
Gosub DoUSBoUT

MaskSwitch=PORTC & $07
Select Case MaskSwitch
Case 1 '%00000001
If SW1=1 Then Gosub Procedure_SW1
If SW1=0 THEN
EndIf

Case 2 '%00000010
If SW2=1 Then Gosub Procedure_SW2
If SW2=0 THEN
EndIf

Case Else
Goto Main
End Select
Goto Main


' ************************************************** **********
' * 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


Procedure_SW1:
'Do Something
Return


Procedure_SW2:
' Do Something Else
Return


I'm guessing once you Gosub DoUSBIn this keeps looping until some data is received. Is there a way to set it so that if no data is exchanged, it comes out of the loop. ie perform primary function, but always look at USB for any possible data, if none continue with primary function. As the need to send data from VB to the PIC is minimal. ie once the timing variables are sent, the need to change them from time to time is minimal. If i comment out the Gosub DoUSBIn line, the primary function of the PIC works fine.

Many thanks.

Tissy
- 27th November 2005, 13:28
I have found that if you put the Gosub DoUSBin routine at the beginning of the code (ie before the Main: routine) then the PIC waits for data transfer and when you send the variables from VB, then it continues with the PICs primary function and uses the variables you sent correctly. This is fine if it is a one of function when you power up the PIC. However, it is not, the PIC will always be powered-up.

So, if you want to change the variables, then you need to reset the PIC and resend them again using USB.

I want to get away from using a button for 'programming mode', so in otherwords it doesn't matter at what stage you send the variables from VB without there being a need for user intervention on the PIC side.

I need to get it out of the loop !!

Steve

Bruce
- 27th November 2005, 15:40
Have you tried something like incrementing a variable in the DoUSBin loop, and exiting once it reaches a certain value?

DoUSBIn:
USBBufferCount = USBBufferSizeRX ' RX buffer size
USBService ' keep connection alive
X = X + 1
PAUSEUS 5000 ' 5mS delay
IF X > ExitVal THEN JumpOut
USBIn 1, USBBuffer, USBBufferCount, DoUSBIn ' read data, if available
JumpOut:
Return

Tissy
- 27th November 2005, 17:29
Thank you so much Bruce, that has been driving me mad for weeks on end. I've been working alot on the other code and kinda working around this, but it works very well indeed now. You're right, it now exits from the loop and back to the main routine. You're a genius !!

Cheers again.

Steve

Tissy
- 27th November 2005, 18:37
Having now got that piece of code working it has presented this:

If you remove power to the PIC and then reconnect, it of course first looks for the USB and data as per the Gosub DoUSBin etc. As at this stage the USB databuffers are empty, ie no data being sent, it stores the EEPROM variables as 0, instead of retaining the previously stored numbers.

I have come up with this, what i think, long winded solution.

Where by the top three lines of code read:


Main:
Gosub DoUSBIN
Gosub CheckData
Gosub DoUSBoUT

And then


CheckData:
If USBBuffer[9] = 0 Then
Read 1, SecondsDelayOut ' read previously stored
Read 3, MinutesDelayOut ' variables from EEPROM
Read 5, HoursDelayOut ' before they are blanked
SecondsDelayOut = SecondsDelay
MinutesDelayOut = MinutesDelay
HoursDelayOut = HoursDelay
Return
Else
SecondsDelay = USBBuffer[11]
MinutesDelay = USBBuffer[13]
HoursDelay = USBBuffer[15]

Write 1, SecondsDelay
Write 3, MinutesDelay
Write 5, Hoursdelay
EndIf
Return

Obvioulsy in VB when i write the data again, i set BufferOut(10) = 1 to write the new variables.

Is this the easiest way?