Skip to content

Commit 1ccd79e

Browse files
committed
Updated Joystick2 and Joystick3 to support UNO R4 boards
1 parent 6d0dabd commit 1ccd79e

File tree

6 files changed

+225
-220
lines changed

6 files changed

+225
-220
lines changed

Joystick2/Joystick2.cpp

Lines changed: 111 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
Joystick2.cpp
33
4-
Copyright (c) 2015, Matthew Heironimus
4+
Copyright (c) 2015-2025 Matthew Heironimus
55
66
This library is free software; you can redistribute it and/or
77
modify it under the terms of the GNU Lesser General Public
@@ -27,95 +27,103 @@
2727
#define JOYSTICK_STATE_SIZE 4
2828

2929
static const uint8_t _hidReportDescriptor[] PROGMEM = {
30-
31-
// Joystick #1
32-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
33-
0x09, 0x04, // USAGE (Joystick)
34-
0xa1, 0x01, // COLLECTION (Application)
35-
0x85, JOYSTICK_REPORT_ID, // REPORT_ID (3)
36-
37-
// 16 Buttons
38-
0x05, 0x09, // USAGE_PAGE (Button)
39-
0x19, 0x01, // USAGE_MINIMUM (Button 1)
40-
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
41-
0x15, 0x00, // LOGICAL_MINIMUM (0)
42-
0x25, 0x01, // LOGICAL_MAXIMUM (1)
43-
0x75, 0x01, // REPORT_SIZE (1)
44-
0x95, 0x10, // REPORT_COUNT (16)
45-
0x55, 0x00, // UNIT_EXPONENT (0)
46-
0x65, 0x00, // UNIT (None)
47-
0x81, 0x02, // INPUT (Data,Var,Abs)
48-
49-
// X and Y Axis
50-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
51-
0x09, 0x01, // USAGE (Pointer)
52-
0x15, 0x81, // LOGICAL_MINIMUM (-127)
53-
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
54-
0xA1, 0x00, // COLLECTION (Physical)
55-
0x09, 0x30, // USAGE (x)
56-
0x09, 0x31, // USAGE (y)
57-
0x75, 0x08, // REPORT_SIZE (8)
58-
0x95, 0x02, // REPORT_COUNT (2)
59-
0x81, 0x02, // INPUT (Data,Var,Abs)
60-
0xc0, // END_COLLECTION
61-
0xc0, // END_COLLECTION
62-
63-
// Joystick #2
64-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
65-
0x09, 0x04, // USAGE (Joystick)
66-
0xa1, 0x01, // COLLECTION (Application)
67-
0x85, JOYSTICK2_REPORT_ID, // REPORT_ID (4)
68-
69-
// 16 Buttons
70-
0x05, 0x09, // USAGE_PAGE (Button)
71-
0x19, 0x01, // USAGE_MINIMUM (Button 1)
72-
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
73-
0x15, 0x00, // LOGICAL_MINIMUM (0)
74-
0x25, 0x01, // LOGICAL_MAXIMUM (1)
75-
0x75, 0x01, // REPORT_SIZE (1)
76-
0x95, 0x10, // REPORT_COUNT (16)
77-
0x55, 0x00, // UNIT_EXPONENT (0)
78-
0x65, 0x00, // UNIT (None)
79-
0x81, 0x02, // INPUT (Data,Var,Abs)
80-
81-
// X and Y Axis
82-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
83-
0x09, 0x01, // USAGE (Pointer)
84-
0x15, 0x81, // LOGICAL_MINIMUM (-127)
85-
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
86-
0xA1, 0x00, // COLLECTION (Physical)
87-
0x09, 0x30, // USAGE (x)
88-
0x09, 0x31, // USAGE (y)
89-
0x75, 0x08, // REPORT_SIZE (8)
90-
0x95, 0x02, // REPORT_COUNT (2)
91-
0x81, 0x02, // INPUT (Data,Var,Abs)
92-
0xc0, // END_COLLECTION
93-
0xc0 // END_COLLECTION
30+
31+
// Joystick #1
32+
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
33+
0x09, 0x04, // USAGE (Joystick)
34+
0xa1, 0x01, // COLLECTION (Application)
35+
0x85, JOYSTICK_REPORT_ID, // REPORT_ID (3)
36+
37+
// 16 Buttons
38+
0x05, 0x09, // USAGE_PAGE (Button)
39+
0x19, 0x01, // USAGE_MINIMUM (Button 1)
40+
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
41+
0x15, 0x00, // LOGICAL_MINIMUM (0)
42+
0x25, 0x01, // LOGICAL_MAXIMUM (1)
43+
0x75, 0x01, // REPORT_SIZE (1)
44+
0x95, 0x10, // REPORT_COUNT (16)
45+
0x55, 0x00, // UNIT_EXPONENT (0)
46+
0x65, 0x00, // UNIT (None)
47+
0x81, 0x02, // INPUT (Data,Var,Abs)
48+
49+
// X and Y Axis
50+
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
51+
0x09, 0x01, // USAGE (Pointer)
52+
0x15, 0x81, // LOGICAL_MINIMUM (-127)
53+
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
54+
0xA1, 0x00, // COLLECTION (Physical)
55+
0x09, 0x30, // USAGE (x)
56+
0x09, 0x31, // USAGE (y)
57+
0x75, 0x08, // REPORT_SIZE (8)
58+
0x95, 0x02, // REPORT_COUNT (2)
59+
0x81, 0x02, // INPUT (Data,Var,Abs)
60+
0xc0, // END_COLLECTION
61+
0xc0, // END_COLLECTION
62+
63+
// Joystick #2
64+
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
65+
0x09, 0x04, // USAGE (Joystick)
66+
0xa1, 0x01, // COLLECTION (Application)
67+
0x85, JOYSTICK2_REPORT_ID, // REPORT_ID (4)
68+
69+
// 16 Buttons
70+
0x05, 0x09, // USAGE_PAGE (Button)
71+
0x19, 0x01, // USAGE_MINIMUM (Button 1)
72+
0x29, 0x10, // USAGE_MAXIMUM (Button 16)
73+
0x15, 0x00, // LOGICAL_MINIMUM (0)
74+
0x25, 0x01, // LOGICAL_MAXIMUM (1)
75+
0x75, 0x01, // REPORT_SIZE (1)
76+
0x95, 0x10, // REPORT_COUNT (16)
77+
0x55, 0x00, // UNIT_EXPONENT (0)
78+
0x65, 0x00, // UNIT (None)
79+
0x81, 0x02, // INPUT (Data,Var,Abs)
80+
81+
// X and Y Axis
82+
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
83+
0x09, 0x01, // USAGE (Pointer)
84+
0x15, 0x81, // LOGICAL_MINIMUM (-127)
85+
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
86+
0xA1, 0x00, // COLLECTION (Physical)
87+
0x09, 0x30, // USAGE (x)
88+
0x09, 0x31, // USAGE (y)
89+
0x75, 0x08, // REPORT_SIZE (8)
90+
0x95, 0x02, // REPORT_COUNT (2)
91+
0x81, 0x02, // INPUT (Data,Var,Abs)
92+
0xc0, // END_COLLECTION
93+
0xc0 // END_COLLECTION
9494
};
9595

9696
Joystick_::Joystick_(uint8_t initJoystickId)
9797
{
98-
// Setup HID report structure
99-
static bool usbSetup = false;
100-
101-
if (!usbSetup)
102-
{
103-
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
104-
HID().AppendDescriptor(&node);
105-
usbSetup = true;
106-
}
98+
// Setup HID report structure
99+
static bool usbSetup = false;
100+
101+
if (!usbSetup)
102+
{
103+
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
104+
HID().AppendDescriptor(&node);
105+
usbSetup = true;
106+
}
107107

108-
// Initalize State
109-
joystickId = initJoystickId;
110-
xAxis = 0;
111-
yAxis = 0;
112-
buttons = 0;
108+
// Initialize State
109+
joystickId = initJoystickId;
110+
xAxis = 0;
111+
yAxis = 0;
112+
buttons = 0;
113113
}
114114

115115
void Joystick_::begin(bool initAutoSendState)
116116
{
117-
autoSendState = initAutoSendState;
118-
sendState();
117+
autoSendState = initAutoSendState;
118+
119+
#if defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_UNOR4_MINIMA)
120+
// Delay added for the UNO R4 boards. Not sure why this delay is required,
121+
// but the library will sometimes hang on the first call to sendState
122+
// without it.
123+
delay(2000);
124+
#endif
125+
126+
sendState();
119127
}
120128

121129
void Joystick_::end()
@@ -126,56 +134,56 @@ void Joystick_::setButton(uint8_t button, uint8_t value)
126134
{
127135
if (value == 0)
128136
{
129-
releaseButton(button);
137+
releaseButton(button);
130138
}
131139
else
132140
{
133-
pressButton(button);
141+
pressButton(button);
134142
}
135143
}
136144
void Joystick_::pressButton(uint8_t button)
137145
{
138-
bitSet(buttons, button);
139-
if (autoSendState) sendState();
146+
bitSet(buttons, button);
147+
if (autoSendState) sendState();
140148
}
141149
void Joystick_::releaseButton(uint8_t button)
142150
{
143-
bitClear(buttons, button);
144-
if (autoSendState) sendState();
151+
bitClear(buttons, button);
152+
if (autoSendState) sendState();
145153
}
146154

147155
void Joystick_::setXAxis(int8_t value)
148156
{
149-
xAxis = value;
150-
if (autoSendState) sendState();
157+
xAxis = value;
158+
if (autoSendState) sendState();
151159
}
152160
void Joystick_::setYAxis(int8_t value)
153161
{
154-
yAxis = value;
155-
if (autoSendState) sendState();
162+
yAxis = value;
163+
if (autoSendState) sendState();
156164
}
157165

158166
void Joystick_::sendState()
159167
{
160-
int8_t data[JOYSTICK_STATE_SIZE];
161-
uint16_t buttonTmp = buttons;
168+
int8_t data[JOYSTICK_STATE_SIZE];
169+
uint16_t buttonTmp = buttons;
162170

163-
// Split 16 bit button-state into 2 bytes
164-
data[0] = buttonTmp & 0xFF;
165-
buttonTmp >>= 8;
166-
data[1] = buttonTmp & 0xFF;
171+
// Split 16 bit button-state into 2 bytes
172+
data[0] = buttonTmp & 0xFF;
173+
buttonTmp >>= 8;
174+
data[1] = buttonTmp & 0xFF;
167175

168-
data[2] = xAxis;
169-
data[3] = yAxis;
176+
data[2] = xAxis;
177+
data[3] = yAxis;
170178

171-
// HID().SendReport(Report number, array of values in same order as HID descriptor, length)
172-
HID().SendReport(JOYSTICK_REPORT_ID + joystickId, data, JOYSTICK_STATE_SIZE);
179+
// HID().SendReport(Report number, array of values in same order as HID descriptor, length)
180+
HID().SendReport(JOYSTICK_REPORT_ID + joystickId, data, JOYSTICK_STATE_SIZE);
173181
}
174182

175183
Joystick_ Joystick[2] =
176184
{
177-
Joystick_(0),
178-
Joystick_(1)
185+
Joystick_(0),
186+
Joystick_(1)
179187
};
180188

181189
#endif

Joystick2/Joystick2.h

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
Joystick2.h
33
4-
Copyright (c) 2015, Matthew Heironimus
4+
Copyright (c) 2015-2025 Matthew Heironimus
55
66
This library is free software; you can redistribute it and/or
77
modify it under the terms of the GNU Lesser General Public
@@ -21,51 +21,46 @@
2121
#ifndef JOYSTICK_h
2222
#define JOYSTICK_h
2323

24-
#include "HID.h"
25-
26-
#if ARDUINO < 10606
27-
#error The Joystick2 library requires Arduino IDE 1.6.6 or greater. Please update your IDE.
24+
#if ARDUINO <= 10606
25+
#error The Joystick library requires Arduino IDE 1.6.7 or greater. Please update your IDE.
2826
#endif
2927

30-
#if ARDUINO > 10606
31-
#if !defined(USBCON)
32-
#error The Joystick2 library can only be used with a USB MCU (e.g. Arduino Leonardo, Arduino Micro, etc.).
33-
#endif
28+
#include "HID.h"
29+
30+
#if !(defined(USBCON) || defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_UNOR4_MINIMA))
31+
#error The Joystick library can only be used with a USB MCU (e.g. Arduino Leonardo, Arduino Micro, Arduino UNO R4, etc.).
3432
#endif
3533

3634
#if !defined(_USING_HID)
37-
3835
#warning "Using legacy HID core (non pluggable)"
39-
4036
#else
4137

42-
//================================================================================
4338
//================================================================================
4439
// Joystick (Gamepad)
4540

4641
class Joystick_
4742
{
4843
private:
49-
uint8_t joystickId;
50-
bool autoSendState;
51-
int8_t xAxis;
52-
int8_t yAxis;
53-
uint16_t buttons;
44+
uint8_t joystickId;
45+
bool autoSendState;
46+
int8_t xAxis;
47+
int8_t yAxis;
48+
uint16_t buttons;
5449

5550
public:
56-
Joystick_(uint8_t initJoystickId);
51+
Joystick_(uint8_t initJoystickId);
5752

58-
void begin(bool initAutoSendState = true);
59-
void end();
53+
void begin(bool initAutoSendState = true);
54+
void end();
6055

61-
void setXAxis(int8_t value);
62-
void setYAxis(int8_t value);
56+
void setXAxis(int8_t value);
57+
void setYAxis(int8_t value);
6358

64-
void setButton(uint8_t button, uint8_t value);
65-
void pressButton(uint8_t button);
66-
void releaseButton(uint8_t button);
59+
void setButton(uint8_t button, uint8_t value);
60+
void pressButton(uint8_t button);
61+
void releaseButton(uint8_t button);
6762

68-
void sendState();
63+
void sendState();
6964
};
7065
extern Joystick_ Joystick[2];
7166

Joystick2/examples/UsbJoystick2Test/UsbJoystick2Test.ino

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Program used to test the Dual Simple USB Joystick object
2-
// on the Arduino Leonardo or Arduino Micro.
2+
// on the Arduino Leonardo, Arduino Micro, or
3+
// Arduino UNO R4.
34
//
45
// Matthew Heironimus
5-
// 2015-04-05
66
//------------------------------------------------------------
77

88
#include "Joystick2.h"
@@ -149,4 +149,3 @@ void loop() {
149149
}
150150
}
151151
}
152-

0 commit comments

Comments
 (0)