Automated Typing demo - InterConnected DigiSpark & ATMEGA32U4 boards:- Arduino Leonardo, Bad Beetle Pro Microboards.

The Digispark can be configured as a HID Keyboard. Also ATMEGA32U4 boards:- Arduino Leonardo, Bad Beetle Pro Micro, OTG connectors and cables and a Wire to disable typing, can be used. Useful for auto testing a typing app.

Arduino Sketches:-

Keyboard_button3.ino

LeonardoAutoType.ino

Arduino Sketches:-

My AutoTyping kit. DigiSpark, ATMEGA32U4 boards:- Arduino Leonardo, Bad Beetle Pro Micro, OTG connectors and cables and a Wire to disable typing. :-

image

Introduction:-

This page explores a peer to peer protocol , but pragmatically a master slave protocol is simpler.

It has a USB port for the HID and three pins.

There are three pins P0, P1, P2. P1 has an LED so in an output.

We want an ASTABLE - when one end is typing, the other end backs off. Turn the LED off when Typing, if the other end has LED off, back off typing.

if one is the master and the other the slave connect P0 on the slave to P1 on the master

Explore peer to peer so

----|----|----|----|----|----|----|----|----|----|----|----|

              +---------+       
              |DigiSpark|
    +---------| P2      |==> USB HID keyboard
    | +-------| P1 LED  |
    | |  +----| P0 I/P  |  
    | |  |    +---------+   
    | |  +-- /DISABLE      P0 is used to disable typing  
    | |                    P1 is LED output  
    | |                    P2 is IDLE, /TYPING      
    | |  +-- /DISABLE   
    | |  |    +---------+       
    | |  |    |DigiSpark|
    | |  +----| P0      |
    +---------| P1 LED  |
      +-------| P2 I/P  |==> USB HID keyboard
              +---------+       

enable pullups on the inputs.
----|----|----|----|----|----|----|----|----|----|----|----|

The units type either fast or slow. When TYPING turn on the LED

Another solution

Inputs:
  P0 HALT   - stops typing - needed for reprogramming.
  P2 TYPING - hold off starting typing, type to end of sentence.
						  
Output: 
  P1 TYPING - Indicated Unit is TYPING SENTENCE.
  
	
* Type till end of the sentence
* Hold off starting until IDLE on P2 
* If interconnected, P1 output => P2 input
* Use weak pull ups on inputs. P2 HIGH when IDLE, so P1 HIGH when IDLE

P0 input  HALT - use to stop typing to reprogram
P2 input  HIGH = IDLE - default Pulled up.
P1 output LED OFF when TYPING, ON WHEN IDLE

modules
  [ holdoff logic ]  
    states: ( not typing ),( typing ), ( handover Sequence )

  [ typing engine ] - type up to GA 

  [ UC1 ]    [ UC2 ]  two micro controllers programmed as HID keyboards

Code expriments in JavaScript on this webpage.

  processUC_1(), processUC_2(), processUC_wiring() is called on a timer tick

Alternative Solution using Wired OR buss.


 
 -----+-------+---- Wired OR buss using Weak Pullup resistors
      |       |
   [ UC1 ] [ UC2 ]  two micro controllers programmed as HID keyboards
      
//
//  processUC_1 is instance 1 in one micro controller
//  processUC_2 is instance 2 in another micro controller
//  processUC_wiring is interconnect wiring
//
//  [ processUC_1 ] , [ processUC_wiring ] , [ processUC_2 ]
//
----|----|----|----|----|----|----|----|----|----|----|----|

              +---------+       
              |DigiSpark|
    +---------| P2 W-OR |==> USB HID keyboard
    | +-------| P1 LED  |
    |    +----| P0 I/P  |  
    |    |    +---------+   
    |    +-- /DISABLE      P0 is used to disable typing  
    |                      P1 is LED output  
    |                      P2 is IDLE, /TYPING      
    |    +-- /DISABLE   
    |    |    +---------+       
    |    |    |DigiSpark|
    |    +----| P0      |
    | +-------| P1 LED  |
    +---------| P2 W-OR |==> USB HID keyboard
              +---------+       

----|----|----|----|----|----|----|----|----|----|----|----|

P0 input  HALT - use to stop typing to reprogram
P2 Wired OR buss - Assert low while typing, Holdoff starting typing till high.
P1 output LED OFF when TYPING, ON WHEN IDLE

DigiSpark 1: Text to be typed.

ds1_P0
ds1_P2 connected to ds2_P1 else ds1_P2 = IDLE,1 else ds1_P2 = TYPING,0
HID_1:


DigiSpark 2: Text to be typed.

ds2_P0
ds2_P2 connected to ds1_P1 else ds2_P2 = IDLE,1 else ds2_P2 = TYPING,0
HID_2:


Pump the two character streams into different methods of collating to see what they look like.

comment:- Memory Leak.

this demo does not delete old text so it has a memory leak! If left to run for a long time the page gets slower and slower.

combined_app:


combined character by character


combined_words:


combined_paragraphs:

A--[ txBuffer ]----
B--[ rxBuffer ]----
===================
stream Timeline:-
===================
A--[ HI GA ]-----------------[Hello     ]-----[Hello     ]---[aaaaaaaaaaa]--------[ddddddd]--
B----------------[ HI GA ]-----[Hi]---------[hhhhhhhhhhhhh]----[bbbbbbbbbbb]---[ccccccc]----

Memory Leak

This demo does not delete old text so it is effectivly a memory leak! If left to run for a long time the page gets slower and slower


thoughts

There are two streams to be displayed together.

Options:

Display two lines:- received, transmitted.

Merge characters as they arrive.

Merge Words as they arrive.

Merge ParaGraphs as they arrive.

Add time Markers so split on.

The input needs to be display at least word by word.


Flushed
1:hsgdhsgdhs
2:khasahsksahk
---------------------			
Line1: jwhej kjwejk kjwhejkwle l
Line2: kwh  ek jknmnm ljkljj 
--------------
When Line1 or Line2 get too big flush some text out to the Flushed buffer.
Build up string consisting of a list of app + TRA interleaved.

opStr = opLogStr+

Issues:-

You could draw a timeline as characters are received.

If people are overtyping, then the bubbles split.

If the bubbles are split on GA, then the Bubbles can overlap in time.

A--[ txBuffer ]----
B--[ rxBuffer ]----

===================
stream Timeline:-
===================
A--[ HI GA ]-----------------[Hello     ]-----[Hello     ]---[aaaaaaaaaaa]--------[ddddddd]--
B----------------[ HI GA ]-----[Hi]---------[hhhhhhhhhhhhh]----[bbbbbbbbbbb]---[ccccccc]----

NON_OVERLAPPING            | OVERLAPPING  
A--[ HI GA ]---------------|--[Hello     ]-----[Hello ]------[aaaaaaaaaaa]--------[ddddddd]-----
B----------------[ HI GA ]-|----[Hi]---------[hhhhhhhhhhhhh]----[bbbbbbbbbbb]---[ccccccc]----

NON_OVERLAPPING            | OVERLAPPING WORDS 
A--[ HI GA ]---------------|--[Hello     ]----[Hello ]---[My ]--------[name ]-----[John ]----
B----------------[ HI GA ]-|----[Hi]---------[Bonjour ]----[what ]--[Description is ]---------

NON_OVERLAPPING            | OVERLAPPING Phases 
A--[ HI GA ]---------------|--[Hello     ]-----[Hello Bill ]---[aaaaaaaaaaa ]---[ddddddd ]--
B----------------[ HI GA ]-|----[Hi]---------[Bonjour ]----[bbbbbbbbbbb ]--[ccccccc ]----

NON_OVERLAPPING            | OVERLAPPING  SENTENCES WITH HANDOVER
A--[ HI GA ]---------------|--[Hello     ]-----[Hello   GA]-----[aaaaaaaaaaa GA]--------[ddddddd GA]--
B----------------[ HI GA ]-|----[Hi]---------[hhhhhhhhhhhhh GA]----[bbbbbbbbbbb GA]---[ccccccc GA]----

So do you have bubbles that are not overlapping, that overlap. If they overlap, does the text go at the start, middle, end? If you think there is an overlap, append tot he same bubble. How do you stop flicker?

Using the Leaky bucket load share:-

Leaky bucket load share uses buckets to pick a destination based of proportions. Add proportions to each bucket, onEachEvent add proportionally to each bucket. Pick the fullest bucket and empty.

Above we see the timelines put into bubbles by using the [bubble] notation. These need to be optimised to look nice.

The bubble must not span too much time. If both ends are typing, they can split and you get lots of small bubbles which use a lot of screen.

if both ends are typing, hold off spliting and fill the bubble more? Use a different background?

Work out a polynomial, that is used to work out when to split.

  • bubble size
  • bubble size of other person
  • next character is space
  • next character is end of sentence
  • time since start of the bubble
  • time since last text from both ends
  • Which end typed last.
  • 
    A--[ HI GA ]-----------------[Hello     ]-----[Hello     ]---[aaaaaaaaaaa]--------[ddddddd]--
    B----------------[ HI GA ]-----[Hi]---------[hhhhhhhhhhhhh]----[bbbbbbbbbbb]---[ccccccc]-----
    O--=========-----=========----===========---===============---==============---===========---
    
    

    Using a Countdown state machine:-

    When a character or word is received, bump up a value that is decremented to zero on a timer tick

    When it gets to empty, split.

    Leak each tick, fill when a character is received, leak when whitespace, empty if end of sentence.

    Add to both buckets when text is received.

    When white space is received leak more. If end of sentence, leak faster.

    Track who typed last. Count the number of words since other person typed.

    When empty consider a split.

    Raspberry Pi Pico

    Also https://github.com/hathach/tinyusb/tree/master/examples/device/hid_composite uses the PICO BOOTSEL button to trigger keyboard, mouse and Game controller events

    There is an example using the Rapsberry Pi Pico when to install the tools into the Arduino IDE. Install "Arduino Mbed OS RP2040 Boards". Adding this to the the Arduino IDE only takes a few minutes. I have yet to find a MicroPython example.

    Example:- Starting point to build out from. My PICOs cost six pounds

    #include "PluggableUSBHID.h"
    #include "USBKeyboard.h"
    
    USBKeyboard Keyboard;
    																							 
    void setup() {
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      delay(1000);
      Keyboard.printf("Hello world\n\r");
    }