Capacitive Joystick Prototype

While I contributed to Active Games at Frankfurt University this year I digged a bit deeper into the capabilities of Cypress PSoC 4. I already played a bit with the capsense feature to realize touch-buttons or sliders. This time I went for the proximity sensor.

I started by connecting a single wire to the PSoC4 and enable the proximity sensor feature for it while sending the raw data via UART. I was impressed by the sensibility and also the S/N ratio. I attached a longer wire to the pin and was able to detect my body even if I was ~1m away. Of course my capacity sensor was not optimized but with that result from just "trial and error" I am pretty sure that you can make it a lot more sensitive if you spend some time reading about how to design the sensor (and not just use a wire).

However, the idea of Active Games is to develop and implement bodily user interfaces so i decided to give it a try and make my own capacitive joystick using proximity sensors.

The actual implementation is relative easy. I use 2 proximity sensors and subtract the values to get the X-Axis while I sum them up to get the Y-Axis. I send this data to a Freescale FRDM-KL25Z with a modified USB-HID library to make a USB-Joystick out of it.

I modified the mbed USBDevice library and ended up with a keyboard, joystick and media control, all in one.

static uint8_t reportDescriptor[] = {
                // Keyboard
                USAGE_PAGE(1),          0x01,
                USAGE(1),               0x06,
                COLLECTION(1),          0x01,
                REPORT_ID(1),           REPORT_ID_KEYBOARD,
                USAGE_PAGE(1),          0x07,
                USAGE_MINIMUM(1),       0xE0,
                USAGE_MAXIMUM(1),       0xE7,
                LOGICAL_MINIMUM(1),     0x00,
                LOGICAL_MAXIMUM(1),     0x01,
                REPORT_SIZE(1),         0x01,
                REPORT_COUNT(1),        0x08,
                INPUT(1),               0x02,
                REPORT_COUNT(1),        0x01,
                REPORT_SIZE(1),         0x08,
                INPUT(1),               0x01,
                REPORT_COUNT(1),        0x05,
                REPORT_SIZE(1),         0x01,
                USAGE_PAGE(1),          0x08,
                USAGE_MINIMUM(1),       0x01,
                USAGE_MAXIMUM(1),       0x05,
                OUTPUT(1),              0x02,
                REPORT_COUNT(1),        0x01,
                REPORT_SIZE(1),         0x03,
                OUTPUT(1),              0x01,
                REPORT_COUNT(1),        0x06,
                REPORT_SIZE(1),         0x08,
                LOGICAL_MINIMUM(1),     0x00,
                LOGICAL_MAXIMUM(2),     0xff, 0x00,
                USAGE_PAGE(1),          0x07,
                USAGE_MINIMUM(1),       0x00,
                USAGE_MAXIMUM(2),       0xff, 0x00,
                INPUT(1),               0x00,

                // Joystick
                USAGE_PAGE(1),          0x01,           // Generic Desktop
                USAGE(1),               0x04,           // Joystick
                COLLECTION(1),          0x01,           // Application
                USAGE(1),               0x01,           // Pointer
                COLLECTION(1),          0x00,           // Physical
                REPORT_ID(1),           REPORT_ID_MOUSE,
                REPORT_COUNT(1),        0x03,
                REPORT_SIZE(1),         0x01,
                USAGE_PAGE(1),          0x09,           // Buttons
                USAGE_MINIMUM(1),       0x1,
                USAGE_MAXIMUM(1),       0x3,
                LOGICAL_MINIMUM(1),     0x00,
                LOGICAL_MAXIMUM(1),     0x01,
                INPUT(1),               0x02,    
                REPORT_COUNT(1),        0x01,
                REPORT_SIZE(1),         0x05,
                INPUT(1),               0x01,
                REPORT_COUNT(1),        0x02,
                REPORT_SIZE(1),         0x08,
                USAGE_PAGE(1),          0x01,
                USAGE(1),               0x30,           // X
                USAGE(1),               0x31,           // Y
              //  USAGE(1),             0x32,           // Z
                LOGICAL_MINIMUM(1),     0x81,
                LOGICAL_MAXIMUM(1),     0x7f,
                INPUT(1),               0x02,

                // Media Control
                USAGE_PAGE(1),         0x0C,
                USAGE(1),              0x01,
                COLLECTION(1),         0x01,
                REPORT_ID(1),          REPORT_ID_VOLUME,
                USAGE_PAGE(1),         0x0C,
                LOGICAL_MINIMUM(1),    0x00,
                LOGICAL_MAXIMUM(1),    0x01,
                REPORT_SIZE(1),        0x01,
                REPORT_COUNT(1),       0x07,
                USAGE(1),              0xB5,             // Next Track
                USAGE(1),              0xB6,             // Previous Track
                USAGE(1),              0xB7,             // Stop
                USAGE(1),              0xCD,             // Play / Pause
                USAGE(1),              0xE2,             // Mute
                USAGE(1),              0xE9,             // Volume Up
                USAGE(1),              0xEA,             // Volume Down
                INPUT(1),              0x02,             // Input (Data, Variable, Absolute)
                REPORT_COUNT(1),       0x01,
                INPUT(1),              0x01,


2 thoughts on “Capacitive Joystick Prototype

  1. […] So I take the Capsense Project without BLE to check if there are any differences to a regular PSoC4 Project. After I have relocated the PWM to the right Pin it works, if my finger gets close to the sensor it brightens up. Not too spectacular, also because I once pushed capsense to the limits when building my capacitive joystick. […]

  2. Title

    [... ]we prefer to recognize quite a few various other web web pages on the web, whether or not these people aren’t related to people, simply by backlinking to them. Here are some web sites worth verifying out[... ]…

Leave a Reply

About Thomas Barth

Thomas Barth, born 1986, is a german teaching fellow and Ph.D. student. He studied electrical engineering in Darmstadt, Frankfurt and Helsinki and worked 7 years in industry automation before he switched to embedded systems and microelectronics. To read more about him, click here.