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,
END_COLLECTION(0),
// 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,
END_COLLECTION(0),
END_COLLECTION(0),
// 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,
END_COLLECTION(0),
};
2 thoughts on “Capacitive Joystick Prototype”