View Full Version : Detecting if USB unplugged

15th March 2016, 16:14
What is the best way to detect if the USB cable has been unplugged please?

I am using an interrupt to keep the HID connection alive and the power for the PIC is not from the USB lead.

15th March 2016, 20:35
OK, a bit more information.

The PC side is written in Delphi which has Notify_Plugged and Notify_Unplugged and I am looking simmilar in Proton.

The PIC has it's own supply and is not allways connected via USB. I could use a pin to detect the supply on the USB plug but I would prefer a more elegant solution.

It's probably in there somewhere but as yet I have not discovered it.

15th March 2016, 20:47
I have not played with USB for a while but surely this looks like it will do what you want?

From the manual.
Poll the USB interface in order to keep it attached to the bus.
If the commands USBin or USBout are not used within a program loop, the interface will drop
off the bus, therefore issue the USBpoll command to stop this happening. This command
should be issued at least every 10ms if using a HID interface and at least once every 5ms for a
CDC interface.
Upon exiting the USBpoll command, the state of the bus can be checked via the USB variable
__USB_bDeviceState. This variable resides in a higher RAM bank of the PICmicro™ (as do all
of the USB variables), which means that bank switching will take place whenever it is accessed.
For this reason, the USBpoll subroutine loads this variable into a variable within Access RAM.
The variable it uses is named USB_bStatus.
Several states are declared within the USB_Dev.Inc file located within the compiler’s Includes
folder. These are: -

16th March 2016, 09:10
Thanks, yes, I saw that already.
This morning I have more time to play so from line numbers 87 & 89 of the USB_Dev.inc as a test I tried

If USB_bDeviceState = cDETACHED_STATE Then
Print at 2,1," USB Unplugged "
While 1 = 1 : Wend

it compiles without error but when I remove the USB lead it does not work so my search goes on.

16th March 2016, 09:22
I'm not sure if the USB code would like it but you can detect if the USB plug is connected (but not if it is enumerating) by putting a high value pullup on D+(I think) then look to see if its pulled down by the PC.

I use it to detect on power up if the power is coming via a USB + data connection or is its just USB +5v.

Another method is to send a packet periodically to the PC and have an ACK or something in your PC code to say if got it.

16th March 2016, 10:14
I could use a pin to detect the supply on the USB plug but I would prefer a more elegant solution
Unless you have a pic with a USB OTG module like a pic24/33, that's the proper way to do it.

If you're self-powered you shouldn't even enable the usb module if you're not connected. According to the USB spec you're not allowed to drive any voltage on the D+/D- lines unless there's power on VBUS so you shouldn't enable the D+ pullup until you verify that.

If you look in the various usb .inc files you'll see definitions like

'$define cUSE_SELF_POWER ' Self powered?


You should define and use those.

16th March 2016, 12:33
OK, thanks for the information. The device is currently a 18F4455 so I think I will go for the pin detect as it is much easier to implement and potentially fewer problems.

USBpoll in the interrupt is happily keeping the USB link alive after the link is established or even if I plug or unplug the lead afterwards.

What I still have not figured out is why :-

USB_tConnected = 0
USB_tConfigured = 1
USB_bDeviceState = 32
USB_bStatus = 32

stay the same.

16th March 2016, 13:04
I haven't traced through all the code, but USBPoll uses the USB_DeviceTasks routine and if you don't set those BUS_SENSE definitions then it looks like it skips checking some of the possible event changes. The only way it sees it's detached is through the bus sense.