Monday, 25 May 2020

USB HID Keyboard

https://www.xenoworld.org/?page_id=125

Description
I recently ordered the book Practical Arduino. It has lots of small neat Arduino projects, and one that really caught my eye; a virtual USB keyboard.
After testing the device while recording, it became clear that some reprogramming is needed. One should be able to just record, and not always send a Ctrl-Z (undo) command. To be updated. /XeNo-07.04.11
After spending a lot of time recording both albums and preproductions in Steinberg Cubase (from SX up to 5) I've grown tired of having to use the same keyboard shortcuts over and over (and over) again to record, stop, undo and relocate the locator (repeat x number of times until you have the take you want :P). I wanted a device to to that for me, preferably using a foot pedal. When you're playing guitars and you're really in the zone, it's frustrating and screws up the concentration having to move your hands back and forth from the guitar to the keyboard all the time.
I had a Behringer foot-pedal that came with a V-Amp 2. The pedal had two switches, and connected through a TRS (stereo) jack-plug. I wanted to use this pedal to start recording, stop recording and 'reset' Cubase for a new take.
Cubase 5
Circuit
The circuit for the USB-part itself is very simple; in addition toan Arduino you need three resistors, two zener diodes and a USB B-socket. The latter available from an electronics shop like for instance ELFA. I connected the outputs of button 1 and 2 on pins 6 and 7 on the Arduino, as well as the common ground to ground.
The USB circuit © Practical Arduino
BuildI used a bit of experiment board to make sort of an Arduino shield to plug the Arduino into. The enclosure I had at hand was a bit small and the mounting spacers inside weren't that great, so the shideld ended up a bit askew after mounting. No biggie. Here's the enclosure with and without the Arduino:
 
The TRS-connector:
Code
The essence in the code is that when button 1 (left on the pedal) is pressed, it sends Ctrl-Z (undo) , Numpad 0 (move locator to previous location) and Numpad * (record) in quick succession. Button 2 (right on the pedal) sends Space (stop/pause). I've also added some logics that Ctrl-Z will not be sent the first time since that usually means there is nothing to undo, as well as only being able to press any button once.
(I'm no programmer, so forgive me if there are any obvious errors/amateur mistakes)
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
/**
* Jon Ivar Larsen/XeNo - www.xenoworld.org - 2011
*
* Derived from this project
*/
 
// Requires the use of the "UsbKeyboard" library available from
#include "UsbKeyboard.h"
 
// Define the inputs to use for buttons
#define BUTTON_1 6
#define BUTTON_2 7
 
// Use the on-board LED as an activity display
int ledPin = 13;
 
// Variable for what button was last pressed
int previous = 2; //Set to 2 since Button 2 should not be allowed to be pressed first
 
// Variable to check if the Arduino/Keyboard was recently started/reset
bool recentlyStarted;
 
/**
* Configure button inputs and set up the USB connection to the host
*/
void setup()
{
 // Set up the activity display LED
 pinMode (ledPin, OUTPUT);
 digitalWrite (ledPin, LOW);
 
 // Set the button pins to inputs
 pinMode (BUTTON_1, INPUT);
 pinMode (BUTTON_2, INPUT);
 
 // Enable the CPU's internal 20k pull-up resistors on the button
 // inputs so they default to a "high" state
 digitalWrite (BUTTON_1, HIGH);
 digitalWrite (BUTTON_2, HIGH);
 
 // Disable timer0 since it can mess with the USB timing. Note that
 // this means some functions such as delay() will no longer work.
 TIMSK0&=!(1<<TOIE0);
 
 // Clear interrupts while performing time-critical operations
 cli();
 
 // Force re-enumeration so the host will detect us
 usbDeviceDisconnect();
 delayMs(250);
 usbDeviceConnect();
 
 // Set interrupts again
 sei();
 
 recentlyStarted = true;
}
 
void loop()
{
 UsbKeyboard.update();
 
 if (digitalRead(BUTTON_1) == LOW) {
 if (previous != 1) {
 if (recentlyStarted == false) { // If it is the first time button 1 is pressed,
                                 // it should not run Ctrl-Z or Numpad 0 (Ins)
 UsbKeyboard.sendKeyStroke(KEY_Z, MOD_CONTROL_LEFT); //Ctrl-Z
 UsbKeyboard.sendKeyStroke(98); //Numpad 0 (Ins)
 UsbKeyboard.sendKeyStroke(85); //Numpad *
 }
 if (recentlyStarted == true)  { // ...but only Numpad * (Cubase Record)
 UsbKeyboard.sendKeyStroke(85); //Numpad *
 recentlyStarted = false;
 }
 
 blinkLED();
 previous = 1;
 }
 }
 
 if (digitalRead(BUTTON_2) == LOW) {
 if (previous != 2) {
 UsbKeyboard.sendKeyStroke(KEY_SPACE);
 
 blinkLED();
 previous = 2;
 }
 }
 
}
 
/**
* Define our own delay function so that we don't have to rely on
* operation of timer0, the interrupt used by the internal delay()
*/
void delayMs(unsigned int ms)
{
 for (int i = 0; i < ms; i++) {
 delayMicroseconds(1000);
 }
}
 
/**
* Routine to blink the LED
*/
void blinkLED()
{
 digitalWrite(ledPin, HIGH);
 delayMs(250);
 digitalWrite(ledPin, LOW);
}
The finished build
Some pictures of the enclosure. The last one with an USB-cable and the footpedal connected.
 

No comments:

Post a Comment