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”