Skip to content

Instantly share code, notes, and snippets.

@joaquimadraz
Created May 13, 2018 12:01
Show Gist options
  • Save joaquimadraz/82ec5f58cee0e48d4ae503b0268615b1 to your computer and use it in GitHub Desktop.
Save joaquimadraz/82ec5f58cee0e48d4ae503b0268615b1 to your computer and use it in GitHub Desktop.
Dream Cheeky USB Missile Launcher
# REFERENCES
# https://github.com/codedance/Retaliation/blob/master/retaliation.py
# http://www.rkblog.rk.edu.pl/w/p/controlling-usb-missile-launchers-python/
# http://matthias.vallentin.net/blog/2007/04/writing-a-linux-kernel-driver-for-an-unknown-usb-device/
require 'libusb'
class Launcher
ID_PRODUCT = 0x0701
ID_VENDOR = 0x0a81
SETUP_PACKET = {
bmRequestType: 0x21,
bRequest: 0x09,
wValue: 0x02,
wIndex: 0x0
}
MOVES = {
down: "\x01\x00", # 1
up: "\x02\x00", # 2
left: "\x04\x00", # 4
right: "\b\x00", # 8
}.freeze
FIRE = "\x10\x00".freeze # 16
STOP = "\x20\x00".freeze # 32
def initialize
device = connect_device!
@handle = device.open
end
def fire
send(FIRE)
sleep(5) # recoil for 1 missile
stop_fire
end
def move_left
timed_move(:left)
end
def move_right
timed_move(:right)
end
def move_up
timed_move(:up)
end
def move_down
timed_move(:down)
end
private
attr_reader :handle
# STOP bytes are not stoping the fire command.
# Sending a command to move somewhere and then STOP, works. ¯\_(ツ)_/¯
def stop_fire
send(MOVES[:up])
stop
end
def stop
send(STOP)
end
def timed_move(move, timeout: 0.5)
send(MOVES[move])
sleep(timeout)
stop
end
def connect_device!
usb = LIBUSB::Context.new
device = usb.devices(idVendor: ID_VENDOR, idProduct: ID_PRODUCT).first
raise('device not found') unless device
device
end
def send(data)
handle.control_transfer(**SETUP_PACKET, dataOut: data)
end
end
launcher = Launcher.new
launcher.fire
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment