code.py
  1  # SPDX-FileCopyrightText: 2018 jenfoxbot@gmail.com
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  # Minecraft Gesture Controller
  6  #
  7  # Written by <jenfoxbot@gmail.com>
  8  # MIT License V.asof2018
  9  # Also coffee/beer ware license :)
 10  # Super awesome thanks to:
 11  # Richard Albritton, Tony DiCola, John Parker
 12  # All the awesome people who wrote the libraries
 13  
 14  # Libraries
 15  
 16  
 17  import time
 18  
 19  # Libraries for accelerometer
 20  import adafruit_lis3dh
 21  import board
 22  import busio
 23  # General purpose libraries
 24  import touchio
 25  # Libraries for HID Keyboard & Mouse
 26  import usb_hid
 27  from adafruit_hid.keyboard import Keyboard
 28  from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
 29  from adafruit_hid.keycode import Keycode
 30  from adafruit_hid.mouse import Mouse
 31  
 32  # CPX Setup
 33  touch_a1 = touchio.TouchIn(board.A1)
 34  touch_a1.threshold = 2000
 35  touch_a2 = touchio.TouchIn(board.A2)
 36  touch_a2.threshold = 2000
 37  touch_a3 = touchio.TouchIn(board.A3)
 38  touch_a3.threshold = 2000
 39  touch_a4 = touchio.TouchIn(board.A4)
 40  touch_a4.threshold = 2000
 41  
 42  # Keyboard & Mouse Setup
 43  
 44  # The keyboard object!
 45  kbd = Keyboard(usb_hid.devices)
 46  # we're americans :)
 47  layout = KeyboardLayoutUS(kbd)
 48  # The mouse object!
 49  mouse = Mouse(usb_hid.devices)
 50  
 51  # Accelerometer Setup
 52  
 53  # Initialize Accelerometer
 54  i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
 55  lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=25)
 56  # Set range of accelerometer
 57  # (can be RANGE_2_G, RANGE_4_G, RANGE_8_G or RANGE_16_G).
 58  lis3dh.range = adafruit_lis3dh.RANGE_8_G
 59  
 60  
 61  # Controller Functions
 62  
 63  # A helper to 'remap' an input range to an output range
 64  def Map(x, in_min, in_max, out_min, out_max):
 65      return int(
 66          (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
 67      )
 68  
 69  
 70  def Move(upDown_axis, isBackward):
 71      axis_new = abs(upDown_axis)
 72      # If you are touching A4, walk backwards, else walk forwards
 73      if isBackward:
 74          print("backwards")  # Debugging
 75          if axis_new > 1.2:  # walk threshold
 76              if axis_new > 2.5:  # run threshold
 77                  kbd.press(Keycode.LEFT_CONTROL, Keycode.S)
 78                  time.sleep(0.1)
 79                  kbd.release_all()
 80              else:
 81                  kbd.press(Keycode.S)
 82                  time.sleep(0.1)
 83              kbd.release_all()
 84      else:
 85          if axis_new > 1.2:  # walk threshold
 86              if axis_new > 2.5:  # run threshold
 87                  kbd.press(Keycode.LEFT_CONTROL)
 88                  time.sleep(0.1)
 89                  kbd.release_all()
 90              else:
 91                  kbd.press(Keycode.W)
 92                  time.sleep(0.1)
 93              kbd.release_all()
 94  
 95  
 96  def Turn(upDown_axis, leftRight_axis, lookUp):
 97      leftRight_adj = int(leftRight_axis)  # currently z_axis
 98      upDown_adj = int(upDown_axis)  # currently y_axis
 99  
100      leftRight_new = Map(leftRight_adj, -3, 3, -100, 100)
101      if lookUp and abs(upDown_adj) < 1.2:
102          upDown_new = Map(upDown_adj, -1, 1, -100, 100)
103      else:
104          upDown_new = 0
105      if abs(leftRight_new) < 127:
106          mouse.move(-leftRight_new, upDown_new)
107      else:
108          mouse.move(0, 0)
109  
110  
111  def Jump(upDown_axis):
112      upDown = abs(upDown_axis)
113      if upDown > 3:
114          kbd.press(Keycode.SPACE, Keycode.W)
115      kbd.release_all()
116  
117  
118  def Give(upDown_axis, frontBack_axis):
119      frontBack_new = abs(frontBack_axis)
120      if abs(upDown_axis) < 1:
121          if frontBack_new > 2:
122              print("give")
123              mouse.click(Mouse.RIGHT_BUTTON)
124              mouse.release_all()
125  
126  
127  def Attack():
128      """Attack! By clicking the left mouse button"""
129      print("attack")
130      mouse.click(Mouse.LEFT_BUTTON)
131      time.sleep(0.1)
132      mouse.release_all()
133  
134  
135  def Inventory():
136      """Open up inventory, press the E keyboard key"""
137      print("inventory")  # Debugging -- view in serial monitor
138      kbd.press(Keycode.E)
139      time.sleep(0.01)
140      kbd.release_all()
141  
142  
143  def ESC():
144      """Escape by pressing the ESCape key"""
145      print("ESC")  # Debugging -- view in serial monitor
146      kbd.press(Keycode.ESCAPE)
147      time.sleep(0.01)
148      kbd.release_all()
149  
150  
151  def readAxes():
152      """Convert acceleration from m/s^2 to G, with a delay"""
153      x, y, z = lis3dh.acceleration
154      time.sleep(0.01)
155      return (x / 9.806, y / 9.806, z / 9.806)  # 9.806 m/s^2 per G
156  
157  
158  # Main Function
159  while True:
160      # Read accelerometer values (in G).  Returns a 3-tuple of x, y, x axis
161      pos_x, pos_y, pos_z = readAxes()
162  
163      # Read finger pads and act accordingly
164      if touch_a1.value:
165          Attack()
166  
167      if touch_a2.value:
168          Inventory()
169  
170      if touch_a3.value:
171          ESC()
172  
173      is_backward = touch_a4.value
174      look_up = touch_a4.value
175  
176      # Run through the motions! .. literally :)
177      Move(pos_y, is_backward)
178      Turn(pos_y, pos_z, look_up)
179      Jump(pos_y)
180      Give(pos_y, pos_x)
181  
182      # Small delay to keep things responsive but
183      # give time for interrupt processing.
184      time.sleep(0.01)
185  
186      # Debugging Ahead!!
187      # Use the following 2 lines to figure out which
188      # axis is upDown, frontBack, or LeftRight
189      # and also for debugging!
190      # print('x = {}G, y = {}G, z = {}G'.format(x, y, z))
191      # time.sleep(0.3)