Unicode plugin feedback / Macros feedback / How to fix infinite typing

Here’s a fun story of how I “bricked” my keyboardio.

I did some experimenting with the Unicode plugin today.

The README says that starting from this example is the recommended way of getting started:

While that example does show how to wire the plugin up and use its core feature, Unicode.type(), it does not show how to run Unicode.type() when pressing a key.

I did it with a macro. Naively I added this to *macroAction():

case MACRO_ODOTS_LOWER:
  Unicode.type(0x00f6);
  break;

What I didn’t know was that *macroAction() appears to be run continuously (on every scan cycle?). In effect, my code caused öööööööööööööööööööööööööööööööö to be typed forever as soon as the keyboard was plugged in.

So I plugged my keyboardio out, and started fixing the code using another keyboard. I came up with this helper function:

static void unicode(uint32_t character, uint8_t keyState) {
  if (keyToggledOn(keyState)) {
    Unicode.type(character);
  }
}

Which can be used like this in *macroAction():

case MACRO_ODOTS_LOWER:
  unicode(0x00f6, keyState);
  break;

Great, now I just needed to reflash the keyboard. So far, I’ve been doing that through make flash. The problem is that to be able flash the keyboard, it has to be plugged in. But having it plugged in makes it difficult to type make flash: It ends up as öööömöööaöököööeöööö öööföölööaööösöhöööö.

I figured I could try flashing using the Arduino IDE instead, where I can click “Upload” in the menu. However, trying to compile from the Arduino IDE failed due to this error:

/home/lydell/Arduino/Model01-Firmware/Model01-Firmware.ino:17:26: fatal error: Kaleidoscope.h: No such file or directory
 #include "Kaleidoscope.h"
                          ^

I didn’t feel like trying to figure out what I’ve set up wrong, so I sat back and thought about some hack I could use to get my keyboardio back in a working state again. After a little while, I came up with a solution.

  1. Unplug the keybordio.
  2. Run read && make flash. This will read stdin in until Enter is pressed. Then, make flash will be run.
  3. Plug in the keyboardio.
  4. Press Enter until you manage it to register. (The Unicode plugin uses the ctrl+shift+u method of inputting unicode chars on Linux, which I use, which means that Enter confirms the unicode input instead of being a regular Enter press. So you need to press Enter exactly in between two cycles, which takes a few attempts depending on your luck.)
  5. Look for the “Press ENTER when ready…” message in the sea of öööööö.
  6. Press Enter and quickly after that hold Prog. Repeat this process until you manage to get Enter to register.

While writing this I realized that it might be possible to run make flash and then quickly plug the keyboardio in. But I don’t feel like testing that :slight_smile:

Takeaways:

Perhaps the comments for macros in Model01-Firmware.ino could warn against doing things in macro functions without checking keyState first. And mention the fact that *macroAction() seems to run on every scan cycle for every macro.

Perhaps the Unicode plugin’s example could be updated to be more “complete”, showing how to run Unicode.type() on a keypress, which I think is the most common thing people want to do with the plugin?

2 Likes

A good thing to do at this point is to create a GitHub issue for the Unicode plugin, requesting that the example be updated to show how to do this. Even better, you could submit a pull request with the changes.

I’m happy to do either or both, if you don’t (have a github account|know how|feel like it). Right now I’m preparing to write a brief guide for contributors, with the aim of developing standard procedures for working with the tree of repositories that is Kaleidoscope and its plugins.

2 Likes

Here we go:

2 Likes

Speaking of using the unicode plugin, does anyone know how to get rid of this linker error

Kaleidoscope-Unicode\src\Kaleidoscope/Unicode.cpp:32: undefined reference to `HostOS'

Manually including “Kaleidoscope-HostOS.h” and doing Kaleidoscope.use(&HostOS, &Unicode) does not seem to help.

I think you need to #include <Kaleidoscope/HostOS-select.h> which will give you the HostOS object use #define KALEIDOSCOPE_HOSTOS_GUESSER 1 before the include to get the fingerprinting otherwise you will need to HostOS.os( OS_TYPE )

What is this? It’s not a plugin.

fatal error: Kaleidoscope/HostOS-select.h: No such file or directory

ah sorry I had assumed you already had #include <Kaleidoscope-HostOS.h> in there.
include both

#include <Kaleidoscope-HostOS.h>
#include <Kaleidoscope/HostOS-select.h>

this worked for me.

2 Likes

I had, but in reverse order, that was the problem. Thank you!