Shop OBEX P1 Docs P2 Docs Learn Events
Customized Joystick using keyboard remapping instead of device driver — Parallax Forums

Customized Joystick using keyboard remapping instead of device driver

RagtopRagtop Posts: 406
edited 2011-01-06 06:47 in Robotics
Purpose: To create a custom interface for my favorite game Joint Operations without having to figure out how to make a joystick driver in Windows.

The work around: Making a serial connection between the propeller based joystick control and a Visual Basic program that uses sendkey to make the keyboard presses in response.

Current progress: I can use a thumb joystick to send a single alphanumeric code to the Visual Basic program that does send out the key press to window programs like notepad.

Current roadblock 1: DirectX programs use directinput that sendkey does not work with. I can send numbers but not letters of the keyboard.

Current roadblock 2: Repeating keys. Don't mind the directional keys causing multiple key presses, but the joystick button (and future buttons) are going to toggle weapons like rifle/grenade.

webCopy.jpg

CON
  _CLKMODE      = xtal1 + pll16x    '80_000_000 times a sec
  _XINFREQ      = 5_000_000                          ' 5MHz Crystal  
VAR

   long RCStack[16],RC2[16]
   long RCTemp,rctemp2
   long Mode,toggle
   long cog,cog2,x,y,buttonpressed,lr,tb
   
OBJ
   'vp     : "Conduit"
  pst      :  "Parallax Serial Terminal"       

PUB Main
   'vp.config(string("start:dso"))
   'vp.config(string("var:call1,call2,x,y,button"))
   'vp.config(string("dso:view=[y(offset=5.463e+07,scale=4e+08),x(offset=122.5,scale=1000),button(offset=0,scale=1)],timescale=0.5s,ymode=manual"))

   'vp.share(@cog,@tb)
   pst.Start(9600)
   
   start1(0,1,@x)
   start2(4,1,@y)
   dira[3]~
   toggle:=1
   repeat
     buttonpressed := ina[3] 
     if x > 1_400 and x < 1_800
        lr := 0
     elseif x > 1_800  
        lr := 1
     elseif x < 1_400
        lr:= 2

    if y > 1_400 and y < 1_800
        tb := 0
    elseif y > 1_800  
        tb := 1
    elseif x < 1_400
        tb:= 2           

    case lr
      0:  case tb
            0:  pst.str(string("A"))
            1:  pst.str(string("B"))
            2:  pst.str(string("C"))
      1:  case tb
            0:  pst.str(string("D"))
            1:  pst.str(string("E"))
            2:  pst.str(string("F"))
      2:  case tb
            0:  pst.str(string("G"))
            1:  pst.str(string("H"))
            2:  pst.str(string("I"))           
    if buttonpressed
       if toggle == 1
           pst.str(string("J"))
           toggle:=0
       else
           pst.str(string("K"))
           toggle:=1  
   
PUB start1(Pin,State,RCValueAddress)

'' Start RCTIME - starts a cog
'' returns false if no cog available
''
''   RCTIME_ptr = pointer to RCTIME parameters
  
  'stop
  cog := cognew(RCTIME(Pin,State,RCValueAddress),@RCStack)

PUB start2(Pin,State,RCValueAddress)

'' Start RCTIME - starts a cog
'' returns false if no cog available
''
''   RCTIME_ptr = pointer to RCTIME parameters
  
  'stop
  cog2 := cognew(RCTIME2(Pin,State,RCValueAddress),@RC2) 


PUB RCTIME(Pin,State,RCValueAddress)
    repeat
           outa[Pin] := State                   'make I/O an output in the State you wish to measure... and then charge cap
           dira[Pin] := 1                               
           Pause1ms(1)                          'pause for 1mS to charge cap
           dira[Pin] := 0                       'make I/O an input
           RCTemp := cnt                        'grab clock tick counter value
           WAITPEQ(1-State,|< Pin,0)            'wait until pin goes into the opposite state you wish to measure; State: 1=discharge 0=charge
           RCTemp := cnt - RCTemp               'see how many clock cycles passed until desired State changed
           RCTemp := RCTemp - 1600              'offset adjustment (entry and exit clock cycles Note: this can vary slightly with code changes)
           RCTemp := RCTemp >> 4                'scale result (divide by 16) <<-number of clock cycles per itteration loop
           long [RCValueAddress] := RCTemp      'Write RCTemp to RCValue

PUB RCTIME2(Pin,State,RCValueAddress)
    repeat
           outa[Pin] := State                   'make I/O an output in the State you wish to measure... and then charge cap
           dira[Pin] := 1                               
           Pause1ms(1)                          'pause for 1mS to charge cap
           dira[Pin] := 0                       'make I/O an input
           RCTemp2 := cnt                        'grab clock tick counter value
           WAITPEQ(1-State,|< Pin,0)            'wait until pin goes into the opposite state you wish to measure; State: 1=discharge 0=charge
           RCTemp2 := cnt - RCTemp2               'see how many clock cycles passed until desired State changed
           RCTemp2 := RCTemp2 - 1600              'offset adjustment (entry and exit clock cycles Note: this can vary slightly with code changes)
           RCTemp2 := RCTemp2 >> 4                'scale result (divide by 16) <<-number of clock cycles per itteration loop
           long [RCValueAddress] := RCTemp2      'Write RCTemp to RCValue
PUB Pause1ms(Period)|ClkCycles 
{{Pause execution for Period (in units of 1 ms).}}

  ClkCycles := ((clkfreq / 1000 * Period) - 4296) #> 381     'Calculate 1 ms time unit
  waitcnt(ClkCycles + cnt)                                   'Wait for designated time              
Sign In or Register to comment.