-
Notifications
You must be signed in to change notification settings - Fork 0
/
controlboard.ino
175 lines (147 loc) · 4.75 KB
/
controlboard.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/**
* ############################## License Info ################################
* This file is part of ControlBoard <https://github.com/frc5024/controlboard>.
* Copyright (c) 2020 Raider Robotics.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* ############################## Program Info ################################
*
* Team 5024's Arduino-based DriverStation control board source code.
*
* This software is designed to run on an Arduino Leonardo. It will register
* itself with a host computer as a standard HID joystick. This joystick can be
* read by FRC DriverStation software, and can be used in FRC robot code with
* the help of Lib5K's frc.lib5k.interface.controlboard package.
*/
// Include needed headers
#include "Joystick.h"
// Constants
#define updatePeriodMS 20
// Create a HID Joystick interface class
Joystick_ Joystick;
/**
* Button data structure containing HID button id, button state, and if this
* state is new for the button
*/
typedef struct {
// HID ID for the button the produced this data
int HIDid;
// Current state of the button
bool state;
// Is this data new?
bool isNew;
} ButtonData;
class JoystickButton {
private:
// Digital pin to read from
int digitalPin;
// "Button" ID to write to on computer
int buttonId;
// Keep track of button state
bool lastState = false;
public:
/**
* Create a new JoystickButton
*
* @param digitalPin Arduino digital pin to read button data from
* @param buttonID HID button ID to write state to
*/
JoystickButton(int, int);
/**
* Initialize button I/O
*/
void init();
/**
* Get the un-filtered button state.
*
* @return Button state
*/
bool getRawButton();
/**
* Get button data
*
* @return Current button data
*/
ButtonData getButtonData();
};
JoystickButton::JoystickButton(int digitalPin, int buttonId) {
// Set local variables
this->digitalPin = digitalPin;
this->buttonId = buttonId;
}
void JoystickButton::init() {
// Set pin mode to pull up. More info about this feature can be found
// here: https://www.arduino.cc/en/Tutorial/InputPullupSerial
pinMode(this->digitalPin, INPUT_PULLUP);
}
bool JoystickButton::getRawButton() {
// The INPUT_PULLUP mode set for the pin will cause button states to be
// inverted. Using "!" will flip them to what we expect
return !(digitalRead(this->digitalPin) == 1);
}
ButtonData JoystickButton::getButtonData() {
// Alloc a ButtonData struct
ButtonData output;
// Fill output with state Info
output.HIDid = this->buttonId;
output.state = this->getRawButton();
output.isNew = true;
//(this->lastState != output.state);
// Set the last state for the button
this->lastState = output.isNew;
// Return the output
return output;
}
// Button mappings
// For the people who only know java, this is a quick way to make an array of
// objects in C++. It is equivalent to the following java code:
// JoystickButton[] buttons = new JoystickButton[]{ ... }
// The innter curly braces define the arguments passed to each object's
// constructor
JoystickButton buttons[] = {{2, 0}, {3, 1}, {4, 2}, {5, 3}, {6, 4},
{7, 5}, {8, 6}, {9, 7}, {10, 8}, {11, 9}};
// Count the number of buttons registered
const int buttonCount = (sizeof(buttons) / sizeof(buttons[0]));
/**
* Arduino setup function. All init code should go here
*/
void setup() {
// Init each button
for (int i = 0; i < buttonCount; i++) {
// Call button's init function
buttons[i].init();
}
// Init the Joystick library (passing false will disable auto-updates)
Joystick.begin(false);
}
/**
* Arduino loop function. This will loop
*/
void loop() {
// Read each button for new data
for (int i = 0; i < buttonCount; i++) {
// Get the button's current data
ButtonData data = buttons[i].getButtonData();
// Check if this data is new
if (data.isNew) {
// Push data
Joystick.setButton(data.HIDid, data.state);
}
}
// Push HID data to host computer
Joystick.sendState();
// Wait for the set period
delay(updatePeriodMS);
}