PDA

View Full Version : USB Keyboard how to make shift,ctrl,win,alt keypress,?



faaktoo
- 11th March 2008, 13:22
I am attempting to implement a usb keyboard. This is a sample of project and it work. I send the letter "a" (small).
My question is how to send big letter "A" with shift press?


DEFINE OSC 48
DEFINE LOADER_USED 1

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

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

TRISD = 255


usbinit ' initialise USB...


USBbuffer[0] = 0
USBbuffer[1] = 0
USBbuffer[2] = $04
USBbuffer[3] = 0
USBbuffer[4] = 0
USBbuffer[5] = 0
USBbuffer[6] = 0
USBbuffer[7] = 0


ProgramStart:
USBSERVICE
IF PORTD.0 = 0 THEN
pause 5
Goto DoUSBOut1
ENDIF
goto ProgramStart




DoUSBOut1:

USBBufferCount = USBBufferSizeTX ' TX buffer size
USBService ' keep connection alive
USBOut 1, USBBuffer, USBBufferCount,DoUSBOut1 ' if bus available, transmit data

Tipka3:
USBService
If PORTD.0 = 0 then
pause 5
goto tipka3
else
USBbuffer[2] = $FF
GOSUB DoUSBOut2
GOTO programstart
endif
goto Tipka3

DoUSBOut2:
USBBufferCount = USBBufferSizeTX ' TX buffer size
USBService ' keep connection alive
USBOut 1, USBBuffer, USBBufferCount,DoUSBOut2 ' if bus available, transmit data
return

end

Merfy
- 8th April 2008, 04:26
Hey Faaktoo,

What I think you are looking for are called modifier keys. The modifier keys are keys such as shift, ctrl, alt and so on. They are set by setting the value in USBbuffer[0].

Modifier Key Bits
0 LEFT CTRL
1 LEFT SHIFT
2 LEFT ALT
3 LEFT GUI
4 RIGHT CTRL
5 RIGHT SHIFT
6 RIGHT ALT
7 RIGHT GUI

For example,

USBbuffer[0] = 00000010b

would register as having the left shift button pressed. I haven't actually tested this, and it's been a while since I played with my pics so hopefully this helps you out.

DaveC3
- 10th April 2008, 04:16
Here is a program I use to send key presses to the PC with various switches and encoders. You should be able to get the drift of what needs to happen to get caps, Ctrl, Alt etc.




'Byte Description
'0 Modifier keys
'1 Reserved
'2 Keycode 1
'3 Keycode 2
'4 Keycode 3
'5 Keycode 4
'6 Keycode 5
'7 Keycode 6

'Bit Key
'0 LEFT CTRL 0x01
'1 LEFT SHIFT 0x02
'2 LEFT ALT 0x04
'3 LEFT GUI
'4 RIGHT CTRL 0x10
'5 RIGHT SHIFT 0x20
'6 RIGHT ALT 0x40
'7 RIGHT GUI

' USB Key Code
'Key Mod make Action
' 0x00 No Action
' 1 0 0x1E 5 NM
' 2 0 0x1F 10
' 3 0 0x20 20
' 4 0 0x21 40
' 5 0 0x22 80
' 6 0 0x23 160
' 7 0 0x24 320
' 8 0 0x25 640
' F2 0 0x3B NAV
' F3 0 0x3C AIRPORTS
' F4 0 0x3D WAYPOINTS
'CTRL-D 4 0x07 Toggle FLight Director
' G 0 0x0A TO/GA Switch
' Q 0 0x14 Left NAV
' SHft-Q 2 0x14 ADF
'CTRL-q 4 0z14 VOR1
'CTRL-S 4 0x16 ND Center
'



'************************************************* ******************************
' Interrupt definition
' ====================
' USB interrupt used to keep USB connection alive
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler USB_INT, _DoUSBService, ASM, yes
;INT_Handler RBC_INT, _Selector, PBP, yes
;INT_Handler INT1_INT, _cent, PBP, yes
;INT_Handler INT0_INT, _CHK_Matrix, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM





' ************************************************** **********
' * main program loop - remember, you must keep the USB *
' * connection alive with a call to USBService every couple *
' * of milliseconds or so... *
' ************************************************** **********
pause 500
usbinit ' initialise USB...
USBService ' keep connection alive
UIE = $7F
UEIE = $9F
@ INT_ENABLE USB_INT
;@ INT_ENABLE RBC_INT
;@ INT_ENABLE INT1_INT
;@ INT_ENABLE INT2_INT
gosub dousbin
gosub dousbout
sel_old = sel
baro = PORTD & %00110000
Baro_old = baro
pta = porta
pta_old = pta
ptb_old = ptb
na1 = portc & %11000000
na1_old = na1
na2 = portd & %00001100
na2_old = na2
'gosub selector
'gosub barometric
'gosub toggle1
'gosub toggle2



goto ProgramStart
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@
' '
' Jump to main program '
' '
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@
'
' Sub Routines
'
'
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@



' ************************************************** **********
' * Send data to USB bus *
' ************************************************** **********
Make:
usbbuffer(0)= ModKey
usbbuffer(1)= 0
usbbuffer(2)= Key
gosub Dousbout
modkey = 0
key = 0


usbbuffer(0)= 0 'Clear buffer to stom multible key outputs
usbbuffer(1)= 0
usbbuffer(2)= 0

gosub Dousbout
return

ClrBuffer: ' Clear usb buffer
usbbuffer(0)= 0
usbbuffer(1)= 0
usbbuffer(2)= 0
usbbuffer(3)= 0
usbbuffer(4)= 0
usbbuffer(5)= 0
usbbuffer(6)= 0
usbbuffer(7)= 0

return

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

'################################################# ##############################
Rot_Encoder:


RotEncDir = New_Bits.3 ^ Old_Bits.2
if RotEncDir = 1 then

RotEnc1_val = RotEnc1_val + 1
if RotEnc1_val > 8 then RotEnc1_val = 8
ELSE
RotEnc1_val = RotEnc1_val - 1

if RotEnc1_val < 1 then RotEnc1_val = 1
ENDIF


select case RotEnc1_val ' encoder counts from 1 to 8 and down from 8 to 1
Case 1
modkey = 0
key = $1E
Case 2
modkey = 0
key = $1F
case 3
modkey = 0
key = $20
case 4
modkey = 0
key = $21
case 5
modkey = 0
key = $22
case 6
modkey = 0
key = $23
case 7
modkey = 0
key = $24
case 8
modkey = 0
key = $25

end select
gosub make
Old_Bits = New_Bits

Return

'################################################# ##############################

DoUSBService: 'Keeps USB alive
usbservice
@ INT_RETURN

'################################################# ##############################
Selector:
sel = portb & %11110000

select case sel

case $D0
modkey = 0
KEY = $10 'M ND map mode

case $B0
modkey = 2
KEY = $10 ' Shift M ND VOR mode

case $70
modkey = 1
KEY = $10 'CTRL M ND APP mde

end select
gosub make
sel_old = sel
return
'################################################# ##############################
BaroMetric:
if baro = $10 then
modkey = 0
KEY = $1A ' W Toggle barimetric pressure to US in
gosub make
endif

if baro = $20 then
modkey = 0
KEY = $19 ' V Toggle barimetric pressure to Euro
gosub make

endif

baro_old = baro
Return
'################################################# ##############################
'Minimums:
'if mins = $40 then

'endif

'if mins = $80 then

'endif

'mins_old = mins

'Return
'################################################# ##############################

Push_Buttons:

if porta.0 = 0 then 'Map NAV F2
modkey = 0
KEY = $3B 'F2 Toggle mapstation display ND
gosub make
endif

if porta.1 = 0 then 'Map APPT F3
modkey = 0
KEY = $3C 'F3 Toggle Airports ND
gosub make
endif

if porta.2 = 0 then 'Map WPT F4
modkey = 0
KEY = $3D 'F4 Toggle waypoints ND
gosub make
endif

if porta.3 = 0 then ' MTRS
modkey = 0
KEY = $18 ' U Altitude metric mode
endif

if porta.4 = 0 then ' Toggle FPV
modkey = 1
KEY = $5 ' CRTL B
endif
pta_old = pta

return
'################################################# ##############################
Toggle1:
if na1 = %11000000 then
modkey = 0
key = $14
gosub make
endif
if na1 = %01000000 then
modkey = 2
key = $14
gosub make
endif
if na1 = %10000000 then
modkey = 1
key = $14
gosub make
endif

na1_old = Na1

return

Toggle2:
if na2 = %00001100 then
modkey = 0
key = $15
gosub make
endif
if na2 = %00000100 then
modkey = 2
key = $15
gosub make
endif
if na2 = %00001000 then
modkey = 1
key = $15
gosub make
endif

na2_old = Na2

Return

'************************************************* *****************************
' End Sub Routines
'
'************************************************* ****************************





ProgramStart:

baro = PORTD & %00110000
if baro != baro_old then gosub barometric ' Two position selector switch

'' mins = PORTD & %11000000
'' if mins != mins_old then gosub Minimums


New_Bits = PORTB & %00001100 'check to see if any encoder has changes
IF New_Bits != Old_Bits then gosub rot_encoder ' if changed process encoder



ptb = portb.1 'Switch on Encoder circle
if ptb != Ptb_old then
If portb.1 = 0 then

modkey = 1
key = $16
gosub make
endif
ptb_old = ptb
endif

sel = Portb & %11110000
if sel_old != sel then gosub selector ' 4 position selector switch



pta = porta
if pta != pta_old then gosub Push_Buttons 'Push buttons

na1 = portc & %11000000
if na1 != na1_old then gosub Toggle1 'Toggle switches

na2 = portd & %00001100
if na2 != na2_old then gosub Toggle2



goto ProgramStart


I had to take out a few lines so I did not exceed the post size limit

faaktoo
- 10th April 2008, 11:02
I'm resolved my problem and finished my project (with your help).
Thank you, once again!!!