With the Jetson Nano I connected a PS4 controller via bluetooth and the device showed up under /dev/input/js0
. However when I connect the controller via bluetooth to my Coral board, I am seeing nothing at that location, maybe because of Mendel instead of Ubuntu? What is the recommended way to connect a PS4 controller and access it from C++? Is there a different joystick I should use?
After doing some research I learned about the difference between joydev and evdev on linux. It seems my PS4 controller showed up as a joydev device on the Jetson, whereas on the Coral running Mendel it showed up as an evdev device. I found some example C++ code for evdev devices from Croepha / David Butler here: https://handmade.network/forums/t/3673-modern_way_to_read_gamepad_input_with_c_on_linux
I modified this code for the PS4 controller like this:
void runJoystick() {
auto gamepad = open("/dev/input/event4", O_RDONLY | O_NONBLOCK); //todo use /proc/bus/input/devices instead
assert(gamepad != -1);
std::cout << "Running joystick" << std::endl;
while (m_still_running) {
struct input_event events[8]; // 8 events per frame is pretty extreme, more like 1 or 2, sometimes as high as 4
auto r1 = read(gamepad, events, sizeof events);
if (r1 != -1) {
int new_event_count = r1 / sizeof(struct input_event);
for (int evi = 0; evi < new_event_count; evi++) {
auto& ev = events[evi];
switch (ev.type) {
case EV_ABS: {
switch (ev.code) {
case ABS_X: { // left x
// std::cout << "type " << ev.code << "value:" << ev.value << std::endl;
} break;
case ABS_Y: { // left y
// std::cout << "type " << ev.code << "value:" << ev.value << std::endl;
} break;
case ABS_Z: { // right x
// std::cout << "type " << ev.code << "value:" << ev.value << std::endl;
} break;
case ABS_RZ: { // right y
// std::cout << "type " << ev.code << "value:" << ev.value << std::endl;
} break;
}
} break;
case EV_KEY: {
switch (ev.code) {
case BTN_A: { // square
std::cout << "Square ";
} break;
case BTN_B: { // x
std::cout << "X ";
} break;
case BTN_C: { // circle
std::cout << "Circle ";
} break;
case BTN_X: { // triangle
std::cout << "Triangle ";
} break;
}
if (ev.value) {
std::cout << "Pressed " << std::endl;
} else {
std::cout << "Released " << std::endl;
}
} break;
}
}
}
assert(r1 != -1 || errno == EWOULDBLOCK || errno == EAGAIN);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}