{"id":5579,"date":"2018-10-13T09:42:26","date_gmt":"2018-10-13T13:42:26","guid":{"rendered":"https:\/\/itp.nyu.edu\/physcomp\/?page_id=5579"},"modified":"2022-11-06T18:16:42","modified_gmt":"2022-11-06T23:16:42","slug":"lab-keyboard-control","status":"publish","type":"page","link":"https:\/\/itp.nyu.edu\/physcomp\/lab-keyboard-control\/","title":{"rendered":"Lab: Keyboard Control"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span>Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In this lab, you&#8217;ll build an alternative computer keyboard using any of the USB-native boards (Nano 33 IoT, the MKR series, the Due, the Leonardo, the Micro, and the Feather M0 series all fit this requirement). You&#8217;ll also learn some techniques for determining when a user takes a physical action. In the <a rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/digital-input-and-output-with-an-arduino\/\" target=\"_blank\">Digital Lab<\/a> and <a rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/analog-in-with-an-arduino\/\" target=\"_blank\">Analog Lab<\/a>, you learned how to read the input from a digital or analog input, but you didn&#8217;t learn how to interpret the stream of data as an event. There are a few everyday physical interactions that are fairly easy to pick out from a stream of data. You&#8217;ll see a few of them in this lab.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_Youll_Need_to_Know\"><\/span>What You\u2019ll Need to Know<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>To get the most out of this lab, you should be familiar with the following concepts. You can check how to do so in the links below:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a class=\"wikilink\" style=\"color: #37aad1;\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/digital-input-and-output-with-an-arduino\/\" target=\"_blank\">Digital Input with Arduino<\/a><\/li><li><a class=\"wikilink\" style=\"color: #37aad1;\" rel=\"noopener noreferrer\" href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/analog-in-with-an-arduino\/\" target=\"_blank\">Analog Input with Arduino<\/a><\/li><li>What is an&nbsp;<a class=\"wikilink\" style=\"color: #37aad1;\" rel=\"noopener noreferrer\" href=\"http:\/\/arduino.cc\/en\/Reference\/Libraries\" target=\"_blank\">Arduino Library<\/a><\/li><li>You may also want to try the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/lab-sensor-change-detection\/\">Sensor Change Detection Lab<\/a>&nbsp;before this one.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Things_Youll_Need\"><\/span>Things You\u2019ll Need<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Figures 1-5 show the parts you\u2019ll need for this exercise. Click on any image for a larger view.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-thumbnail\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/breadboard_short-e1532116106284.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/breadboard_short-e1532116106284-150x150.jpg\" alt=\"A short solderless breadboard with two rows of holes along each side. There are no components mounted on the board.\" class=\"wp-image-788\"\/><\/a><figcaption>Figure 1. A solderless breadboard.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image wp-image-5921\"><figure class=\"alignleft\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-arduino-nano-33-iot-150x150.jpg\" alt=\"Photo of an Arduino Nano 33 IoT module. The USB connector is at the top of the image, and the physical pins are numbered in a U-shape from top left to bottom left, then from bottom right to top right.\" class=\"wp-image-5921\"\/><figcaption>Figure 2. Arduino Nano 33 IoT<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-thumbnail\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/hookup_wire2.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/hookup_wire2-150x150.jpg\" alt=\"Three 22AWG solid core hookup wires. Each is about 6cm long. The top one is black; the middle one is red; the bottom one is blue. All three have stripped ends, approximately 4 to 5mm on each end.\" class=\"wp-image-1203\"\/><\/a><figcaption>Figure 3. 22AWG solid core hookup wires.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/resistors1.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/resistors1-150x150.jpg\" alt=\"Resistors. Shown here are 220-ohm resistors. You can tell this because they have two red and one brown band, followed by a gold band.\" class=\"wp-image-798\"\/><\/a><figcaption>Figure 4. Resistors. Shown here are 220-ohm resistors.&nbsp; For this exercise, you&#8217;ll need 10-kilohm resistors (10K resistors are brown-black-orange. You&#8217;ll also need 1 220-ohm resistor. For more, see this <a href=\"https:\/\/www.allaboutcircuits.com\/tools\/resistor-color-code-calculator\/\">resistor color calculator<\/a>)<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image wp-image-5918\"><figure class=\"alignleft size-thumbnail\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-pushbuttons-150x150.jpg\" alt=\"Photo of four breadboard-mounted pushbuttons\" class=\"wp-image-5918\"\/><figcaption>Figure 5. Pushbuttons.&nbsp; For this exercise you&#8217;ll need five pushbuttons or any five momentary switches<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image wp-image-5911\"><figure class=\"alignleft size-thumbnail\"><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/pcomp-kit-f2019-leds-150x150.jpg\" alt=\"Photo of a handful of LEDs\" class=\"wp-image-5911\"\/><figcaption>Figure 6. LEDs. The long leg goes to voltage and the short leg goes to ground<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"About_Keyboard_control\"><\/span>About Keyboard control<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><strong>NOTE: The sketches contained in this lab will cause the microcontroller to take control of your keyboard. Make sure they&#8217;re working properly before you add the keyboard commands.<\/strong> The example doesn&#8217;t introduce the Keyboard commands until the end of the lab. Instead, messages are printed to the serial monitor to tell you what should happen. When you&#8217;ve run this and seen the serial messages occurring when you think they should, then you can add the mouse commands safely.<\/p>\n\n\n\n<p>The circuit diagrams below show an Arduino Leonardo, but you can use any USB-capable board that you wish.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Note_on_Mouse_Keyboard_and_Serial_Ports\"><\/span><a href=\"https:\/\/github.com\/tigoe\/ArduinoGeneralExamples\/tree\/master\/KeyboardMouseExamples#note-on-mouse-keyboard-and-serial-ports\"><\/a>Note on Mouse, Keyboard, and Serial Ports<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The Mouse and Keyboard libraries on the SAMD boards (MKRZero, MKR1xxx, Nano 33IoT) have an unusual behavior: using them changes the serial port enumeration. When you include the Keyboard library in a sketch, your board&#8217;s serial port number will change. For example, on MacOS, if the port number is&nbsp;<code>\/dev\/cu.usbmodem14101<\/code>, then adding the Keyboard library will change it to&nbsp;<code>\/dev\/cu.usbmodem14102<\/code>. Removing the Keyboard library will change it back to&nbsp;<code>\/dev\/cu.usbmodem14101<\/code>. Similarly, if you double-tap the reset button to put the board in bootloader mode, the serial port will re-enumerate to its original number.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Windows_and_HID_Devices\"><\/span>Windows and HID Devices<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You may have trouble getting these sketches to work on Windows.  On Windows, the default Arduino drivers must be uninstalled so the system can recognize the Arduino as both serial device and HID device. Read <a href=\"https:\/\/github.com\/arduino\/ArduinoCore-samd\/releases\/tag\/1.8.2\">this issue<\/a> and follow the instructions there. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Recovering_From_a_Runaway_HID_Mouse_or_Keyboard_Sketch\"><\/span><a href=\"https:\/\/github.com\/tigoe\/ArduinoGeneralExamples\/tree\/master\/KeyboardMouseExamples#recovering-from-a-runaway-hid-sketch\"><\/a>Recovering From a Runaway HID (Mouse or Keyboard) Sketch<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Programs which control your keyboard and mouse can make development difficult or impossible if you make a mistake in your code. If you create a mouse or keyboard example that doesn&#8217;t do what you want it to, and you need to reprogram your microcontroller to stop the program, do this:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Open_a_new_blank_sketch\"><\/span><a href=\"https:\/\/github.com\/tigoe\/ArduinoGeneralExamples\/tree\/master\/KeyboardMouseExamples#open-a-new-blank-sketch\"><\/a>Open a new blank sketch.<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>This sketch is your recovery:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n\n}\nvoid loop() {\n\n}\n<\/pre><\/div>\n\n\n<p>Programming the board with this blank sketch removes your mistaken sketch and gives you control again. To do this, however, you need the current sketch to stop running. So:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Put_the_microcontroller_in_bootloader_mode_and_upload_the_blank_sketch\"><\/span><a href=\"https:\/\/github.com\/tigoe\/ArduinoGeneralExamples\/tree\/master\/KeyboardMouseExamples#put-the-microcontroller-in-bootloader-mode-and-upload-the-blank-sketch\"><\/a>Put the microcontroller in bootloader mode and upload the blank sketch<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>On the SAMD boards, you can do this by double-tapping the reset button. The on-board LED will begin glowing, and the bootloader will start so that you get a serial port enumeration, but the sketch won&#8217;t run. On the Leonardo and other 32U4-based boards, hold the reset down until you&#8217;ve given the upload command. The 32U4 bootloader will take a few seconds before it starts the sketch, so the uploader can take command and load your blank sketch.<\/p>\n\n\n\n<p>Once you&#8217;ve got the blank sketch on the board, review the logic of your mistaken Keyboard or Mouse sketch and find the problem before uploading again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Prepare_the_breadboard\"><\/span>Prepare the breadboard<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/vimeo.com\/86534049#t=1m41s\" target=\"_blank\">Connect power and ground on the breadboard<\/a> to power and ground from the microcontroller. On the Arduino module, use the 5V and any of the ground connections as shown below in Figure 7. If using the Arduino Nano connect the 3.3V and ground pins according to Figure 8.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/arduino_leonardo_and_breadboard_bb.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"231\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/arduino_leonardo_and_breadboard_bb-300x231.png\" alt=\"An Arduino Leonardo on the left connected to a solderless breadboard, right. The Leonardo's 5V output hole is connected to the red column of holes on the far left side of the breadboard. The Leonardo's ground hole is connected to the blue column on the left of the board. The red and blue columns on the left of the breadboard are connected to the red and blue columns on the right side of the breadboard with red and black wires, respectively. These columns on the side of a breadboard are commonly called the buses. The red line is the voltage bus, and the black or blue line is the ground bus.\" class=\"wp-image-1883\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/arduino_leonardo_and_breadboard_bb-300x231.png 300w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/arduino_leonardo_and_breadboard_bb-1024x788.png 1024w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/arduino_leonardo_and_breadboard_bb.png 1200w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/a><figcaption><br><a name=\"arduino_leonardo_and_breadboard_bb\"><\/a> Figure 7. An Arduino Leonardo on the left connected to a solderless breadboard, right.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/LabTemplateNanoShort_bb.png\" alt=\"Arduino Nano on a breadboard.\" class=\"wp-image-5903\" width=\"228\" height=\"359\"\/><\/figure><\/div>\n\n\n\n<p>Figure 8. Breadboard view of an Arduino Nano connected to a breadboard. The +3.3 volts and ground pins of the Arduino are connected by red and black wires, respectively, to the left side rows of the breadboard. +3.3 volts is connected to the left outer side row (the voltage bus) and ground is connected to the left inner side row (the ground bus). The side rows on the left are connected to the side rows on the right using red and black wires, respectively, creating a voltage bus and a ground bus on both sides of the board.<\/p>\n\n\n\n<p><em>Made with <a href=\"http:\/\/fritzing.org\/home\/\">Fritzing<\/a><\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Add_Several_Pushbuttons\"><\/span>Add Several Pushbuttons<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Attach pushbuttons to digital pin 2 through 6 as shown below in Figure 9. For Arduino Nano connections, see Figure 10. For the schematic view, see Figure 11. Connect one side of each pushbutton to voltage, and the other side of the pushbuttons to 10-kilohm resistors. Connect the other end of each resistor to ground. Connect the junction where each pushbutton and resistor meet to a digital pin, using pins 2 through 6. (For more on this digital input circuit, see the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/digital-input-and-output-with-an-arduino\/\">Digital Input Lab<\/a>).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_no_LED_bb.png\"><img loading=\"lazy\" decoding=\"async\" width=\"310\" height=\"256\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_no_LED_bb.png\" alt=\"Breadboard drawing of an Arduino Leonardo connected to five pushbuttons. The pushbuttons straddle the center divide of the breadboard in rows 4-6, 9-11, 14-16, 19-21, and 24-26, respectively. 10-kilohm resistors straddle the center divide in rows 7, 12, 17, and 22, respectively. Each resistor's row on the left center side is connected to the row above it with a wire, thus connecting the pushbuttons and the resistors. Each resistor's row on the right center side is connected to the right side ground bus with a black wire. Each pushbutton's upper row (that is, rows 4, 9, 14, 19, and 23) on the right center side is connected to the right side voltage bus with a red wire. The junction rows, that is, rows 6, 11, 16, 21, and 26, are connected to digital inputs 2 through 6 on the Leonardo, respectively, with blue wires\" class=\"wp-image-5598\"\/><\/a><figcaption><a name=\"KeyboardLabButtons_no_LED_bb\"><\/a>Figure 9. Breadboard drawing of an Arduino Leonardo connected to five pushbuttons at the Leonardo&#8217;s digital pins 2-6.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image wp-image-6202\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/LabMouseKeyNano_bb-e1566067560999.png\" alt=\"Breadboard drawing of an Arduino Nano connected to five pushbuttons. The pushbuttons straddle the center divide of the breadboard in rows 20-22, 25-27, 30-32, 35-37, and 40-42, respectively. 10-kilohm resistors connect the left side of each pushbutton to the breadboard's GND bus at rows 22, 27, 32, 37, 42. Blue wires connect the right side of each pushbutton at pins 22, 27, 32, 37, 42 to the arduino digital pins 2-6 respectively. Red wires connect the left side of each pushbutton to the voltage bus at rows 20, 25, 30, 35, 40\" class=\"wp-image-6202\" width=\"284\" height=\"886\"\/><figcaption>Figure 10. Breadboard drawing of an Arduino Nano connected to five pushbuttons at the Nano&#8217;s digital pins 2-6.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_no_LED_schem.png\"><img loading=\"lazy\" decoding=\"async\" width=\"747\" height=\"495\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_no_LED_schem.png\" alt=\"Schematic drawing of five pushbuttons attached to an Arduino Leonardo. The pushbuttons is attached to digital pin 2 through 5 on one side, and to +5 volts on the other. There is also a 10-kilohm resistor attached to each of digital pins 2 through 6. The other side of each resistor is attached to ground.\" class=\"wp-image-5599\"\/><\/a><figcaption>Figure 11. Schematic drawing of five pushbuttons attached to an Arduino Leonardo.<\/figcaption><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Add_an_LED\"><\/span>Add an LED<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Add an LED and 220-ohm resistor on pin 13 as shown below in Figure 12. For Arduino Nano see Figure 13. For the schematic view, see Figure 14. You&#8217;ll use this to keep track of the state of the keyboard control.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_bb.png\"><img loading=\"lazy\" decoding=\"async\" width=\"310\" height=\"295\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_bb.png\" alt=\"Breadboard drawing of an Arduino Leonardo connected to five pushbuttons. The pushbuttons straddle the center divide of the breadboard in rows 4-6, 9-11, 14-16, 19-21, and 24-26, respectively. 10-kilohm resistors straddle the center divide in rows 7, 12, 17, and 22, respectively. Each resistor's row on the left center side is connected to the row above it with a wire, thus connecting the pushbuttons and the resistors. Each resistor's row on the right center side is connected to the right side ground bus with a black wire. Each pushbutton's upper row (that is, rows 4, 9, 14, 19, and 23) on the right center side is connected to the right side voltage bus with a red wire. The junction rows, that is, rows 6, 11, 16, 21, and 26, are connected to digital inputs 2 through 6 on the Leonardo, respectively, with blue wires. A 220-ohm resistor is connected to pin 13 of the board, and straddles the center divide of the breadboard in row 1. The anode of an LED is attached to the other side of the resistor, and the cathode is attached to the right side ground bus.\" class=\"wp-image-5600\"\/><\/a><figcaption><a name=\"KeyboardLabButtons_bb\"><\/a>Figure 12: Breadboard drawing of an Arduino Leonardo connected to five pushbuttons at digital pins 2-6. The Leonardo&#8217;s digital pin 13 is connected to a 220 ohm resistor in series with an LED.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image wp-image-6203\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/LabMouseKeyNanoLED_bb.png\" alt=\"Breadboard drawing of an Arduino Nano connected to five pushbuttons. The pushbuttons straddle the center divide of the breadboard in rows 20-22, 25-27, 30-32, 35-37, and 40-42, respectively. 10-kilohm resistors connect the left side of each pushbutton to the breadboard's GND bus at rows 22, 27, 32, 37, 42. Blue wires connect the right side of each pushbutton at pins 22, 27, 32, 37, 42 to the arduino digital pins 2-6 respectively. Red wires connect the left side of each pushbutton to the voltage bus at rows 20, 25, 30, 35, 40. A blue wire connects the Arduino's digital pin 13 to a a 220-ohm resistor in series with a green LED. The anode of an LED is attached to the anode of the resistor, the cathode of the LED is attached to the ground bus with a black wire.\" class=\"wp-image-6203\" width=\"374\" height=\"923\"\/><figcaption>Figure 13. Breadboard drawing of an Arduino Nano connected to five pushbuttons at digital pins 2-6. The Nano&#8217;s pin 13 is connected to a 220 ohm resistor in series with an LED.<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_schem.png\"><img loading=\"lazy\" decoding=\"async\" width=\"879\" height=\"495\" src=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_schem.png\" alt=\"Schematic drawing of five pushbuttons attached to an Arduino Leonardo. The pushbuttons is attached to digital pin 2 through 5 on one side, and to +5 volts on the other. There is also a 10-kilohm resistor attached to each of digital pins 2 through 6. The other side of each resistor is attached to ground. A 220-ohm resistor is connected to pin 13. The anode of an LED is connected to the other side of the resistor, and its cathode is connected to ground.\" class=\"wp-image-5601\" srcset=\"https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_schem.png 879w, https:\/\/itp.nyu.edu\/physcomp\/wp-content\/uploads\/KeyboardLabButtons_schem-768x432.png 768w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><figcaption>Figure 14. Schematic drawing of five pushbuttons and an LED attached to an Arduino Leonardo.<\/figcaption><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>In the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/lab-sensor-change-detection\/\">Sensor Change Lab<\/a>, you learned how to detect the state change of a digital input. You&#8217;ll use the same technique here.<\/p>\n\n\n\n<p>You&#8217;ll use the pushbutton on pin 2 to track whether the microcontroller is acting as a keyboard or not. Pressing this button will change the state of a global variable called <code>keyboardIsActive<\/code>. It will also call the <code>Keyboard.begin()<\/code> and <code>Keyboard.end()<\/code> commands as needed to take or relinquish control of the keyboard. The other four pushbuttons are intended to imitate keystrokes.&nbsp;The first will send the shift key. The last three will send the letters a, s, and d. With these options, you&#8217;ll learn to send both regular keystrokes as well as key combinations.<\/p>\n\n\n\n<p>To make this work, you&#8217;ll need to know not only when each button is pressed and released, but also when it is still being pressed. For the keyboard activator button, you&#8217;ll change the state of the keyboard whenever the button is pressed. For the shift button, you&#8217;ll send a message on press and release. For the other buttons, you&#8217;ll send a message on press and release, and when the button is still being pressed, you&#8217;ll send the keystroke repeatedly, after a short delay.<\/p>\n\n\n\n<p>Start by including the Keyboard library, then add two global arrays to track the button states and the previous button states. Also add a boolean variable to track whether the microcontroller is acting as a keyboard or not, a variable for the key repeat rate in milliseconds, and an array holding the keys you want to press with four of the five keys:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n#include \"Keyboard.h\"\n\n\/\/ Global variables:\nint buttonState&#x5B;5];      \/\/ states of the buttons\nint lastButtonState&#x5B;5];  \/\/ previous states of the buttons\n\/\/ whether or not the Arduino is controlling the keyboard:\nbool keyboardIsActive = false;\nint repeatRate = 50;    \/\/ key repeat rate, in milliseconds\n\n\/\/ keys to be pressed by the keyboard buttons:\nint key&#x5B;] = {KEY_LEFT_SHIFT, 'a', 's', 'd'};\n\n<\/pre><\/div>\n\n\n<p>Now, in the <tt>setup()<\/tt> function, set all the keys to be inputs. You can do this quickly with a for loop. Set the LED pin as an output as well:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid setup() {\n  \/\/ initialize serial communication:\n  Serial.begin(9600);\n  \/\/ set the pins as INPUT_PULLUPs:\n  for (int b = 2; b &lt; 7; b++) {\n    pinMode(b, INPUT_PULLUP);\n  }\n  \/\/ make the LED pin an output:\n  pinMode(13, OUTPUT);\n}\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Detect_the_State_Change_of_the_Buttons\"><\/span>Detect the State Change of the Buttons<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Now in your main <code>loop()<\/code> function you need to detect whether each button is pressed, released, or repeating. This is a slight variation on the digital in state change algorithm from the <a href=\"https:\/\/itp.nyu.edu\/physcomp\/labs\/labs-arduino-digital-and-analog\/lab-sensor-change-detection\/\">Sensor Change Lab<\/a>. Again, you can use a for loop to do this for all the buttons like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid loop() {\n  \/\/ iterate over the buttons:\n  for (int b = 0; b &lt; 5; b++) {\n    \/\/ pin number = array index number + 2:\n    buttonState&#x5B;b] = digitalRead(b + 2);\n    \/\/ see if the button has changed:\n    if (buttonState&#x5B;b] != lastButtonState&#x5B;b]) {\n      Serial.print(&quot;button&quot;);\n      Serial.print(b);\n      if (buttonState&#x5B;b] == HIGH)\n      { \/\/ pressed\n        Serial.println(&quot;pressed&quot;);\n      } else { \/\/ released\n        Serial.println(&quot;released&quot;);\n      }\n    } else {\n      if (buttonState&#x5B;b] == HIGH) {\n        Serial.println(&quot;still pressed&quot;);\n      }\n    }\n    \/\/ save button&#039;s current state as previous state for next loop:\n    lastButtonState&#x5B;b] = buttonState&#x5B;b];\n  }\n}\n<\/pre><\/div>\n\n\n<p>If you run the code now, you&#8217;ll see the messages &#8220;pressed&#8221;, &#8220;released&#8221; and &#8220;still pressed&#8221; for each key. You need to do something different foreach of those states for&nbsp; each key, as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Keyboard state button (pin 2): on press, toggle the keyboard state<\/li><li>Shift key button (pin 3): If <code>keyboardIsActive<\/code> is true, on press, send shift key press. On release, send shift key release. On still pressed, do nothing<\/li><li>Other key buttons:&nbsp; If <code>keyboardIsActive<\/code> is true, on press, send key press. On release, send key release. On still pressed, send key press after key repeat delay<\/li><\/ul>\n\n\n\n<p>You can write a function in which you pass the button number and the state of the button to make this happen. First, add the following function after the <code>loop()<\/code> function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid buttonAction(int buttonNumber, int buttonState) {\n  \/\/ the keyboard state change button\n  if (buttonNumber == 0) {\n    \/\/ on press, toggle keyboardIsActive\n    if (buttonState == HIGH) {\n      keyboardIsActive = !keyboardIsActive;\n    }\n  }\n  \/\/ the other three buttons:\n  if (keyboardIsActive) {\n    if (buttonNumber &gt; 0 ) {\n      if (buttonState == HIGH) {\n        Serial.println(&quot;pressed&quot;);\n      }\n      if (buttonState == LOW) {\n        Serial.println(&quot;released&quot;);\n      }\n    }\n    \/\/ all the buttons other than the shift button and the keyboard state button:\n    if (buttonNumber &gt; 1) {\n      if (buttonState == 2) { \/\/ still pressed\n        Serial.println(&quot;repeating&quot;);\n        delay(repeatRate);\n      }\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p>Then replace all the <code>Serial.println()<\/code> functions in the main <code>loop()<\/code> function with calls to this function, like so:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; highlight: [12,13,15,16,20,21]; title: ; notranslate\" title=\"\">\nvoid loop() {\n  \/\/ iterate over the buttons:\n  for (int b = 0; b &lt; 5; b++) {\n    \/\/ pin number = array index number + 2:\n    buttonState&#x5B;b] = digitalRead(b + 2);\n    \/\/ see if the button has changed:\n    if (buttonState&#x5B;b] != lastButtonState&#x5B;b]) {\n      Serial.print(&quot;button &quot;);\n      Serial.print(b);\n      if (buttonState&#x5B;b] == HIGH)\n      { \/\/ pressed\n        buttonAction(b, 0);\n        \/\/Serial.println(&quot; pressed&quot;);\n      } else { \/\/ released\n        buttonAction(b, 1);\n        \/\/Serial.println(&quot; released&quot;);\n      }\n    } else {\n      if (buttonState&#x5B;b] == HIGH) {\n        buttonAction(b, 2);\n        \/\/Serial.println(&quot;still pressed&quot;);\n      }\n    }\n    \/\/ save button&#039;s current state as previous state for next loop:\n    lastButtonState&#x5B;b] = buttonState&#x5B;b];\n  }\n}\n<\/pre><\/div>\n\n\n<p>When you run this sketch now, you should see that when you press the first button, it enables the other three to print out &#8220;pressed&#8221;, &#8220;released&#8221; and &#8220;repeating&#8221; messages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Add_commands_to_control_the_Keyboard\"><\/span>Add commands to control the Keyboard<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Finally, change the <code>Serial.println() <\/code> statements in the <code>buttonAction()<\/code> functions to <code>Keyboard.press()<\/code> or <code>Keyboard.release()<\/code> functions like so. Also add a block of code to activate or deactivate the Keyboard library and to set the LED (n.b. an audio alternative to the LED follows this code block). Note that you&#8217;re getting the key value from the <code>key[]<\/code> array, using the button number as the index:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; highlight: [7,8,9,10,11,12,13,14,21,22,25,26,32,33]; title: ; notranslate\" title=\"\">\nvoid buttonAction(int buttonNumber, int buttonState) {\n  \/\/ the keyboard state change button\n  if (buttonNumber == 0) {\n    \/\/ on press, toggle keyboardIsActive\n    if (buttonState == HIGH) {\n      keyboardIsActive = !keyboardIsActive;\n      \/\/ activate the keyboard:\n      if (keyboardIsActive) {\n        Keyboard.begin();\n      } else {\n        Keyboard.end();\n      }\n      \/\/ change the LED to reflect the keyboard state:\n      digitalWrite(13, keyboardIsActive);\n    }\n  }\n  \/\/ the other three buttons:\n  if (keyboardIsActive) {\n    if (buttonNumber &gt; 0 ) {\n      if (buttonState == HIGH) {\n        Keyboard.press(key&#x5B;buttonNumber - 3]);\n        \/\/ Serial.println(&quot; pressed&quot;);\n      }\n      if (buttonState == LOW) {\n        Keyboard.release(key&#x5B;buttonNumber - 3]);\n        \/\/ Serial.println(&quot; released&quot;);\n      }\n    }\n    \/\/ all the buttons other than the shift button and the keyboard state button:\n    if (buttonNumber &gt; 1) {\n      if (buttonState == 2) { \/\/ pressed\n        Keyboard.press(key&#x5B;buttonNumber - 3]);\n        \/\/ Serial.println(&quot; repeating&quot;);\n        delay(repeatRate);\n      }\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p>If you prefer an audio notification instead of the LED, put a buzzer on pin 13 and change the lines following the one that changes the <code>keyboardIsActive<\/code> variable as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\neyboardIsActive = !keyboardIsActive;\n\/\/ activate the keyboard:\nif (keyboardIsActive) {\n  Keyboard.begin();\n  \/\/buzz once for active:\n  digitalWrite(13, HIGH);\n  delay(300);\n  digitalWrite(13, LOW);\n} else {\n  Keyboard.end();\n  \/\/buzz twice for inactive:\n  digitalWrite(13, HIGH);\n  delay(300);\n  digitalWrite(13, LOW);\n  delay(300);\n  digitalWrite(13, HIGH);\n  delay(300);\n  digitalWrite(13, LOW);\n}\n<\/pre><\/div>\n\n\n<p>Once you upload this change, your board will be controlling the keyboard. Open a text editor and press the keyboard activation button. The LED will light up to indicate that keyboard control is active. Then press the last three keys, and it should send a, s, and d to the text editor. Hold shift while you press the other keys and you&#8217;ll get A, S, and D.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Shouldnt_I_Use_the_Shift_Key_to_Modify_The_Behavior_of_Others_in_Code\"><\/span>Shouldn&#8217;t I Use the Shift Key to Modify The Behavior of Others in Code?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>You may be thinking that the code above is not finished, and that you should be sending &#8220;a&#8221; when the shift key is unpressed, but &#8220;A&#8221; when it is. That is what is happening, but that&#8217;s not the microcontroller&#8217;s job. It only has to report which keys are pressed. The operating system on the receiving computer decides what to do with the results.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Keyboard_Library_Commands\"><\/span>The Keyboard Library Commands<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In the sketch above, you used the <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardbegin\/\">Keyboard.begin()<\/a> and <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardend\/\">Keyboard.end()<\/a> commands to take or relinquish control of the keyboard, and the <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardpress\/\">Keyboard.press()<\/a>, <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardrelease\/\">Keyboard.release()<\/a>, and <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardwrite\/\">Keyboard.write()<\/a> commands to send keystrokes. There is more you can do with the Keyboard library. You can use many of the same commands you&#8217;ve used in the Serial library, like <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardprint\/\">print()<\/a> and <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/keyboardprintln\/\">println()<\/a>. You can even <a href=\"https:\/\/www.arduino.cc\/en\/Tutorial\/KeyboardReprogram\">program the Arduino to reprogram itself<\/a>. Check out the <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/usb\/keyboard\/\">Keyboard library documentation<\/a> for more.<\/p>\n\n\n\n<p>The full sketch for this can be found on the <a rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/ITPNYU\/physcomp\/\" target=\"_blank\">phys comp github repository<\/a>, called <a rel=\"noopener noreferrer\" href=\"https:\/\/github.com\/ITPNYU\/physcomp\/blob\/master\/Labs\/LabKeyboardControl\/LabKeyboardControl.ino\" target=\"_blank\">LabKeyboardControl<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this lab, you&#8217;ll build an alternative computer keyboard using any of the USB-native boards <\/p>\n","protected":false},"author":55,"featured_media":0,"parent":0,"menu_order":999,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[50,15,49],"tags":[],"class_list":["post-5579","page","type-page","status-publish","hentry","category-keyboard","category-lab","category-usb"],"_links":{"self":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/5579"}],"collection":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/comments?post=5579"}],"version-history":[{"count":74,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/5579\/revisions"}],"predecessor-version":[{"id":10738,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/pages\/5579\/revisions\/10738"}],"wp:attachment":[{"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/media?parent=5579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/categories?post=5579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itp.nyu.edu\/physcomp\/wp-json\/wp\/v2\/tags?post=5579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}