• Hello all,

    I thought I'd share the code for the input method I've just thought of and been playing around with today. (Lockdown creativity!)

    I've been wanting a method to enter text "on the go" on my phone, so thought that a Pixl.js was a good way to experiment. The attached code implements a Bluetooth keyboard that works with a Pixl.js with no other hardware.

    The idea is to press buttons in sequence then release them. So BTN4 is 'T', BTN3 is 'A' etc. To get other letters you hold down a sequence - 'H' is hold BTN4, hold BTN3, release both. 'P' is hold down three buttons then release all.

    This is a bit complex to remember, so I made a graphical pattern for each letter - see the attached picture. This works holding a Pixl "rotated" so that the 'Pixl.js..Espruino' writing is on the right hand side as you hold it, so that 'a' is the top right button, 'e' is the bottom left.

    I don't think it's too bad to use; I was writing text reasonably quickly and found I was beginning to memorise the patterns. I've used letter frequencies so (in English) more common letters need fewer presses.

    I'd like to expand this to have numbers and other characters, and possibly to work with a capacitative sensor so you can just write out the shapes with a finger. It would be cool to have this sensor woven into fabric, or via a tiny sensor with four quadrants you could wear as a thimble or something.

    Future plans:

    • Work out how to add more characters - e.g. numbers and capital letters. Theoretically the pattern length can be infinite, or maybe have a combination to switch 'mode'.
    • Work out how to use 4 cap sense inputs on the Pixl and experiment with conductive thread to make pads on fabric. I've got a couple of I2C cap sensor chips lying around but I suspect the NRF chip can do this.
    • Work out how to bond the Pixl to the phone so the phone automatically connects to the device - currently I have to manually connect on the phone.

    What do you think?

    Colin

    The code is below (Indentation has gone a bit wrong but hopefully it's readable)

    To explain the code:

    • states maintains a mapping of buttons to letter. The starting state is '_'.
    • Pressing button 1 moves to the 'E' state. If all buttons are released then 'E' is emitted. If more buttons are pressed then the state moves from 'E' to the next state according to the button.
    • '?' is an error state - e.g. pressing button 1 twice without releasing it isn't possible.
    • '!' is an unused state so extra things can be added.

          
      // Key state transitions
      var states = {
      //  BTN. 1   2   3   4
      //Single key
      '_': ['E',' ','A','T'],
      // Two keys
      ' ': ['L','?','I','M'],
      'E': ['?','D','C','S'],
      'A': ['U','O','?','R'],
      'T': ['N','W','H','?'],
      // Three keys
      'W': ['F','!','!','!'],
      'D': ['!','!','!','G'],
      'C': ['!','J','!','Y'],
      'H': ['P','!','!','!'],
      'S': ['!','B','X','!'],
      'M': ['V','!','!','!'],
      'I': ['K','!','!','!'],
      'N': ['!','Q','!','!'],
      'R': ['Z','!','!','!'],
      'Z': ['!','CR','!','!'],
      // Error
      '?': ['?','?','?','?']
      };
      
      function keydown(key) {
      if (state=='?') Terminal.println("Error - bad state");
      ++keydowncount;
      state=states[state][key]; // Transition to the new state
      }
      
      function keyup(key) {
      --keydowncount;
      
      if (keydowncount==0) { // All keys released: Emit the key
        emitkey(state);
        state='_'; // Reset state transition
      }
      }
      
      // Do whatever when the key is released
      function emitkey(letter) {
      Terminal.print(letter);
      // CR hack
      if (letter=='CR') Terminal.println("");
        
      if (kb) {
        // CR hack
        if (letter=='CR') {
          kb.tap(kb.KEY.ENTER,0);
        }
        else
          kb.tap(kb.KEY[letter], 0);
      }
      }
      
      // Map a button to the position in the state array
      function wireKey(button,position) {
      setWatch(function() { keydown(position); }, button, { edge: 'rising', repeat: true});
      setWatch(function() { keyup(0); }, button, { edge: 'falling', repeat: true});
      }
      
      function onInit() {
      keydowncount = 0;
      state = '_'; // Starting state
      
      wireKey(BTN1,0);
      wireKey(BTN2,1);
      wireKey(BTN3,2);
      wireKey(BTN4,3);
      
      kb = undefined;
      kb = require("ble_hid_keyboard");
      NRF.setServices(undefined, { hid : kb.report });
      }
      
      

    1 Attachment

    • colin-4key.jpeg
About

Avatar for ColinP @ColinP started