Mode Switcher for Talon Voice That Fits in the Gap of a Microsoft Sculpt Keyboard.

by lookbothways in Circuits > Arduino

974 Views, 4 Favorites, 0 Comments

Mode Switcher for Talon Voice That Fits in the Gap of a Microsoft Sculpt Keyboard.

USER_SCOPED_TEMP_DATA_MSGR_PHOTO_FOR_UPLOAD_1639059963510_6874715761192907638.jpg

Streamlined dictation

Mode switcher for Talon Voice, switches between Command mode and Dictation mode instantly when the joystick is flicked up or Talon sleep and Talon wake when flicked down.

This speeds up voice-input as the user doesn't need to interrupt their thought process to say the commands to switch modes and wait for the interpreter to execute them.

For example: in Dictation mode (green), saying the year 2019 will be typed as 'two thousand and nineteen' - flick this up to Command mode (blue) just before you say it and Talon will type 2019, flick it back to dictation and continue.

The same for things like 'left paren/right paren', pressing escape / delete keys, custom inputs (i.e: 'My address', 'My email') and other types of punctuation that would otherwise be typed out verbatim.

Instant-off

Often someone else starts talking at the user. A flick down means the user needn't talk over the interruption to say 'Talon sleep' before their machine does something unwanted.

Housing

The case fits under a Microsoft Sculpt keyboard but can be handheld.

How?

An Itsy Bitsy 32u4 sends keyboard shortcuts to the PC that are hooked up to Talon Via Autohotkey.

AutoHotKey scripts can be edited to send any shortcut / script execution - meaning this thingy is not limited to use with Talon.

Supplies

modeSwitcherOnShapeways.JPG
itsyBitsy 3677-00_1024x1024.jpg
RGBLEDmodule.JPG
AnalogueJoystick.JPG

1x Adafruit ItsyBitsy 32u4 - 5V 16MHz + USB Micro-B cable

£9.60 at Pimoroni https://shop.pimoroni.com/products/adafruit-itsyb...

1x XY Analogue joystick with push-down click

£2.19 https://www.amazon.co.uk/Hobby-Components-Ltd-Com...

1x RGB LED Module

£4.80 https://shop.pimoroni.com/products/rgb-led-module...

1x 3D printed 'modeSwitcher.stl'

3D printed by yourself. In my case Shapeways in 'Black natural versatile plastic' for about £50

9x wires

Both the LED and Analogue Joystick and wires came from this Elegoo 37-in-one kit: https://www.elegoo.com/products/elegoo-37-in-1-se...

------------------------------------------

Also required:

  • Soldering Iron with a tiny tip
  • Dremel or some way to cut off the bridge between the case components and trim the underside of the lid if it's not snug
  • Glue gun - for sticking the components in
  • Gorilla Glue - for sticking the lid on (cleaner than using the glue-gun).

Useful to have:

  • Clamps for holding lid in place while it dries - masking tape may be fine for this
  • Scalpel for trimming wires
  • Helping Hand with magnifying glass

https://www.amazon.co.uk/Rolson-Tools-60335-Helpin...

Test the Hardware

circuit.JPG
testIt.JPG

Download the modeSwitcher.ino, flash it onto the Itsy Bitsy or an Arduino Leonardo.

modeSwitcher.ino

#include <Keyboard.h>
bool commandMode = true;
bool sleep = false;
bool yesPop = true;
bool controlMouse = false;


int sensitivity = 120;
int sensitivityNegative = -120;
int wait = 400;


//autoHotKey command to kill Talon voice by pressing control shift k (without the forward slashes)
//^+k:: Run, %ComSpec% /c echo actions.speech.toggle() | %A_AppData%\talon\.venv\Scripts\repl , , Hide


char ctrlKey = KEY_LEFT_CTRL;
char leftShift = KEY_LEFT_SHIFT;


char f9 = KEY_F9;
char f10 = KEY_F9;
char f11 = KEY_F11;
char f12 = KEY_F12;


int VRx = A0;
int VRy = A1;
int SW = 2;


int xPosition = 0;
int yPosition = 0;
int SW_state = 0;
int mapX = 0;
int mapY = 0;


//RGB settings
int redpin = 11; // select the pin for the red LED
int bluepin =10; // select the pin for the  blue LED
int greenpin =9; // select the pin for the green LED
int Rval;
int Gval;
int Bval;
int on = 100;


void setup() {
  Serial.begin(14400); 
  //joystick input
  pinMode(VRx, INPUT);
  pinMode(VRy, INPUT);
  pinMode(SW, INPUT_PULLUP); 
  //RGB output
  pinMode(redpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(greenpin, OUTPUT);
}


void loop() {
  xPosition = analogRead(VRx);
  yPosition = analogRead(VRy);
  SW_state = digitalRead(SW);
  mapX = map(xPosition, 0, 1023, -512, 512);
  mapY = map(yPosition, 0, 1023, -512, 512);  
  
  if (mapY >= sensitivity) {
    //set sensitivity
    if (controlMouse == true) {
      Serial.print(mapY);
      controlMouse = false;
      delay(wait);
    }  
    else {
      Serial.print(mapY);
      controlMouse = true;
      delay(wait);
      }
  }  
  if (mapY == sensitivityNegative) {
    //set pop
    if (yesPop == true) {
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('i');
      Keyboard.releaseAll();
      Serial.print("yespop");
      yesPop = false;
      delay(wait);
    }  
    else {
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('o');
      Keyboard.releaseAll();
      Serial.print("nopop");
      yesPop = true;
      delay(wait);
      }
  }  
  if (mapX >= sensitivity) {
    //sleep wake
    if (sleep == true) {
      //sleep
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('k');
      Keyboard.releaseAll();
      Serial.print("sleep");
      sleep = false;
      Rval = 0;
      Gval = 0;
      Bval = 0;
      analogWrite(11, Rval);
      analogWrite(9, Gval);
      analogWrite(10, Bval);
      }  
    else {
      //wake
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('h');
      Keyboard.releaseAll();
      Serial.print("wake");
      sleep = true;
    }
    if ( sleep == true and commandMode == false ) {
      Rval = 0;
      Gval = 0;
      Bval = on;
      analogWrite(11, Rval);
      analogWrite(9, Gval);
      analogWrite(10, Bval);       
    }
    if ( sleep == true and commandMode == true ) {
      Rval = 0;
      Gval = on;
      Bval = 0;
      analogWrite(11, Rval);
      analogWrite(9, Gval);
      analogWrite(10, Bval);
    }
    delay(wait);
  }


  
  if (mapX <= sensitivityNegative) {
    //first wake talon if asleep
    if (sleep == false) {
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('h');
      Keyboard.releaseAll();
      Serial.print("waking talon");
      sleep = true;
      delay(50);
    }
    //set command mode / dictation mode
    if (commandMode == true) {
      //commandMode
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('j');
      Keyboard.releaseAll();
      Serial.print("commandMode");
      Rval = 0;
      Gval = 0;
      Bval = on;
      analogWrite(11, Rval);
      analogWrite(9, Gval);
      analogWrite(10, Bval);
      commandMode = false;
      delay(wait);
    }  
    else {
      //dictationMode
      Keyboard.press(ctrlKey);
      Keyboard.press(leftShift);
      Keyboard.press('l');
      Keyboard.releaseAll();
      Serial.print("dictationMode");
      Rval = 0;
      Gval = on;
      Bval = 0;
      analogWrite(11, Rval);
      analogWrite(9, Gval);
      analogWrite(10, Bval);
      commandMode = true;
      delay(wait);
      }
  }
}

Note the code won't work on an Uno as it doesn't natively emulate a USB keyboard.

Wire it up

Check out the circuit diagram.
I'd recommend checking everything works by poking wires through the holes in the Itsy Bitsy while it's held by the Helping Hand, or use an Arduino Leonardo to test the thing first.
See attached picture with everything taped into place.

Test it

Plug it in to a PC. Flick it down (away from the pins) and the LED should light up. Flick it up and it should change colour. Flick it down again and it should go off.

Solder

IMG_20211209_112058.jpg
IMG_20211209_120657.jpg
testitagain.JPG

  • Trim the wires to length, I do this by rolling them gently on the cutting board with a scalpel - I left about five millimetres of cable visible.
    Sorry I didn't measure them - use the photo as a guide, also note how I bent the pins of the joystick so the LED would fit.
  • To solder them I used the helping hand to grip the wire and then dropped the Arduino on the top and put a tiny amount of solder in the hole from the underside.
  • Test it again now it's soldered.

Set Up Talon and AutoHotKey

This tutorial assumes that you have already got to Talon installed, if you don't and would like to try using your computer without your hands - or reduce how much typing you do, visit https://talonvoice.com/

If you would prefer, construct the AutoHotKey scripts yourself:

Command Mode

MsgBox, Script is running. Now you can press ctrl+shift+j to set command mode.

^+j:: Run, %ComSpec% /c echo mimic("command mode") | %A_AppData%\talon\.venv\Scripts\repl , , Hide

Dictation Mode

MsgBox, Script is running. Now you can press ctrl+shift+l to set dictation mode

^+l:: Run, %ComSpec% /c echo mimic("dictation mode") | %A_AppData%\talon\.venv\Scripts\repl , , Hide

Talon Sleep

MsgBox, Script is running. Now you can press ctrl+shift+k to sleep Talon

^+k:: Run, %ComSpec% /c echo mimic("talon sleep") | %A_AppData%\talon\.venv\Scripts\repl , , Hide

Talon Wake

MsgBox, Script is running. Now you can press ctrl+shift+h to sleep Talon

^+h:: Run, %ComSpec% /c echo mimic("talon wake") | %A_AppData%\talon\.venv\Scripts\repl , , Hide

  • Run them, you should see a confirmation dialogue
  • Plug in the modeSwitcher hardware and test it.
  • If you wish, add them to the startup folder.
  • To open the “Startup” folder, type Windows+R, type “shell:startup,” and press Enter.

Print the Box, Glue It In

modeSwitcher.JPG
USER_SCOPED_TEMP_DATA_MSGR_PHOTO_FOR_UPLOAD_1638982189560_6874389553601781051.jpg
modeSwitcherOnShapeways.JPG
diffuser.JPG

Print

I used Shapeways to print this in generic black.
I printed it as one piece to save money and used a Dremel to cut out the bridge, a hacksaw blade should be fine for this if you don't have a Dremel. Try to make it flush so nothing protrudes onto the components.

The file I printed needed a bit of tweaking around the hole for the USB cable, so the numbers in their analysis of the mesh may be slightly different. The dimensions should match the photo.

Glue

I used a glue-gun to stick the Itsy Bitsy in first, then the LED and attached their wires, then the Joystick and attached the wires. The tricky part was getting the joystick to be dead-centre while the glue was cooling. Be quick! Try to align the Itsy-Bitsy USB level with the hole - avoid using too much glue.
I made the hole bigger in the STL uploaded here to accommodate mistakes.

Light diffuser

A piece of card sits over the LED and under the edge of the joystick to bounce light out the top of the ring.
If I'd used translucent plastic this wouldn't be necessary. Brightness of the LED is controlled via the Arduino code, default is 100.

Glue on the lid

Use Gorilla glue or similar slower-drying glue - In that photo the lid is held on with Blu-tak still.

Hope this helps - bear in mind the modeSwitcher can be used for any software via AutoHotKey, which can do some pretty complex stuff.

Downloads