1
+ // --------------------------------------------//
2
+ // HID-Button-Micro V1.0 //
3
+ // (c) Alexander Feuster 2024 //
4
+ // http://www.github.com/feuster/HID-Button //
5
+ // //
6
+ // powered by coffee //
7
+ // //
8
+ // ( ( //
9
+ // ) ) //
10
+ // .______. //
11
+ // | | //
12
+ // | | //
13
+ // |______| //
14
+ // \______/ //
15
+ // //
16
+ // --------------------------------------------//
17
+
18
+ // defines
19
+ #define enable_reboot // enabled reboot on maximum duration button press else credential pair 3 is typed
20
+ #define enable_german_layout // define german keyboard layout, if disabled US keyboard layout will be used
21
+
22
+ // includes
23
+ #include " Credentials.h" // header file with stored USER|PASSWORD credentials
24
+ #include < Keyboard.h> // library for emulating a HID keyboard
25
+ #include " Bounce2.h" // library for handling the button hardware bouncing
26
+
27
+ // / -----------------------------------------------------------------------------------------------------------------------
28
+ // / do not change code behind this line if not needed !!!
29
+ // / -----------------------------------------------------------------------------------------------------------------------
30
+
31
+ // / -----------------------------------------------------------------------------------------------------------------------
32
+ // / hardware & software definitions
33
+ // / -----------------------------------------------------------------------------------------------------------------------
34
+ // input pin for pushbutton (other pin with according wiring change)
35
+ const int buttonPin = A0;
36
+
37
+ // reset pin for hardware reset trigger (other pin with according wiring change)
38
+ #ifdef enable_reboot
39
+ const int resetPin = A1;
40
+ #endif
41
+
42
+ // first run
43
+ bool firstRun = true ;
44
+
45
+ // state of the builtin LED for blinking
46
+ int previousLedState = HIGH;
47
+
48
+ // time to define a long button press in ms
49
+ int longPressTimeSpan = 1000 ;
50
+
51
+ // time to define a maximum duration button press in ms (must be longer than longPressTimeSpan)
52
+ #ifdef enable_reboot
53
+ int maxPressTimeSpan = 5000 ; // used longer timespan for the reboot to prevent unwanted trigger
54
+ #else
55
+ int maxPressTimeSpan = 3000 ; // use shorter timespan for typing the credential pair 2
56
+ #endif
57
+
58
+ // create a Bounce2::Button object
59
+ Bounce2::Button button = Bounce2::Button();
60
+
61
+ // / -----------------------------------------------------------------------------------------------------------------------
62
+ // / start the hardware initialization
63
+ // / -----------------------------------------------------------------------------------------------------------------------
64
+ void setup () {
65
+ #ifdef enable_reboot
66
+ // configure the reset pin as output with default HIGH
67
+ digitalWrite (resetPin, HIGH);
68
+ pinMode (resetPin, OUTPUT);
69
+ #endif
70
+
71
+ // configure the pushbutton pin as input with internal pullup resistor
72
+ pinMode (buttonPin, INPUT_PULLUP);
73
+
74
+ // configure the builtin LED pin as output since the Micro does not blink without
75
+ digitalWrite (LED_BUILTIN, LOW);
76
+ pinMode (LED_BUILTIN, OUTPUT);
77
+
78
+ // Bounce2::Button configuration
79
+ button.attach (buttonPin, INPUT_PULLUP);
80
+ button.interval (5 );
81
+ button.setPressedState (LOW);
82
+
83
+ // initialize control over the keyboard:
84
+ Keyboard.begin ();
85
+ }
86
+
87
+ // / -----------------------------------------------------------------------------------------------------------------------
88
+ // / program loop
89
+ // / -----------------------------------------------------------------------------------------------------------------------
90
+ void loop () {
91
+ // wait some time on first run, to give hardware time to initialize and blink the builtin LED as start confirmation
92
+ if (firstRun)
93
+ {
94
+ firstRun = false ;
95
+ for (int i = 0 ; i < 20 ; i++)
96
+ {
97
+ blink (100 );
98
+ }
99
+ }
100
+
101
+ // read the pushbutton state once per loop
102
+ button.update ();
103
+
104
+ // validate if button was pressed short
105
+ if (button.released () && button.previousDuration () < longPressTimeSpan)
106
+ {
107
+ // type login credentials pair 1
108
+ Type (USER1, PASSWORD1);
109
+ }
110
+ // validate if button was pressed long
111
+ else if (button.released () && button.previousDuration () > longPressTimeSpan && button.previousDuration () < maxPressTimeSpan)
112
+ {
113
+ // type login credentials pair 2
114
+ Type (USER2, PASSWORD2);
115
+ }
116
+ // validate if button was pressed over the maximal time within a small timespan window to prevent unwanted repeats
117
+ else if (button.isPressed () && button.currentDuration () > maxPressTimeSpan && button.currentDuration () < maxPressTimeSpan + 25 )
118
+ {
119
+ #ifdef enable_reboot
120
+ // blink as signalization for reboot
121
+ for (int i = 0 ; i < 10 ; i++)
122
+ {
123
+ blink (100 );
124
+ }
125
+ digitalWrite (LED_BUILTIN, previousLedState);
126
+
127
+ // execute reboot
128
+ reboot ();
129
+ #else
130
+ // type login credentials pair 3
131
+ Type (USER3, PASSWORD3);
132
+ #endif
133
+ }
134
+
135
+ // keep alive
136
+ delay (25 );
137
+
138
+ // /program loop ends here and will repeat now in a new cycle
139
+ }
140
+
141
+ // / -----------------------------------------------------------------------------------------------------------------------
142
+ // / set the keyboard layout
143
+ // / -----------------------------------------------------------------------------------------------------------------------
144
+ void KeyBoardBegin ()
145
+ {
146
+ #ifdef enable_german_layout
147
+ Keyboard.begin (KeyboardLayout_de_DE);
148
+ #else
149
+ Keyboard.begin (KeyboardLayout_en_US);
150
+ #endif
151
+ }
152
+
153
+ // / -----------------------------------------------------------------------------------------------------------------------
154
+ // / type the desired user credentials as USB HID keyboard
155
+ // / -----------------------------------------------------------------------------------------------------------------------
156
+ void Type (char User[], char Password[])
157
+ {
158
+ // turn the builtin LED on while login is typed
159
+ digitalWrite (LED_BUILTIN, HIGH);
160
+
161
+ // type login credentials pair or only the password if user is left empty in the credentials
162
+ if (User[0 ] != 0 )
163
+ {
164
+ TypeInSingleChars (User);
165
+ sendKeyStroke (KEY_TAB); // switches from the user input field to the password input field (should work for 99% of login masks)
166
+ }
167
+ TypeInSingleChars (Password);
168
+ sendKeyStroke (KEY_RETURN); // confirms login input
169
+
170
+ // clear potential write error
171
+ if (Keyboard.getWriteError () != 0 )
172
+ Keyboard.clearWriteError ();
173
+
174
+ // turn the builtin LED off after login has been typed
175
+ digitalWrite (LED_BUILTIN, LOW);
176
+ }
177
+
178
+ // / -----------------------------------------------------------------------------------------------------------------------
179
+ // / print a longer text as single chars
180
+ // / remark: this should prevent freezing when typing longer texts
181
+ // / -----------------------------------------------------------------------------------------------------------------------
182
+ void TypeInSingleChars (char Text[])
183
+ {
184
+ // split text array in single chars and type char
185
+ KeyBoardBegin ();
186
+ for (byte i = 0 ; Text[i] != 0 ; i++)
187
+ {
188
+ Keyboard.print (Text[i]);
189
+ // delay should prevent freezing when typing longer texts
190
+ delay (10 );
191
+ }
192
+ Keyboard.end ();
193
+ }
194
+
195
+ // / -----------------------------------------------------------------------------------------------------------------------
196
+ // / sendKeyStroke is used as wrapper to add a keep alive delay
197
+ // / -----------------------------------------------------------------------------------------------------------------------
198
+ void sendKeyStroke (uint8_t key)
199
+ {
200
+ // press single key and release
201
+ KeyBoardBegin ();
202
+ Keyboard.press (key);
203
+ Keyboard.releaseAll ();
204
+ delay (50 );
205
+ Keyboard.end ();
206
+ }
207
+
208
+ // / -----------------------------------------------------------------------------------------------------------------------
209
+ // / blink builtin LED
210
+ // / -----------------------------------------------------------------------------------------------------------------------
211
+ void blink (long milli)
212
+ {
213
+ digitalWrite (LED_BUILTIN, previousLedState);
214
+ previousLedState = !previousLedState;
215
+ delay (milli);
216
+ }
217
+
218
+ #ifdef enable_reboot
219
+ // / -----------------------------------------------------------------------------------------------------------------------
220
+ // / reboot via RESET pin low (needs wiring Arduino RESET pin to IO pin which is used as trigger)
221
+ // / -----------------------------------------------------------------------------------------------------------------------
222
+ void reboot ()
223
+ {
224
+ digitalWrite (resetPin, LOW);
225
+ }
226
+ #endif
0 commit comments