# Read Joystick from Julia

**URL:** <https://discourse.julialang.org/t/read-joystick-from-julia/81325>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 19, 2022, 6:59pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325 "2022-05-19T18:59:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2022, 6:59pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/1 "2022-05-19T18:59:02Z")

</div>

Hello,

I would like to read a joystick on Linux to control my kite simulator (see: [GitHub - aenarete/KiteViewers.jl: 3D viewer for airborne wind energy systems](https://github.com/aenarete/KiteViewers.jl) ). The following test on the command line works:

```julia
jstest --normal /dev/input/js0
Driver version is 2.1.0.
Joystick (Logitech Extreme 3D pro) has 6 axes (X, Y, Rz, Throttle, Hat0X, Hat0Y)
and 12 buttons (Trigger, ThumbBtn, ThumbBtn2, TopBtn, TopBtn2, PinkieBtn, BaseBtn, BaseBtn2, BaseBtn3, BaseBtn4, BaseBtn5, BaseBtn6).
Testing ... (interrupt to exit)
Axes: 0: 0 1: 0 2: 0 3: 0 4: 0 5: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off 

```

But how can I access the values from Julia?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 19, 2022, 8:45pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/2 "2022-05-19T20:45:31Z")

</div>

This C code looks straightforward to port to Julia: [https://gist.github.com/jasonwhite/c5b2048c15993d285130](https://gist.github.com/jasonwhite/c5b2048c15993d285130)

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2022, 9:54pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/3 "2022-05-19T21:54:39Z")

</div>

I give it a try…

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2022, 10:05pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/4 "2022-05-19T22:05:18Z")

</div>

How would you translate this to Julia:

```julia
size_t get_axis_count(int fd)
{
    __u8 axes;

    if (ioctl(fd, JSIOCGAXES, &axes) == -1)
        return 0;

    return axes;
}

```

I just need a starting point.

Update:  
Found this discussion: [Ccall() to ioctl - #17 by yuyichao](https://discourse.julialang.org/t/ccall-to-ioctl/6219/17)

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 19, 2022, 10:36pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/5 "2022-05-19T22:36:56Z")

</div>

I don’t know if there is a Julia wrapper for `ioctl` already, but you can always [`@ccall`](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/index.html) it. You can do something like this

```julia
function get_axis_count(fd::Cint)::Csize_t
    axes = Ref{UInt8}()
    if @ccall(ioctl(fd::Cint, JSIOCGAXES::Cint; axes::Ref{UInt8})::Cint) == -1
        return 0
    end
    return axes[]
end

```

(didn’t test it)

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2022, 11:13pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/6 "2022-05-19T23:13:35Z")

</div>

Nice. Now I need to find the value of JSIOCGAXES, which is defined as

```julia
#define JSIOCGAXES _IOR('j', 0x11, __u8) /* get number of axes */

```

see: [joystick.h - include/uapi/linux/joystick.h - Linux source code (v5.19.6) - Bootlin](https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/joystick.h#L57)

Any idea which Cint number this refers to?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 19, 2022, 11:26pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/7 "2022-05-19T23:26:56Z")

</div>

```nohighlight
% cat joystick.c
#include <linux/joystick.h>
#include <stdio.h>

int main(void) {
    printf("JSIOCGAXES = %d\n", JSIOCGAXES);
    return 0;
}
% cc joystick.c -o joystick
% ./joystick               
JSIOCGAXES = -2147390959

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2022, 11:37pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/8 "2022-05-19T23:37:57Z")

</div>

This code works:

```julia
const JSIOCGAXES=2147576337

function open_joystick(filename="/dev/input/js0")
   file = open(filename,"r+")
   Cint(fd(file))
end

function get_axis_count(fd::Cint)
    axes = Ref{UInt8}()
    if @ccall(ioctl(fd::Cint, JSIOCGAXES::Clong; axes::Ref{UInt8})::Cint) == -1
        return -1
    end
    Int64(axes[])
end

```

```julia
using Pkg
pkg"add https://github.com/ufechner7/Joystick.jl"

using Joystick
fd=open_joystick()
axis_count = get_axis_count(fd)
println(axis_count)

```

But why do I have a different value for JSIOCGAXES than you have?  
And is it correct to assume that the file descriptor is of type Cint, both on 64bit and 32bit systems?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2022, 11:52pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/9 "2022-05-19T23:52:05Z")

</div>

Feel free to fork my code and make a pull request: [https://github.com/ufechner7/Joystick.jl](https://github.com/ufechner7/Joystick.jl)

I will continue tomorrow.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 20, 2022, 12:51am UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/10 "2022-05-20T00:51:29Z")

</div>

I don’t know _why_ it’s different, I’m not familiar with Linux programming. What’s the output of this command for you?

```nohighlight
% echo '#include <linux/joystick.h>\nJSIOCGAXES' | cc -E - | tail -n1          
(((2U) << (((0 +8)+8)+14)) | ((('j')) << (0 +8)) | (((0x11)) << 0) | ((((sizeof(__u8)))) << ((0 +8)+8)))

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 20, 2022, 12:58am UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/11 "2022-05-20T00:58:04Z")

</div>

Wait, it’s the same number: `Int32(-2147390959)` _is_ the same as `UInt32(2147576337)`

```julia
julia> Int(reinterpret(UInt32, Int32(-2147390959)))
2147576337

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 20, 2022, 1:25am UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/12 "2022-05-20T01:25:24Z")

</div>

The correct type of JSIOCGAXES is Clong…

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 20, 2022, 1:33am UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/13 "2022-05-20T01:33:38Z")

</div>

So a signed integer. So you should use `-2147390959`, not `2147576337` (unless you convert the latter to unsigned). These integer literals are all signed as you’re writing them, so using the reinterpreted unsigned value is wrong.

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [May 20, 2022, 1:37am UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/14 "2022-05-20T01:37:09Z")

</div>

Thanks! Will give it a try

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 20, 2022, 4:23pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/15 "2022-05-20T16:23:59Z")

</div>

```julia
// gcc test.c -o test
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/joystick.h>

int main(int argc, char *argv[])
{
    printf("JSIOCGAXES: %lu\n", JSIOCGAXES);
    printf("JSIOCGBUTTONS: %lu\n", JSIOCGBUTTONS);
    return 0;
}

```

Output:

```julia
ufechner@TUD277255:~/repos/Joystick.jl/src$ ./test
JSIOCGAXES: 2147576337
JSIOCGBUTTONS: 2147576338

```

So the positive value is correct.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [May 20, 2022, 4:32pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/16 "2022-05-20T16:32:33Z")

</div>

You’re printing an unsigned value and getting a positive value… Again, the Julia literal `2147576337` is a _ **signed** _ value, which is completely different from the unsigned litearal value `0x80016a11`. `2147576337` doesn’t even fit in a `Int32`.

---

<div class="post-metadata">

**Author:** ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)\
**Post date:** [May 20, 2022, 6:43pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/17 "2022-05-20T18:43:52Z")

</div>

Did it and [summited a PR](https://github.com/ufechner7/Joystick.jl/pull/2). I don’t have a Joystick right now to check the implementation, and I didn’t add more test, but hope you find it useful.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 20, 2022, 8:02pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/18 "2022-05-20T20:02:21Z")

</div>

Thanks a lot! I merged your commit and fixed one typo, but your example does’t work. Something is missing:

```julia
julia> using Joystick
[Info: Precompiling Joystick [82f05805-4863-42dc-b1a7-0852bd62c632]

julia> axes = Joystick.JSAxis()
ERROR: MethodError: no method matching Tuple{Joystick.JSAxisState, Joystick.JSAxisState, Joystick.JSAxisState}()
Closest candidates are:
  (::Type{T})(::Tuple) where T<:Tuple at ~/packages/julias/julia-1.7/share/julia/base/tuple.jl:312
  (::Type{T})(::NamedTuple) where T<:Tuple at ~/packages/julias/julia-1.7/share/julia/base/namedtuple.jl:147
  (::Type{T})(::Any) where T<:Tuple at ~/packages/julias/julia-1.7/share/julia/base/tuple.jl:317
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

```

I mean, JSAxis is just a type without constructor:

```julia
struct JSAxisState
    x::Int16
    y::Int16
end

const JSAxis = NTuple{3, JSAxisState}

```

I think a constructor is missing, but I don’t know how to write a constructor for an NTuple. So far I only used structs.

Any idea?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 20, 2022, 8:25pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/19 "2022-05-20T20:25:05Z")

</div>

OK, this works:

```julia
using Joystick
jsaxes = ntuple(i->JSAxisState(0,0), 3)

```

So the example has no syntax error any more, but is still not yet working.

---

<div class="post-metadata">

**Author:** ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)\
**Post date:** [May 20, 2022, 9:52pm UTC](https://discourse.julialang.org/t/read-joystick-from-julia/81325/20 "2022-05-20T21:52:17Z")

</div>

Oh, I see. Maybe is the reading of events? Try [here](https://github.com/ufechner7/Joystick.jl/blob/main/src/Joystick.jl#L67) to change `all=true` (that is the default).

Also, what does the example do right now?

[Next page](https://discourse.julialang.org/t/read-joystick-from-julia/81325.md?page=2)
