PicoRuby (f/k/a mmruby) is an alternative Ruby implementation dedicated to one-chip microcontrollers. The binary fits into less than 256 KB ROM and runs on less than 64 KB RAM. This development was supported by the Ruby Association (RA) Grant program 2020 and mentored by Matz himself! Monstarlab is one of the developers of the Ruby programming ecosystem.

C/C++ is still the first language for microcontrollers though, script languages like Lua and MicroPython are nicely developing in embedded systems nowadays. I, an enthusiastic Ruby fan, dreamed that Ruby would be a real choice to make hardware. The time has come.

Ruby in small footprint

Implementing a Ruby interpreter for microcontrollers was regarded as difficult because of its free and descriptive grammatical rules. An upside of Ruby is also a downside in terms of a small footprint. The unnecessity of parenthesizing arguments in method call may increase the size of the syntax parser table. The dynamic type decision system will complicate the runtime environment.

Despite these valid observations, some people including me are trying to achieve it. I am working at the Shimane development branch at Monstarlab Japan.

Developing Ruby as my daily work

After my proposal was adopted by the RA Grant, I talked to Daisuke, our CTO in Japan, about whether we can work on the project as an official work of our company. I became a “part-time committer” of the OSS at that moment since he promptly agreed to my suggestion.

Matz, the founder of Ruby, has been responsible for my mentorship during the project as mentioned above. I could (even now I still can) text him to ask how Ruby works, why did he design Ruby like that, and what are his thoughts in reducing the memory consumption. Thanks to Matz’s big support, I successfully submitted the final report.

A keyboard firmware in Ruby

Now you can freely fork and build PicoRuby, though it is probably hard to use it properly without any idea. My next goal is to make a “killer product” to indicate that PicoRuby deserves to be your language of choice.

I definitely know you are a “keyboard lover” if you are a software programmer, right? I have good news for you that I recently released “PRK Firmware” which is a keyboard firmware platform and runs on Raspberry Pi Pico (RP2040 chip). keymap.rb which configures keymap and allows you to modify keyboard behavior can be written as follows:

Initialize a Keyboard object and configure GPIO pins

kbd = Keyboard.new

kbd.init_pins(
  [ 2, 3, 4, 5 ],                                 # row0, row1,... respectively
  [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ]  # col0, col1,... respectively
)

Supposing you are building a 4x12 matrix, a so-called “40%” keyboard.

Add layers as you like

# (I skipped the right-side of the keymap)
kbd.add_layer :default, [
  %i(KC_ESC  KC_Q        KC_W        KC_E      KC_R     KC_T ...),
  %i(KC_TAB  KC_A        KC_S        KC_D      KC_F     KC_G ...),
  %i(KC_LSFT KC_Z        KC_X        KC_C      KC_V     KC_B ...),
  %i(KC_NO   KC_NO       KC_LGUI     KC_LALT   KC_LCTL  RAISE_ENTER ...)
]
kbd.add_layer :raise, [
  %i(KC_ESC  KC_1        KC_2        KC_3      KC_4     KC_5 ...),
  %i(KC_TAB  KC_F1       KC_F2       KC_F3     KC_F4    KC_F5 ...),
  %i(KC_LSFT KC_LBRACKET KC_RBRACKET KC_SCOLON KC_MINUS KC_PLUS ...),
  %i(KC_NO   KC_NO       KC_LGUI     KC_LALT   KC_LCTL  RAISE_ENTER ...)
]

You don’t need to insert , (comma) between KC_x and KC_x while QMK firmware requires you to do.

Define “mode” keys

#                   Your mode       Keycode or  Keycode or Proc                     Release time      Re-push time
#                   key name        Proc when   while you keep press                threshold(ms)     threshold(ms)
#                                   you  click                                      to consider as    to consider as
#                                                                                   `click the key`   `hold the key`
kbd.define_mode_key :RAISE_ENTER, [ :KC_ENTER,  Proc.new { kbd.hold_layer :raise }, 200,              150 ]
kbd.define_mode_key :LOWER_SPACE, [ :KC_SPACE,  Proc.new { kbd.lock_layer :lower }, 200,              150 ]

You will easily see Proc object works particularly.

Want to input “:” without Shift and “;” with Shift?

Sure!

kbd.before_report do
  kbd.invert_sft if kbd.keys_include?(:KC_SCOLON)
end

Conclusion

What do you say? I hope you find keymap.rb is better than other firmware platforms :)

PRK Firmware will be frequently updated as it is still public beta. Please check my Twitter and GitHub if you want to be notified.

Resources

Developing PRK Firmware on Raspberry Pi Pico

Article Photo by hasumikin

Author

Hitoshi Hasumi

A Programmer

Ruby

You may also like

WWDC21 - A first look at Apple's new Augmented Reality features

There are now over 1 billion augmented reality enabled iPhones and iPads which gives an incredible reach for your experiences. Here is an overview of what we know so far from this year’s WWDC when it comes to augmented reality, with more details to unravel this week after the engineering...

iOS
Static type checking in PicoRuby

The static type system ensures correspondence of the “type” among arguments, parameters, and return values. The point is that you can notice some kinds of bugs in advance of execution.