kaiseiyokoyama / joycon-rs Goto Github PK
View Code? Open in Web Editor NEWJoy-Con library for Rust 🦀 🎮
License: Apache License 2.0
Joy-Con library for Rust 🦀 🎮
License: Apache License 2.0
hidapi::HidApi
exists only one instance at a time. Because of that, only one JoyConManager
could exists at a time.
Add examples of
Thanks for creating this library!
I'm having some trouble running the examples on Ubuntu 20.04, with kernel 5.11.0-38-generic. I paired my Joy-Con (R) via bluetooth.
$ dmesg
[ 52.887339] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[ 52.887344] Bluetooth: HIDP socket layer initialized
[ 53.950876] hid-generic 0005:057E:2007.0007: unknown main item tag 0x0
[ 53.951099] input: Joy-Con (R) as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/bluetooth/hci0/hci0:256/0005:057E:2007.0007/input/input31
[ 53.951471] hid-generic 0005:057E:2007.0007: input,hidraw4: BLUETOOTH HID v0.01 Gamepad [Joy-Con (R)] on c8:21:58:8e:32:ca
If I run cat /dev/input/js0
I can see that button presses are getting sent to my computer. However, the joycon-rs examples (for example scan_for_joycons) don't seem to recognize my joycon. There is no output and I can only close it with Ctrl+C
I also tried the "Receiving reports" example on the README.md and the same behaviour occurs there. Using a debugger, its stuck on the line managed_devices.into_iter()
I've also tried using the dkms-hid-nintendo kernel module, but I still can't get the library to work.
Do you have any pointers on what else I could try/check?
EDIT: to confirm the dkms HID nintendo kernel module works, I have verified with dmesg
:
[ 1841.730027] input: Nintendo Switch Right Joy-Con as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/bluetooth/hci0/hci0:256/0005:057E:2007.0009/input/input34
[ 1841.730617] input: Nintendo Switch Right Joy-Con IMU as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/bluetooth/hci0/hci0:256/0005:057E:2007.0009/input/input35
and two controllers(regulars controls, and IMU) show up in jstest-gtk
ref.
setup()
and construct()
setup()
and construct()
methods are separated from the new()
method so that common parts of the implementation can be omitted, but there is a major drawback that reduces the degree of freedom of implementation.Deref
and DerefMut
driver()
, driver_mut()
, into_driver()
enhance #1 's code design and feature
To reduce crate size, move images to somewhere.
Hi. I'm writing a program which runs on Ubuntu 20.04 using joycon-rs.
I think it is necessary to change backend of hidapi to solve the issue #65, however it is impossible to control features of indirectly depended crates.
Therefore, I want joycon-rs to re-export features of hidapi.
I tried to implement it like this, and it seems to have worked.
I hope you will consider it. I'm willing to send a PR. Of course, it's ok if there's a better way.
ack_byte
ack_byte
once()
for SubCommandReplyData
In the 21 input reports, the byte13 (ACK byte) can be parsed as follows: byte13 >> 7 tells us if it's an ACK or NACK. If it's an ACK, check byte13 & 0x7F to see what type of data it has. If it is a simple ACK, the byte13 is x80 and thus the type of data is x00. If we expect a certain order of received packets, we can hardcode these byte13 values. If it's a NACK, the byte13 is always x00
Powered by DeepL ->
21 の入力レポートでは、byte13 (ACK バイト) は次のように解析することができます:byte13 >> 7 は ACK か NACK かを示します。ACK の場合は、byte13 & 0x7F をチェックして、それがどのようなデータタイプを持っているかを確認します。単純なACKであれば、byte13はx80なのでデータの種類はx00となります。受信パケットの特定の順番が予想される場合は、これらのbyte13の値をハードコードすることができます。NACK の場合、byte13 は常に x00 です。
FYI, I'm also doing a crate for full Joycon support! It's at https://github.com/Yamakaky/joy. I plan to support the full feature set of the hardware, including NFC read, gyroscope, merging right and left joycon in one controller and such. I currently mainly support the infrared camera and accelerometer+gyro, with the goal to recreate a 3D view from the raw image.
Do you have other sources of documentation appart from jc_tookit and https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering?
According to git history, I really started my crate one month after you, but didn't think to check if someone had started a similar crate since my first try ^^
Old version, I added a lot of features since:
Hi. I'm using your library (version 0.6.1), and I'm noticing that with the example code in "standard_full_report.rs" the main thread panics if I
I'm using Windows 10 Pro - 21H1 - 19043.1348
Rust 1.56.1
I have lightly edited the example code to be able to show the error more clearly (without all the normal controller messages), and with a stacktrace
#![allow(unused_must_use)]
use joycon_rs::prelude::*;
fn main() -> JoyConResult<()> {
// First, connect your Joy-Cons to your computer!
let (tx, rx) = std::sync::mpsc::channel();
let _output = std::thread::spawn(move || {
// Push buttons or tilt the stick please.
// Stop with `Cmd + C` or `Ctrl + C`
while let Ok(_message) = rx.recv() {
//dbg!(message);
}
});
let manager = JoyConManager::get_instance();
let devices = {
let lock = manager.lock();
match lock {
Ok(manager) => manager.new_devices(),
Err(_) => unreachable!(),
}
};
devices.iter()
.try_for_each::<_, JoyConResult<()>>(|d| {
let driver = SimpleJoyConDriver::new(&d)?;
let standard_full_mode = StandardFullMode::new(driver)?;
let tx = tx.clone();
std::thread::spawn( move || {
loop {
match standard_full_mode.read_input_report() {
Ok(report) => {
tx.send(report).unwrap()
}
Err(JoyConError::Disconnected) => {
println!("Disconnected");
return;
}
Err(a) => {
dbg!(a);
return;
}
};
}
});
Ok(())
})?;
Ok(())
}
Program output and stacktrace:
[src\main.rs:45] a = HidApiError(
HidApiError {
message: "The device is not connected.",
},
)
thread '<unnamed>' panicked at 'internal error: entered unreachable code', C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\joycon-rs-0.6.1\src\joycon\manager.rs:219:30
stack backtrace:
0: 0x7ff6bbaa36fe - std::backtrace_rs::backtrace::dbghelp::trace
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\..\..\backtrace\src\backtrace\dbghelp.rs:98
1: 0x7ff6bbaa36fe - std::backtrace_rs::backtrace::trace_unsynchronized
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
2: 0x7ff6bbaa36fe - std::sys_common::backtrace::_print_fmt
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\sys_common\backtrace.rs:67
3: 0x7ff6bbaa36fe - std::sys_common::backtrace::_print::impl$0::fmt
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\sys_common\backtrace.rs:46
4: 0x7ff6bbab361a - core::fmt::write
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\core\src\fmt\mod.rs:1150
5: 0x7ff6bbaa1098 - std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\io\mod.rs:1667
6: 0x7ff6bbaa5b56 - std::sys_common::backtrace::_print
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\sys_common\backtrace.rs:49
7: 0x7ff6bbaa5b56 - std::sys_common::backtrace::print
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\sys_common\backtrace.rs:36
8: 0x7ff6bbaa5b56 - std::panicking::default_hook::closure$1
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\panicking.rs:210
9: 0x7ff6bbaa5644 - std::panicking::default_hook
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\panicking.rs:227
10: 0x7ff6bbaa61b5 - std::panicking::rust_panic_with_hook
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\panicking.rs:624
11: 0x7ff6bbaa5d6f - std::panicking::begin_panic_handler::closure$0
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\panicking.rs:519
12: 0x7ff6bbaa4047 - std::sys_common::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure$0,never$>
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\sys_common\backtrace.rs:141
13: 0x7ff6bbaa5cf9 - std::panicking::begin_panic_handler
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\panicking.rs:517
14: 0x7ff6bbaba400 - core::panicking::panic_fmt
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\core\src\panicking.rs:101
15: 0x7ff6bbaba34c - core::panicking::panic
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\core\src\panicking.rs:50
16: 0x7ff6bba45268 - joycon_rs::joycon::manager::impl$0::scan::closure$7
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\joycon-rs-0.6.1\src\joycon\manager.rs:219
17: 0x7ff6bba4241d - core::iter::traits::iterator::Iterator::for_each::call::closure$0<ref$<ref$<joycon_rs::joycon::manager::JoyConSerialNumber> >,joycon_rs::joycon::manager::impl$0::scan::closure$7>
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\core\src\iter\traits\iterator.rs:730
18: 0x7ff6bba68e62 - core::iter::traits::iterator::Iterator::fold<std::collections::hash::set::Iter<ref$<joycon_rs::joycon::manager::JoyConSerialNumber> >,tuple$<>,core::iter::traits::iterator::Iterator::for_each::call::closure$0>
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\core\src\iter\traits\iterator.rs:2170
19: 0x7ff6bba690d9 - core::iter::traits::iterator::Iterator::for_each<std::collections::hash::set::Iter<ref$<joycon_rs::joycon::manager::JoyConSerialNumber> >,joycon_rs::joycon::manager::impl$0::scan::closure$7>
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\core\src\iter\traits\iterator.rs:733
20: 0x7ff6bba44723 - joycon_rs::joycon::manager::JoyConManager::scan
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\joycon-rs-0.6.1\src\joycon\manager.rs:201
21: 0x7ff6bba43ee4 - joycon_rs::joycon::manager::impl$0::with_interval::closure$1
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\joycon-rs-0.6.1\src\joycon\manager.rs:93
22: 0x7ff6bba5e4fa - std::sys_common::backtrace::__rust_begin_short_backtrace<joycon_rs::joycon::manager::impl$0::with_interval::closure$1,tuple$<> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\std\src\sys_common\backtrace.rs:125
23: 0x7ff6bba53c28 - std::thread::impl$0::spawn_unchecked::closure$0::closure$0<joycon_rs::joycon::manager::impl$0::with_interval::closure$1,tuple$<> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\std\src\thread\mod.rs:481
24: 0x7ff6bba5c588 - core::panic::unwind_safe::impl$23::call_once<tuple$<>,std::thread::impl$0::spawn_unchecked::closure$0::closure$0>
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\core\src\panic\unwind_safe.rs:271
25: 0x7ff6bba6e708 - std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>,tuple$<> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\std\src\panicking.rs:403
26: 0x7ff6bba6f9c3 - crossbeam_channel::context::impl$2::clone
27: 0x7ff6bba6e649 - std::panicking::try<tuple$<>,core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\std\src\panicking.rs:367
28: 0x7ff6bba62a88 - std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked::closure$0::closure$0>,tuple$<> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\std\src\panic.rs:129
29: 0x7ff6bba53a8f - std::thread::impl$0::spawn_unchecked::closure$0<joycon_rs::joycon::manager::impl$0::with_interval::closure$1,tuple$<> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\std\src\thread\mod.rs:480
30: 0x7ff6bba53fee - core::ops::function::FnOnce::call_once<std::thread::impl$0::spawn_unchecked::closure$0,tuple$<> >
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\core\src\ops\function.rs:227
31: 0x7ff6bbaa7cdc - alloc::boxed::impl$44::call_once
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\alloc\src\boxed.rs:1636
32: 0x7ff6bbaa7cdc - alloc::boxed::impl$44::call_once
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\alloc\src\boxed.rs:1636
33: 0x7ff6bbaa7cdc - std::sys::windows::thread::impl$0::new::thread_start
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\sys\windows\thread.rs:58
34: 0x7ffcaf2c7034 - BaseThreadInitThunk
35: 0x7ffcb0202651 - RtlUserThreadStart
JoyCon | ProCon | |
---|---|---|
Behavior in simple HID mode | Push reports every putton and stick operation | 120Hz? |
Default input mode | None? | Simple HID mode |
Due to the effect of hidapi's Issue, hidapi-rs can't open multiple JoyCons on macOS. So, I forked hidapi-rs and use it with hidapi's Fork which fixes the bug. I need to publish this forked hidapi-rs in crate.io.
HidDevice::read_timeout()
HidDevice::set_blocking_mode()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.