Overview

This project is a handmade mechanical keyboard wired to an Arduino, which is further connected to a receipt printer. The goal of the project was to make a temporary vessel for transient thoughts that I don’t have the time to give proper mind to.

The finished project, for scale/ visual comprehension.

 

View of top panel the the – regrettably – bare keys.

Process Images

While developing this project, there were myriad decisions to make. Of these, a rather subtle choice that I made was to make the base key panels into modular things that can be wired into a system separately. All that they really are in the end are button arrays, and will certainly have utility in later projects. By setting the modules up to be reusable, it was possible later to restart designing without having to redo a lot of work. Another big point where things changed was when I realized that my original design did not work as-is. This was because I was down a large number of diodes. As a result, I needed to rethink the whole system, but this was arguably a good thing since it forced me to simplify my project significantly.

Each of these keyboard panels is designed to simply carry current out to the appropriate wire when a given button is pressed (provided that the red power lines are receiving power). These were crucial to make early, as the buttons used were not breadboard compatible. Each had to be soldered to

In this image, I’ve bundled all of the cables that go together so that management for wiring would be tractable (never mend tolerable). It might not be super clear, but the wires are individually bundled per color with tape, with all of the sub-bundles further bundled into one.

 

This image shows the beginning of wiring of the keyboard submodules to their corresponding selectors on the arduino. After doing some power flow testing, I realized that I had made a fatal flaw in my wiring – I was about 102 diodes short of making the board actually work.

 

This image highlights the moment that I was prepared to take the original board apart and restart with the simpler design.

 

The moment where I bound the lighter-weight key interfaces to a cardboard case to make the shell for the keyboard.

I like this image, mostly because of the deep blue aura around the LED has me thinking a bit more critically about how light reflects in air. This image shows the light indicating that the keyboard is being used turning on as a result of, well, the keyboard being activated.

Discussion

Looking over this project in hindsight, I feel that I learned a  lot of lessons both big and small. Chief among them is that, no matter how long you think something will take to do in the world of complex projects with many small parts like this, your estimate WILL be wrong. I ended up sinking an entire weekend (October 24-26… 3 days I’ll never forget) into solely wiring the system and still couldn’t finish it due to unforeseen technical difficulties. That last bit stings the most, but I can’t say that it wasn’t my fault that this was the outcome – I should have thought more about the wiring before just jumping in and grinding it out. This is more evidence to me that, in order to really excel at a project with a seriously involved technical component, one should plan rigorously, and make sure to iron out all of the fine details before jumping in.

Considering the previous, I’m not totally satisfied with how the project itself turned out, but this is immaterial to me. More important than the product, I’ve gained a newfound appreciation for the process of developing custom electronics, and given that my system did (sort of) work in the end, I’m confident that in a future project or personal endeavor, given I plan effectively ahead of time, the outcome will be something much more exciting. There is still that looming notion of poor planning, and I think this is what allowed for such a languid final product.

All of the written peer critique that I received was rather positive. One states,

I could tell you obviously put in a whole lot of effort! It’s a shame that you ran into so many wiring troubles, but cool idea overall.

It’s certainly reassuring that the idea of the project wasn’t strangled out in the tangle of spaghetti-wiring!

Another reads,

The idea was really cool! I can emphasize [sic] with having many ideas that I don’t know what to do with.”

Being such a scatterbrain myself, it feels good to know that the idea of trying to effectively reign the mind in is something that is appealing to others. As someone who’s lived their life with ADHD and OCD, often times my mind is inherently incapable of regulating its own direction and flow without manual intervention, but often this leads me to lose out on some really interesting streams of consciousness that will, well, never exist again. While I reckon that among the many preexisting methods for maintaining and logging thoughts what I’ve created here is not so novel, it would be nice to explore more novel methods to this end. There is something to be said about making something to solve your own problems as opposed to buying into a solution designed for an abstracted, generalized market.

Going forward, I think I’ll take more of my own time to create. I’ve always enjoyed visual arts and creative program, but the idea that I can essentially fold all of the power of a (tiny) computer into actual, physical projects is mind blowing. I feel a newfound fire in the engine that drives my work, and I want to ensure that it doesn’t burn out before I really carve out new ground. I now have a bunch of wired button arrays to use and a mountain of other electrical components that I feel more comfortable with beyond what I can learn from an ECE textbook. Alas, I can say all I like about what I could do, but this won’t matter until I actually do something.

While I’m not planning to iterate on this design (by the time you read it much of the project has likely been broken down for components), if I were to, there are two direction’s I’d take it. First, I’d dial back to the first circuit idea that I had – first, I’d strictly plan everything out and acquire every last required component to make the design, and do rigorous electrical testing throughout. This way, I wouldn’t be 80% of the way done only to learn that the rest of the non-cosmetic work is impossible to finish. The other, more likely direction I would take this would be to drop the arduino altogether and learn how to interface with a USB, as in a keyboard. This way, I could make a genuine physical keyboard out of the modules that I have. This would in all honesty probably be similar process-wise to the prior, but the end result, if constructed well enough, would be something that I’d be able to use in a variety of other situations.

Technical Portion

  1. <span class="com">/* Arduino Receipt Printer and Keyboard Driver
  2. * by Evan Tipping
  3. *
  4. * The following code is used to drive an otherwise entirely mechanical keyboard,
  5. * store the input and print it out via a receipt printer.
  6. *
  7. * NOTE: This code requires and arduino Mega to work
  8. *
  9. * PINOUT:
  10. * A0 : Pin linked to print button
  11. * A1 : Pin linked to starting and stopping keyboard
  12. * A3 : Pin linked to space button
  13. *
  14. * 6 : TX Digital serial transmission to receipt printer
  15. * 5 : RX Digital serial reception from receipt printer
  16. *
  17. * start_pin to start_pin + 36 : Corresponds to a key in the keyboard
  18. *
  19. * Credit to https://github.com/pjreddie/darknet/blob/master/LICENSE.v1 for the idea of
  20. * writing a useless liscense :D
  21. *
  22. * Liscense Information:
  23. * lol what's the point of liscensing code that's not being used in security-critical
  24. * applications? our modern legal system already failed and mostly serves to protect
  25. * those in a position of power and even if this code had a different liscense it's
  26. * not like I could afford a lawyer to defend myself. basically go nuts!
  27. */</span><span class="pln">
  28. </span><span class="com">#include</span><span class="pln"> </span><span class="str"><EEPROM.h></span><span class="pln">
  29. </span><span class="com">#include</span><span class="pln"> </span><span class="str">"Adafruit_Thermal.h"</span><span class="pln">
  30. </span><span class="com">#include</span><span class="pln"> </span><span class="str">"SoftwareSerial.h"</span><span class="pln">
  31. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MEM_LIM </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4096</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Length of EEPROM, board dependant</span><span class="pln">
  32. </span><span class="kwd">int</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln">
  33. </span><span class="kwd">int</span><span class="pln"> start_pin </span><span class="pun">=</span><span class="pln"> </span><span class="lit">18</span><span class="pun">;</span><span class="pln">
  34. </span><span class="kwd">bool</span><span class="pln"> typing </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
  35. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIN_PRINT </span><span class="pun">=</span><span class="pln"> A0</span><span class="pun">;</span><span class="pln">
  36. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIN_WRITE </span><span class="pun">=</span><span class="pln"> A1</span><span class="pun">;</span><span class="pln">
  37. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIN_SPACE </span><span class="pun">=</span><span class="pln"> A3</span><span class="pun">;</span><span class="pln">
  38. </span><span class="kwd">int</span><span class="pln"> TX_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">6</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Arduino transmit YELLOW WIRE labeled RX on printer</span><span class="pln">
  39. </span><span class="kwd">int</span><span class="pln"> RX_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Arduino receive GREEN WIRE labeled TX on printer</span><span class="pln">
  40. </span><span class="com">// Needed to operate keyboard</span><span class="pln">
  41. </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">char</span><span class="pln"> key_array</span><span class="pun">[</span><span class="lit">36</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="str">'0'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'3'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'4'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'5'</span><span class="pun">,</span><span class="pln">
  42. </span><span class="str">'6'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'7'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'8'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'9'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'a'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'b'</span><span class="pun">,</span><span class="pln">
  43. </span><span class="str">'c'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'d'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'e'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'f'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'g'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'h'</span><span class="pun">,</span><span class="pln">
  44. </span><span class="str">'i'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'j'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'k'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'l'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'m'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'n'</span><span class="pun">,</span><span class="pln">
  45. </span><span class="str">'o'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'p'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'q'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'r'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'s'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'t'</span><span class="pun">,</span><span class="pln">
  46. </span><span class="str">'u'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'w'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'x'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'y'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'z'</span><span class="pun">};</span><span class="pln">
  47. </span><span class="typ">SoftwareSerial</span><span class="pln"> mySerial</span><span class="pun">(</span><span class="pln">RX_PIN</span><span class="pun">,</span><span class="pln"> TX_PIN</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Declare SoftwareSerial obj first</span><span class="pln">
  48. </span><span class="typ">Adafruit_Thermal</span><span class="pln"> printer</span><span class="pun">(&</span><span class="pln">mySerial</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Pass addr to printer constructor</span><span class="pln">
  49. </span><span class="com">// Establish the top 36 inputs in the MEGA to be keys</span><span class="pln">
  50. </span><span class="kwd">void</span><span class="pln"> set_key_pins</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  51. </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> start_pin</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> start_pin </span><span class="pun">+</span><span class="pln"> </span><span class="lit">36</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  52. pinMode</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Use for button</span><span class="pln">
  53. </span><span class="pun">}</span><span class="pln">
  54. </span><span class="pun">}</span><span class="pln">
  55. </span><span class="kwd">char</span><span class="pln"> get_char_pressed</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  56. </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> start_pin</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> start_pin </span><span class="pun">+</span><span class="pln"> </span><span class="lit">36</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">10</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  57. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">i</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// Extra check accounting for.. hardware failure..</span><span class="pln">
  58. </span><span class="kwd">return</span><span class="pln"> key_array</span><span class="pun">[</span><span class="pln">i</span><span class="pun">];</span><span class="pln"> </span><span class="com">// Otherwise use regular key indexing</span><span class="pln">
  59. </span><span class="pun">}</span><span class="pln">
  60. </span><span class="pun">}</span><span class="pln">
  61. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">false</span><span class="pun">){</span><span class="com">//digitalRead(PIN_SPACE)) {</span><span class="pln">
  62. </span><span class="kwd">return</span><span class="pln"> </span><span class="str">' '</span><span class="pun">;</span><span class="pln"> </span><span class="com">// If the space key is pressed, return a space character</span><span class="pln">
  63. </span><span class="pun">}</span><span class="pln">
  64. </span><span class="kwd">return</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">;</span><span class="pln">
  65. </span><span class="pun">}</span><span class="pln">
  66. </span><span class="kwd">void</span><span class="pln"> print_msg</span><span class="pun">(</span><span class="kwd">char</span><span class="pun">*</span><span class="pln"> msg_buf</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  67. printer</span><span class="pun">.</span><span class="pln">boldOn</span><span class="pun">();</span><span class="pln">
  68. printer</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">msg_buf</span><span class="pun">);</span><span class="pln">
  69. printer</span><span class="pun">.</span><span class="pln">boldOff</span><span class="pun">();</span><span class="pln">
  70. </span><span class="pun">}</span><span class="pln">
  71. </span><span class="kwd">void</span><span class="pln"> print_mem</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  72. </span><span class="kwd">char</span><span class="pln"> str_msg</span><span class="pun">[</span><span class="pln">MEM_LIM</span><span class="pun">];</span><span class="pln">
  73. </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  74. </span><span class="kwd">int</span><span class="pln"> j </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Index in message</span><span class="pln">
  75. </span><span class="kwd">char</span><span class="pln"> chr_msg</span><span class="pun">;</span><span class="pln">
  76. </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">((</span><span class="pln">chr_msg </span><span class="pun">=</span><span class="pln"> EEPROM</span><span class="pun">.</span><span class="pln">read</span><span class="pun">(</span><span class="pln">i</span><span class="pun">))</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// While not at end of string</span><span class="pln">
  77. str_msg</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> chr_msg</span><span class="pun">;</span><span class="pln">
  78. i</span><span class="pun">++;</span><span class="pln">
  79. j</span><span class="pun">++;</span><span class="pln">
  80. </span><span class="pun">}</span><span class="pln">
  81. str_msg</span><span class="pun">[</span><span class="pln">j</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">;</span><span class="pln">
  82. </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">str_msg</span><span class="pun">);</span><span class="pln">
  83. print_msg</span><span class="pun">(</span><span class="pln">str_msg</span><span class="pun">);</span><span class="pln">
  84. </span><span class="pun">}</span><span class="pln">
  85. </span><span class="pun">}</span><span class="pln">
  86. </span><span class="kwd">int</span><span class="pln"> find_mem_start</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  87. </span><span class="kwd">int</span><span class="pln"> eeprom_end </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  88. </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="pln">EEPROM</span><span class="pun">.</span><span class="pln">read</span><span class="pun">(</span><span class="pln">eeprom_end</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> eeprom_end </span><span class="pun"><</span><span class="pln"> MEM_LIM</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  89. </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">eeprom_end</span><span class="pun">);</span><span class="pln">
  90. eeprom_end</span><span class="pun">++;</span><span class="pln">
  91. </span><span class="pun">}</span><span class="pln">
  92. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">eeprom_end </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  93. eeprom_end</span><span class="pun">++;</span><span class="pln"> </span><span class="com">// Skip over the null terminator if we aren't at start of memory</span><span class="pln">
  94. </span><span class="pun">}</span><span class="pln">
  95. </span><span class="kwd">return</span><span class="pln"> eeprom_end</span><span class="pun">;</span><span class="pln">
  96. </span><span class="pun">}</span><span class="pln">
  97. </span><span class="kwd">bool</span><span class="pln"> mem_full</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  98. </span><span class="kwd">return</span><span class="pln"> mem_start </span><span class="pun">>=</span><span class="pln"> MEM_LIM </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln"> </span><span class="com">// This is to ensure that there is a '\0' at end of eeprom </span><span class="pln">
  99. </span><span class="pun">}</span><span class="pln">
  100. </span><span class="kwd">void</span><span class="pln"> write_to_mem</span><span class="pun">(</span><span class="kwd">char</span><span class="pln"> key_pressed</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  101. EEPROM</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">mem_start</span><span class="pun">,</span><span class="pln"> key_pressed</span><span class="pun">);</span><span class="pln">
  102. mem_start</span><span class="pun">++;</span><span class="pln">
  103. EEPROM</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">mem_start</span><span class="pun">,</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">);</span><span class="pln">
  104. </span><span class="pun">}</span><span class="pln">
  105. </span><span class="kwd">void</span><span class="pln"> clear_eeprom</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  106. </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  107. EEPROM</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
  108. </span><span class="pun">}</span><span class="pln">
  109. </span><span class="pun">}</span><span class="pln">
  110. </span><span class="com">/*
  111. * SETUP SYSTEM
  112. */</span><span class="pln">
  113. </span><span class="kwd">void</span><span class="pln"> setup</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  114. set_key_pins</span><span class="pun">();</span><span class="pln">
  115. mem_start </span><span class="pun">=</span><span class="pln"> find_mem_start</span><span class="pun">();</span><span class="pln">
  116. pinMode</span><span class="pun">(</span><span class="pln">PIN_PRINT</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln">
  117. pinMode</span><span class="pun">(</span><span class="pln">PIN_WRITE</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln">
  118. pinMode</span><span class="pun">(</span><span class="pln">PIN_SPACE</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln">
  119. </span><span class="com">// Find end of EEPROM string</span><span class="pln">
  120. </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">
  121. mySerial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">19200</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Initialize SoftwareSerial</span><span class="pln">
  122. printer</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">();</span><span class="pln"> </span><span class="com">// Init printer (same regardless of serial type)</span><span class="pln">
  123. printer</span><span class="pun">.</span><span class="pln">justify</span><span class="pun">(</span><span class="str">'C'</span><span class="pun">);</span><span class="pln">
  124. </span><span class="pun">}</span><span class="pln">
  125. </span><span class="com">/*
  126. * LOOP TO DRIVE THE BOARD
  127. */</span><span class="pln">
  128. </span><span class="kwd">void</span><span class="pln"> loop</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  129. digitalWrite</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln">
  130. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">typing</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  131. </span><span class="kwd">int</span><span class="pln"> old_start </span><span class="pun">=</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln">
  132. </span><span class="kwd">char</span><span class="pln"> key_pressed </span><span class="pun">=</span><span class="pln"> get_char_pressed</span><span class="pun">();</span><span class="pln">
  133. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">key_pressed </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  134. </span><span class="kwd">char</span><span class="pln"> dbg_buf</span><span class="pun">[</span><span class="lit">2</span><span class="pun">];</span><span class="pln">
  135. dbg_buf</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">;</span><span class="pln">
  136. dbg_buf</span><span class="pun">[</span><span class="lit">0</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> key_pressed</span><span class="pun">;</span><span class="pln">
  137. digitalWrite</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
  138. write_to_mem</span><span class="pun">(</span><span class="pln">key_pressed</span><span class="pun">);</span><span class="pln">
  139. </span><span class="pun">}</span><span class="pln">
  140. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">PIN_WRITE</span><span class="pun">)</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> mem_full</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  141. typing </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Cancel typing early as there's no room left in memory or the user pressed the keyboard controller</span><span class="pln">
  142. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">mem_full</span><span class="pun">()</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> </span><span class="pun">!(</span><span class="pln">old_start </span><span class="pun">==</span><span class="pln"> mem_start</span><span class="pun">))</span><span class="pln"> mem_start</span><span class="pun">++;</span><span class="pln"> </span><span class="com">// Skip null terminator from prior string</span><span class="pln">
  143. </span><span class="pun">}</span><span class="pln">
  144. </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  145. </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">PIN_WRITE</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  146. typing </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
  147. </span><span class="pun">}</span><span class="pln">
  148. </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">PIN_PRINT</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  149. digitalWrite</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
  150. print_mem</span><span class="pun">();</span><span class="pln">
  151. clear_eeprom</span><span class="pun">();</span><span class="pln">
  152. </span><span class="pun">}</span><span class="pln">
  153. </span><span class="pun">}</span><span class="pln">
  154. delay</span><span class="pun">(</span><span class="lit">300</span><span class="pun">);</span><span class="pln">
  155. </span><span class="pun">}</span>
<span class="com">/* Arduino Receipt Printer and Keyboard Driver
 * by Evan Tipping
 * 
 * The following code is used to drive an otherwise entirely mechanical keyboard,
 * store the input and print it out via a receipt printer.
 * 
 * NOTE: This code requires and arduino Mega to work
 * 
 * PINOUT:
 * A0 : Pin linked to print button
 * A1 : Pin linked to starting and stopping keyboard
 * A3 : Pin linked to space button
 * 
 * 6 : TX Digital serial transmission to receipt printer
 * 5 : RX Digital serial reception from receipt printer
 * 
 * start_pin to start_pin + 36 : Corresponds to a key in the keyboard
 * 
 * Credit to https://github.com/pjreddie/darknet/blob/master/LICENSE.v1 for the idea of 
 * writing a useless liscense :D
 * 
 * Liscense Information:
 * lol what's the point of liscensing code that's not being used in security-critical
 * applications? our modern legal system already failed and mostly serves to protect
 * those in a position of power and even if this code had a different liscense it's
 * not like I could afford a lawyer to defend myself. basically go nuts!
 */</span><span class="pln">

</span><span class="com">#include</span><span class="pln"> </span><span class="str"><EEPROM.h></span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">"Adafruit_Thermal.h"</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">"SoftwareSerial.h"</span><span class="pln">

</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> MEM_LIM </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4096</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Length of EEPROM, board dependant</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> start_pin </span><span class="pun">=</span><span class="pln"> </span><span class="lit">18</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">bool</span><span class="pln"> typing </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIN_PRINT </span><span class="pun">=</span><span class="pln"> A0</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIN_WRITE </span><span class="pun">=</span><span class="pln"> A1</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> PIN_SPACE </span><span class="pun">=</span><span class="pln"> A3</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> TX_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">6</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Arduino transmit  YELLOW WIRE  labeled RX on printer</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> RX_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Arduino receive   GREEN WIRE   labeled TX on printer</span><span class="pln">

</span><span class="com">// Needed to operate keyboard</span><span class="pln">
</span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">char</span><span class="pln"> key_array</span><span class="pun">[</span><span class="lit">36</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="str">'0'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'3'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'4'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'5'</span><span class="pun">,</span><span class="pln"> 
                            </span><span class="str">'6'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'7'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'8'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'9'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'a'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'b'</span><span class="pun">,</span><span class="pln"> 
                            </span><span class="str">'c'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'d'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'e'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'f'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'g'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'h'</span><span class="pun">,</span><span class="pln">
                            </span><span class="str">'i'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'j'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'k'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'l'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'m'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'n'</span><span class="pun">,</span><span class="pln">
                            </span><span class="str">'o'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'p'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'q'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'r'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'s'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'t'</span><span class="pun">,</span><span class="pln">
                            </span><span class="str">'u'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'w'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'x'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'y'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'z'</span><span class="pun">};</span><span class="pln">



</span><span class="typ">SoftwareSerial</span><span class="pln"> mySerial</span><span class="pun">(</span><span class="pln">RX_PIN</span><span class="pun">,</span><span class="pln"> TX_PIN</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Declare SoftwareSerial obj first</span><span class="pln">
</span><span class="typ">Adafruit_Thermal</span><span class="pln"> printer</span><span class="pun">(&</span><span class="pln">mySerial</span><span class="pun">);</span><span class="pln">     </span><span class="com">// Pass addr to printer constructor</span><span class="pln">

</span><span class="com">// Establish the top 36 inputs in the MEGA to be keys</span><span class="pln">
</span><span class="kwd">void</span><span class="pln"> set_key_pins</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> start_pin</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> start_pin </span><span class="pun">+</span><span class="pln"> </span><span class="lit">36</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    pinMode</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Use for button</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">char</span><span class="pln"> get_char_pressed</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> start_pin</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> start_pin </span><span class="pun">+</span><span class="pln"> </span><span class="lit">36</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">10</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">i</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// Extra check accounting for.. hardware failure..</span><span class="pln">
      </span><span class="kwd">return</span><span class="pln"> key_array</span><span class="pun">[</span><span class="pln">i</span><span class="pun">];</span><span class="pln"> </span><span class="com">// Otherwise use regular key indexing</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">false</span><span class="pun">){</span><span class="com">//digitalRead(PIN_SPACE)) {</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="str">' '</span><span class="pun">;</span><span class="pln"> </span><span class="com">// If the space key is pressed, return a space character</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> print_msg</span><span class="pun">(</span><span class="kwd">char</span><span class="pun">*</span><span class="pln"> msg_buf</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  printer</span><span class="pun">.</span><span class="pln">boldOn</span><span class="pun">();</span><span class="pln">
  printer</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">msg_buf</span><span class="pun">);</span><span class="pln">
  printer</span><span class="pun">.</span><span class="pln">boldOff</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> print_mem</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">char</span><span class="pln"> str_msg</span><span class="pun">[</span><span class="pln">MEM_LIM</span><span class="pun">];</span><span class="pln">
  </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">int</span><span class="pln"> j </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Index in message</span><span class="pln">
    </span><span class="kwd">char</span><span class="pln"> chr_msg</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">((</span><span class="pln">chr_msg </span><span class="pun">=</span><span class="pln"> EEPROM</span><span class="pun">.</span><span class="pln">read</span><span class="pun">(</span><span class="pln">i</span><span class="pun">))</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// While not at end of string</span><span class="pln">
      str_msg</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> chr_msg</span><span class="pun">;</span><span class="pln">
      i</span><span class="pun">++;</span><span class="pln">
      j</span><span class="pun">++;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    str_msg</span><span class="pun">[</span><span class="pln">j</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">str_msg</span><span class="pun">);</span><span class="pln">
    print_msg</span><span class="pun">(</span><span class="pln">str_msg</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">int</span><span class="pln"> find_mem_start</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> eeprom_end </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="pln">EEPROM</span><span class="pun">.</span><span class="pln">read</span><span class="pun">(</span><span class="pln">eeprom_end</span><span class="pun">)</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> eeprom_end </span><span class="pun"><</span><span class="pln"> MEM_LIM</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">eeprom_end</span><span class="pun">);</span><span class="pln">
    eeprom_end</span><span class="pun">++;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">eeprom_end </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    eeprom_end</span><span class="pun">++;</span><span class="pln"> </span><span class="com">// Skip over the null terminator if we aren't at start of memory</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> eeprom_end</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">


</span><span class="kwd">bool</span><span class="pln"> mem_full</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> mem_start </span><span class="pun">>=</span><span class="pln"> MEM_LIM </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln"> </span><span class="com">// This is to ensure that there is a '\0' at end of eeprom </span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> write_to_mem</span><span class="pun">(</span><span class="kwd">char</span><span class="pln"> key_pressed</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    EEPROM</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">mem_start</span><span class="pun">,</span><span class="pln"> key_pressed</span><span class="pun">);</span><span class="pln">
    mem_start</span><span class="pun">++;</span><span class="pln">
    EEPROM</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">mem_start</span><span class="pun">,</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">


</span><span class="kwd">void</span><span class="pln"> clear_eeprom</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun"><</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    EEPROM</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">/*
 * SETUP SYSTEM
 */</span><span class="pln">
</span><span class="kwd">void</span><span class="pln"> setup</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  set_key_pins</span><span class="pun">();</span><span class="pln">
  mem_start </span><span class="pun">=</span><span class="pln"> find_mem_start</span><span class="pun">();</span><span class="pln">

  pinMode</span><span class="pun">(</span><span class="pln">PIN_PRINT</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln">
  pinMode</span><span class="pun">(</span><span class="pln">PIN_WRITE</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln">
  pinMode</span><span class="pun">(</span><span class="pln">PIN_SPACE</span><span class="pun">,</span><span class="pln"> INPUT_PULLUP</span><span class="pun">);</span><span class="pln">

  </span><span class="com">// Find end of EEPROM string</span><span class="pln">
  </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">

  mySerial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">19200</span><span class="pun">);</span><span class="pln">  </span><span class="com">// Initialize SoftwareSerial</span><span class="pln">
  printer</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">();</span><span class="pln">        </span><span class="com">// Init printer (same regardless of serial type)</span><span class="pln">
  printer</span><span class="pun">.</span><span class="pln">justify</span><span class="pun">(</span><span class="str">'C'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">/*
 * LOOP TO DRIVE THE BOARD
 */</span><span class="pln">
</span><span class="kwd">void</span><span class="pln"> loop</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  digitalWrite</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">typing</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">int</span><span class="pln"> old_start </span><span class="pun">=</span><span class="pln"> mem_start</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">char</span><span class="pln"> key_pressed </span><span class="pun">=</span><span class="pln"> get_char_pressed</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">key_pressed </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="kwd">char</span><span class="pln"> dbg_buf</span><span class="pun">[</span><span class="lit">2</span><span class="pun">];</span><span class="pln">
      dbg_buf</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'\0'</span><span class="pun">;</span><span class="pln">
      dbg_buf</span><span class="pun">[</span><span class="lit">0</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> key_pressed</span><span class="pun">;</span><span class="pln">
      digitalWrite</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
      write_to_mem</span><span class="pun">(</span><span class="pln">key_pressed</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">PIN_WRITE</span><span class="pun">)</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> mem_full</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> 
      typing </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Cancel typing early as there's no room left in memory or the user pressed the keyboard controller</span><span class="pln">
      </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">mem_full</span><span class="pun">()</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> </span><span class="pun">!(</span><span class="pln">old_start </span><span class="pun">==</span><span class="pln"> mem_start</span><span class="pun">))</span><span class="pln"> mem_start</span><span class="pun">++;</span><span class="pln"> </span><span class="com">// Skip null terminator from prior string</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">PIN_WRITE</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      typing </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">digitalRead</span><span class="pun">(</span><span class="pln">PIN_PRINT</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        digitalWrite</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
        print_mem</span><span class="pun">();</span><span class="pln">
        clear_eeprom</span><span class="pun">();</span><span class="pln">
      </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  delay</span><span class="pun">(</span><span class="lit">300</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span>

Electrical schematic for this project.