keybrd library is an open source library for creating custom-keyboard firmware.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

keybrd_2_single-layer_annotated.ino 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* keybrd_single-layer_2_annotated.ino
  2. This sketch:
  3. is a simple 1-layer keyboard
  4. runs on the first two rows and columns of a breadboard keyboard
  5. is annotated with a walk-through narrative
  6. This layout table shows how keys are arranged on the keyboard:
  7. | Layout | **0** | **1** |
  8. |:------:|-------|-------|
  9. | **0** | a | b |
  10. | **1** | c | shift |
  11. The layout's row and column numbers are in the headers.
  12. Each cell in the table's body represents a key.
  13. The sketch is annotated with a walk-through narrative enclosed in comment blocks.
  14. Each comment block explains the next one or two lines of code.
  15. keybrd is instantiated under the "GLOBAL" heading. Most of the sketch is in global space.
  16. keybrd runs at the end of this sketch, under the "MAIN" heading.
  17. */
  18. // ################## GLOBAL ###################
  19. // ================= INCLUDES ==================
  20. /*
  21. The compiler copies #included files into the sketch.
  22. All the includes in this sketch are to keybrd library classes.
  23. */
  24. //Ports
  25. #include <RowPort_AVR_Optic.h>
  26. #include <ColPort_AVR.h>
  27. //Codes
  28. #include <Code_Sc.h>
  29. //Matrix
  30. #include <Row.h>
  31. #include <Matrix.h>
  32. // ============ SPEED CONFIGURATIONS ============
  33. /*
  34. DELAY_MICROSECONDS specifies the amount of delay between row scans.
  35. Keyboard switches are made of moving contacts.
  36. When the contacts close, they bounce apart one or more times before making steady contact.
  37. DELAY_MICROSECONDS gives the switches time to debounce.
  38. DELAY_MICROSECONDS is a static variable of class Row.
  39. */
  40. const unsigned int Row::DELAY_MICROSECONDS = 1000;
  41. // =================== PORTS ===================
  42. /*
  43. A micro-controller has one or more ports. Each port has one or more pins.
  44. These pins are connected to the keyboard's rows and columns.
  45. The RowPort constructor parameters specify the port's registers.
  46. */
  47. RowPort_AVR_Optic rowPortF(DDRF, PORTF);
  48. /*
  49. The ColPort constructor parameters specify the port's registers and the port pins to read:
  50. A number to the right of "1<<" is the pin number to read. 1<<0 reads pin 0, and 1<<1 reads pin 1.
  51. */
  52. ColPort_AVR colPortB(DDRB, PORTB, PINB, 1<<0 | 1<<1 );
  53. /*
  54. ColPort pointers are placed in an array because some keyboards use multiple column ports.
  55. This sketch only has one column port.
  56. sizeof() is used to compute the number of array elements.
  57. This eliminates the risk of forgetting to update the count after adding or removing an element.
  58. */
  59. ColPort* const ptrsColPorts[] = { &colPortB };
  60. const uint8_t COL_PORT_COUNT = sizeof(ptrsColPorts)/sizeof(*ptrsColPorts);
  61. // =================== CODES ===================
  62. /*
  63. The CODES section instantiates four codes, one for each item in the layout.
  64. The Code_Sc constructor takes one scancode ("Sc" means "scancode").
  65. When Code_Sc is pressed, it sends its scancode.
  66. The Code object names in this sketch start with a "s_" prefix.
  67. */
  68. Code_Sc s_a(KEY_A);
  69. Code_Sc s_b(KEY_B);
  70. Code_Sc s_c(KEY_C);
  71. Code_Sc s_shift(MODIFIERKEY_LEFT_SHIFT);
  72. // ================== MATRIX ===================
  73. /*
  74. The MATRIX section instantiates the components of the matrix:
  75. Codes are grouped into rows.
  76. Rows are grouped into a matrix.
  77. How the matrix works:
  78. 1) The matrix scans one row at a time.
  79. 2) If a row detects a key press, it notifies the code.
  80. 3) The code sends its scancode.
  81. */
  82. // ------------------- ROWS --------------------
  83. /*
  84. Here we group Code pointers into rows.
  85. Codes are a kind of Key. Array ptrsKeys_0[] contains two pointers to Key objects.
  86. The Row constructor parameters are:
  87. one rowPort
  88. one row pin
  89. an array of colPorts, and the number of colPorts
  90. an array of Key pointers
  91. The Row objects names in this sketch start with a "row_" followed by a row number.
  92. */
  93. Key* const ptrsKeys_0[] = { &s_a, &s_b };
  94. Row row_0(rowPortF, 1<<0, ptrsColPorts, COL_PORT_COUNT, ptrsKeys_0);
  95. Key* const ptrsKeys_1[] = { &s_c, &s_shift };
  96. Row row_1(rowPortF, 1<<1, ptrsColPorts, COL_PORT_COUNT, ptrsKeys_1);
  97. /*
  98. HOW ROW OBJECTS WORK
  99. When a row is scanned, the row strobes the row pin, and the column ports read their column pins.
  100. If a row detects a key press, it notifies the key which then sends its scancode.
  101. */
  102. // ------------------ MATRIX -------------------
  103. /*
  104. Here we group Row pointers into a matrix.
  105. Array ptrsRows[] contains two pointers to Row objects.
  106. */
  107. Row* const ptrsRows[] = { &row_0, &row_1 };
  108. const uint8_t ROW_COUNT = sizeof(ptrsRows)/sizeof(*ptrsRows);
  109. /*
  110. The Matrix constructor parameters are:
  111. one array of Row pointers, and the number of rows
  112. '0' for active low or '1' for active high
  113. WARNING: the tutorial sketches all have '1' for active high to be compatible with DH.
  114. The breadboard keyboard described in tutorial_1 is active low.
  115. For active low, change the '1' to a '0':
  116. */
  117. Matrix matrix(ptrsRows, ROW_COUNT, 1);
  118. // ################### MAIN ####################
  119. /*
  120. Aruduino IDE copies Functions setup() and loop() into main().
  121. setup() initialized the keybrd.
  122. Keyboard.begin() should be called once to initialize.
  123. */
  124. void setup()
  125. {
  126. Keyboard.begin();
  127. }
  128. /*
  129. loop() continually scans the Matrix object.
  130. */
  131. void loop()
  132. {
  133. matrix.scan();
  134. }