{"id":131,"date":"2013-11-23T01:19:24","date_gmt":"2013-11-23T01:19:24","guid":{"rendered":"http:\/\/coffeefueledcreations.com\/blog\/?p=131"},"modified":"2016-09-26T23:08:13","modified_gmt":"2016-09-26T22:08:13","slug":"using-java-libusb-wrapper-to-control-dream-cheeky-thunder-turret","status":"publish","type":"post","link":"http:\/\/coffeefueledcreations.com\/blog\/?p=131","title":{"rendered":"Using Java libusb Wrapper to Control Dream Cheeky Thunder Turret"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>After getting frustrated trying to get any Java USB library to work I figured it&#8217;s probably worth writing about one that does (It seems many are old projects). Specifically if you want to control DreamCheeky&#8217;s Thunder Turret, this guide is dedicated to you.<\/p>\n<p>One of the first pitfalls I fell into is what documentation to read and where. With some of the libraries it seemed documentation was non existent. I&#8217;ll attempt to link all the sources I used and comment the hell out of my code. I found myself asking &#8220;why?&#8221; A LOT as this is my first exposure Java USB and the libraries assume the reader has existing knowledge of USB protocols.\u00a0I found many Python tutorials but here is one for Java.<!--more--><\/p>\n<h2>Before we start<\/h2>\n<p>When writing this I was using Windows 7 64bit. Programming in NetBeans.<\/p>\n<p>Read some of this:\u00a0<a href=\"http:\/\/libusbjava.sourceforge.net\/wp\/\">http:\/\/libusbjava.sourceforge.net\/wp\/<\/a><\/p>\n<p>This is the project site for Java libusb wrapper we will be using. It details how to set-up your device for use with the libusb library. I will be attempting to go through everything in detail for Win7 first but I&#8217;m hoping to make another post in the near future about getting everything to work in Linux (Debian\/Centos\/Ubuntu likely).<\/p>\n<h3>Files<\/h3>\n<p>libusb-win32-bin-1.2.6.0.zip:<a href=\"http:\/\/sourceforge.net\/projects\/libusb-win32\/files\/libusb-win32-releases\/1.2.6.0\/\"><br \/>\nhttp:\/\/sourceforge.net\/projects\/libusb-win32\/files\/libusb-win32-releases\/1.2.6.0\/<br \/>\n<\/a><\/p>\n<p>libusb jar library (ch.ntb.usb-0.5.9.jar):<br \/>\n<a href=\"http:\/\/sourceforge.net\/projects\/libusbjava\/files\/libusbjava-snapshots\/20090517\/\">http:\/\/sourceforge.net\/projects\/libusbjava\/files\/libusbjava-snapshots\/20090517\/<\/a><\/p>\n<h2>Install libusb driver for Thunder Launcher<\/h2>\n<h3><span style=\"color: #999999;\"><a title=\"libusb install\" href=\"http:\/\/libusbjava.sourceforge.net\/wp\/?page_id=8\"><span style=\"color: #999999;\">(source)<\/span><\/a><\/span><\/h3>\n<p>In order to allow libusb to see the usb device we need to create a driver for it. This is done with a tool provided with libusb-win32. Inside &#8220;bin&#8221; directory in the zip file run the inf-wizard.exe, select next and find the device we want to use in your Java program. For the Thunder Turret the Vendor ID is 0x2123 and the Product ID is 0x1010. Select this and click next. Click next again and select a place to save the driver. Install the driver then check that the USB device is using it.<\/p>\n<p>Creating the driver will automatically copy over some dlls but one needs to be copied over manually:<\/p>\n<ul>\n<li>LibusbJava.dll -&gt; windowssystem32<\/li>\n<\/ul>\n<p>By default the device manage will not use this driver as it is not digitally signed. We may need to force the device manager to use our driver. \u00a0In the start menu right click &#8220;Computer&#8221; and select manage. On the left pane select Device Manager. The launcher will be under &#8220;Human Interface Devices&#8221;. Find the right device with the right product id and vendor id.<\/p>\n<p>Right click device &gt; Properties &gt; Details tab &gt; Property: &#8220;Hardware Ids&#8221;<\/p>\n<p>VID = Vendor ID (1010)<br \/>\nPID = Product ID (2123)<\/p>\n<p>Select the driver tab and update the driver. Locate the driver manually and explicitly pick the driver you made. (It will warn you about the driver not being digitally signed)<\/p>\n<p>Your missile launcher is ready for some Java!<\/p>\n<h2>Java Thunder Launcher<\/h2>\n<p>Lets start by creating an object to hide all of the grizzly bits from us so we can just send a command and a length of time to execute it in milliseconds.<\/p>\n<p>Create a new Java Application NetBeans Project and import the\u00a0ch.ntb.usb-0.5.9.jar file.<\/p>\n<p>To control the launcher we are sending commands in the data packet for the control message. To control the motors the first byte is 0x02. For the LED it is 0x03. The second byte is the command and the other 6 bytes are 0x00. For reference the commands we are passing in the data packet are as follows:<\/p>\n<p>DOWN = 0x01<br \/>\nUP = 0x02<br \/>\nLEFT = 0x04<br \/>\nRIGHT = 0x08<br \/>\nFIRE = 0x10<br \/>\nSTOP = 0x20<br \/>\nLEDON = 0x01<br \/>\nLEDOFF = 0x00<\/p>\n<p>Thanks to:\u00a0<a href=\"https:\/\/github.com\/codedance\/Retaliation\">https:\/\/github.com\/codedance\/Retaliation<\/a><\/p>\n<p>650 pages of fun! (Seriously though, look up\u00a0Control Transfers to get an idea what is going on. Pages, 225-227, 248-250)\u00a0<a href=\"http:\/\/sdphca.ucsd.edu\/Lab_Equip_Manuals\/usb_20.pdf\">http:\/\/sdphca.ucsd.edu\/Lab_Equip_Manuals\/usb_20.pdf<\/a><\/p>\n<p>The first thing to do is create an object we can use to control the launcher. Here&#8217;s mine:<\/p>\n<pre class=\"prettyprint\"><code class=\"language-java\">package thunderlauncher;\r\n\r\nimport ch.ntb.usb.Device;\r\nimport ch.ntb.usb.USB;\r\nimport ch.ntb.usb.USBException;\r\n\r\n\/**\r\n *\r\n * @author James Green\r\n * @version 1.0.0\r\n * @website http:\/\/coffeefueledcreations.com\/\r\n *\/\r\npublic class Launcher {\r\n\r\n    private Device dev = null;\r\n    private final byte[][] COMMANDS = {{0x02, 0x20, 0x00,0x00,0x00,0x00,0x00,0x00},{0x03, 0x01, 0x00,0x00,0x00,0x00,0x00,0x00},{0x03, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00},{0x02, 0x02, 0x00,0x00,0x00,0x00,0x00,0x00},{0x02, 0x01, 0x00,0x00,0x00,0x00,0x00,0x00},{0x02, 0x04, 0x00,0x00,0x00,0x00,0x00,0x00},{0x02, 0x08, 0x00,0x00,0x00,0x00,0x00,0x00},{0x02, 0x10, 0x00,0x00,0x00,0x00,0x00,0x00}};\r\n    public enum Command {STOP,LEDON,LEDOFF,UP,DOWN,LEFT,RIGHT,FIRE}\r\n\r\n    Launcher(){\r\n        usbSetup();\r\n    }\r\n\r\n    \/**\r\n     * Resets the turret to a guess at middle position\r\n     *\/\r\n    private void zero(){ \/\/ Reset to bottom left and return to center-ish\r\n            execute(Launcher.Command.DOWN, 3000);\r\n            execute(Launcher.Command.LEFT, 6000);\r\n            execute(Launcher.Command.RIGHT, 3000);\r\n            execute(Launcher.Command.UP, 200);\r\n    }\r\n\r\n    \/**\r\n     * Open the USB Thunder Launcher\r\n     *\/\r\n    private void usbSetup(){ \r\n        dev = USB.getDevice((short) 0x2123, (short) 0x1010); \/\/ Vendor ID, Product ID\r\n        try {\r\n            dev.open(1, 0, -1); \/\/ Open the device (Configuration(default), Interface(Control), AlternativeConfig(None))\r\n        } catch (USBException ex) {\r\n            System.out.println(\"Please check the driver for device VID:0x2123, PID:0x1010\");\r\n            ex.printStackTrace();\r\n        }\r\n    }\r\n\r\n    \/**\r\n     * \r\n     * @param c Use the public \"Command\" enum to control the turret.\r\n     * @param Duration The number of milliseconds to execute the command.\r\n     * The FIRE command takes about 3300 milliseconds.\r\n     *\/\r\n    public void execute(Command c, long Duration){\r\n        try{\r\n        if(dev.isOpen()){\r\n            switch(c){\r\n                case STOP: \/\/ Send a control message\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[0], COMMANDS[0].length, 2000, false);\r\n                    break;\r\n                case LEDON:\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[1], COMMANDS[1].length, 2000, false);\r\n                    break;\r\n                case LEDOFF:\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[2], COMMANDS[2].length, 2000, false);\r\n                    break;\r\n                case UP:\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[3], COMMANDS[3].length, 2000, false);\r\n                    break;\r\n                case DOWN:\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[4], COMMANDS[4].length, 2000, false);\r\n                    break;    \r\n                case LEFT:\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[5], COMMANDS[5].length, 2000, false);\r\n                    break;    \r\n                case RIGHT:\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[6], COMMANDS[6].length, 2000, false);\r\n                    break;    \r\n                case FIRE:\/\/The fire command needs about 3300 milis to execute\r\n                    dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[7], COMMANDS[7].length, 2000, false);\r\n                    break;          \r\n            } \r\n            long wait = System.currentTimeMillis()+Duration;\r\n            while(wait &gt; System.currentTimeMillis()){\r\n                \/\/Burn Time and let the Launcher execute.\r\n            }\r\n            dev.controlMsg(0x21, 0x09, 0,0, COMMANDS[0], COMMANDS[0].length, 2000, false);\r\n        }\r\n        }catch(Exception e){\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n}\r\n<\/code><\/pre>\n<p>As a simple demo, lets attach some keyboard controls.<\/p>\n<pre class=\"prettyprint\"><code class=\"language-java\">package thunderlauncher;\r\n\r\nimport java.awt.event.ActionEvent;\r\nimport java.awt.event.ActionListener;\r\nimport java.awt.event.KeyEvent;\r\nimport java.awt.event.KeyListener;\r\nimport javax.swing.JFrame;\r\nimport javax.swing.JLabel;\r\n\r\n\/**\r\n *\r\n * @author James Green\r\n * @version 1.0.0\r\n * @website http:\/\/coffeefueledcreations.com\/\r\n *\/\r\npublic class KeyController extends JFrame implements KeyListener, ActionListener  {\r\n    Launcher l = null;\r\n    KeyController(Launcher l){\r\n        this.l = l;\r\n        javax.swing.SwingUtilities.invokeLater(new Runnable() { \/\/Thread safe GUI initilazation\r\n            public void run() {\r\n                createGUI();\r\n            }\r\n        });\r\n    }\r\n\r\n    private void createGUI() {\r\n        this.setName(\"Key Controller Demo\");\r\n        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r\n        JLabel label = new JLabel();\r\n        label.setText(\"Use arrow keys to move launcher, space to fire and z,x to toggle led\");\r\n        this.add(label);\r\n        this.setSize(410, 200);\r\n        this.setVisible(true);\r\n        this.addKeyListener(this);\r\n    }\r\n\r\n    @Override\r\n    public void keyPressed(KeyEvent e) {\r\n        System.out.println(e.getKeyCode());\r\n        switch(e.getKeyCode()){\r\n            case 38:\r\n                l.execute(Launcher.Command.UP, 25);\r\n                break;\r\n            case 40:\r\n                l.execute(Launcher.Command.DOWN, 25);\r\n                break;\r\n            case 37:\r\n                l.execute(Launcher.Command.LEFT, 25);\r\n                break;\r\n            case 39:\r\n                l.execute(Launcher.Command.RIGHT, 25);\r\n                break;\r\n            case 32:\r\n                l.execute(Launcher.Command.FIRE, 3300);\r\n                break;\r\n            case 90:\r\n                l.execute(Launcher.Command.LEDON, 1);\r\n                break;\r\n            case 88:\r\n                l.execute(Launcher.Command.LEDOFF, 1);\r\n                break;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void keyReleased(KeyEvent e) {\r\n\r\n    }\r\n\r\n    @Override\r\n    public void actionPerformed(ActionEvent e) {\r\n\r\n    }\r\n\r\n    @Override\r\n    public void keyTyped(KeyEvent e) {\r\n\r\n    } \r\n}\r\n<\/code><\/pre>\n<p>And finally this is the main to start it all off.<\/p>\n<pre class=\"prettyprint\"><code class=\"language-java\">package thunderlauncher;\r\n\r\n\/**\r\n *\r\n * @author James Green\r\n * @version 1.0.0\r\n * @website http:\/\/coffeefueledcreations.com\/\r\n *\/\r\npublic class ThunderLauncher {\r\n    public static void main(String[] args) {\r\n        Launcher l = new Launcher();\r\n        KeyController kc = new KeyController(l);\r\n    }   \r\n}\r\n<\/code><\/pre>\n<h2>Results<\/h2>\n<p><iframe loading=\"lazy\" src=\"\/\/www.youtube.com\/embed\/i6ofy0sgbtc\" height=\"315\" width=\"420\" allowfullscreen=\"\" frameborder=\"0\"><\/iframe><\/p>\n<h2>Next Part:\u00a0Face Detection<\/h2>\n<p><a href=\"http:\/\/coffeefueledcreations.com\/blog\/?p=153\">[Next, Face Detection]<\/a><br \/>\n<iframe loading=\"lazy\" src=\"\/\/www.youtube.com\/embed\/XYkFHRNGVN0\" height=\"315\" width=\"560\" allowfullscreen=\"\" frameborder=\"0\"><\/iframe><\/p>\n<p>Note: You can roll back the driver by updating the driver and let windows find it automatically.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction After getting frustrated trying to get any Java USB library to work I figured it&#8217;s probably worth writing about one that does (It seems many are old projects). Specifically if you want to control DreamCheeky&#8217;s Thunder Turret, this guide &hellip; <a href=\"http:\/\/coffeefueledcreations.com\/blog\/?p=131\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8,11,14],"tags":[],"_links":{"self":[{"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/131"}],"collection":[{"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=131"}],"version-history":[{"count":1,"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/131\/revisions"}],"predecessor-version":[{"id":328,"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/131\/revisions\/328"}],"wp:attachment":[{"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/coffeefueledcreations.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}