keyboard hack

hello !

I’m currently working on a project in which I want to control two mobile phones synchronously through keyboard hacking.
The method I used for keyboard hacking is the following one : since it’s a “matrix” keyboard, I first search what is the circuit of rows and columns, how the keys’ pins are connected together. The phone I chose for this project has 23 keys, selected by 6 rows and 4 columns (see schematic below).

Then, I use 2 multiplexers (one for the rows, the other for the columns) and connect their common input/output pin. Finally, by setting a specific address for each multiplexer, I’m able to select a specific row and key, and so make a connection between them and simulate a key press. Key release is made by sending a high voltage to “inhibit pin” of both multiplexers.
Here is the whole schematic (arduino controlling 2 phones) :

The phone are controlled by a Puredata patch that sends bytes to the arduino board over COM port. Each keyboard key matches a specific number, plus one for the key release, as you can read in the arduino sketch in comments.

//  TabIndex      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22
int KeyCol[23] = {2, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 2, 2, 4, 4, 1, 3, 1, 3, 1, 3, 4, 4};
int KeyRow[23] = {6, 3, 3, 3, 4, 4, 4, 5, 5, 5, 3, 1, 2, 1, 2, 2, 2, 1, 1, 6, 6, 5, 4};
//  KeyIndex      0  1  2  3  4  5  6  7  8  9 OK  <  > up dw GR RD c< >c  *  # v+ v-

/*
      index  |  key                 index  |  key
      24  0  =  0                   36 12  =  Right
      25  1  =  1                   37 13  =  Up
      26  2  =  2                   38 14  =  Down
      27  3  =  3                   39 15  =  Green phone
      28  4  =  4                   40 16  =  Red phone
      29  5  =  5                   41 17  =  Ctrl Left
      30  6  =  6                   42 18  =  Ctrl Right
      31  7  =  7                   43 19  =  *
      32  8  =  8                   44 20  =  #
      33  9  =  9                   45 21  =  Vol+
      34 10  =  Enter/Valid         46 22  =  Vol-
      35 11  =  Left                57 23  = (--release key--)
*/

int phoneFPin[2] = {2, 8}; // First pin of parallel control of multiplexers

 /*                          Parallel MUX Port pins
  *              col.A   col.B   row.A   row.B   row.C   inhib
  *    phone1      2       3       4       5       6       7
  *    phone2      8       9      10      11      12      13  
  */

void setup() {
  // start COMmunication with software
  Serial.begin(9600);

  // set all muxer's control pins to OUTPUT
  for (int ph = 0; ph < 2; ph++) {
    for (int i = phoneFPin[ph] ; i < (phoneFPin[ph] + 6); i++) {
      pinMode(i, OUTPUT);
    }  
  }  
  inhibit(1, 0); // release key on phone 1
  inhibit(1, 1); // release key on phone 2
  Serial.flush();
  delay(10);
}

void loop() 
{
  if (Serial.available() > 0)
  {
    int newcom = Serial.read();
    ExecCommand(newcom);
  }
}

void ExecCommand(int Command)
{
  int phone;
  
  // detect if input command is for phone 1 or 2
  if (Command >= 24)  
  {
    phone = 1;
    Command = Command - 24;
  }
  else
  {
    phone = 0;
  }
  
  // release key (disable connection between both multiplexer common in/out)
  inhibit(1, phone);
  delay(1);  
  
  if (Command != 23)
  {
  
  // check row & columns addresses  
  unsigned int C = KeyCol[Command] - 1; //-1 because multiplexer index start at 0
  unsigned int R = KeyRow[Command] - 1;  
  
  // combinate both row & columns on 1 port (5 bits > 5 digital outputs)  
  R = R << 2;                           
  unsigned int muxCode = C ^ R;

  if (phone == 0) PORTD = muxCode << 2;
    else PORTB = muxCode;

  // once address is set, press key (close multiplexer circuit)
  delay(1);  
  inhibit(0, phone);
  } 
  else // if command is 23 then release key (inhibit HIGH)
  {
    inhibit(1, phone);
  }
  delay(5);
  return;
}

void inhibit(boolean state, int phone) 
{
  digitalWrite(phoneFPin[phone]+5, state);
}

This is so beautiful, isn’t it ?
Well, it works, but not perfectly. And I need to have it working PERFECTLY !
Sometimes, some keys are “muted” and do not respond, and sometimes one keypress command acts as two presses.

For more precisions, the Puredata patch can be downloaded here :
http://phae.fr/bazar/controlKeyboard_2.pd

Of course I tried various intervalls between the key press and key release.

I suspect the clock of the phone (but shouldn’t be so slow ?), some resistance in the wires (how could it be pulled), or a problem with the speed of this kind of multiplexers.
Or something I din’t think about…
Any ideas ?

no ideas, critics on the method, or test i could make ?
please help me !!!

Maybe found something by myself...

First, I tried to suppress the serial communication part with puredata, and include a "keypress sequence" directly on the ATMega, but the problems remain.

Then, I tried this idea of pulling resistors... I'm not very used to this "pulling thing" idea... but I added one 1 KOhms resistor between the common in/out of both multiplexers, and for each a 10 KOhms resistor between VSS and GND. Seem to work much better with this ! Well, the sequence is quite slow : - a key stay pressed about 25O msecs - there's about 1 second between each keypress command

But it works quite well for now with a 10 stage sequence...

I'd be glad to have some explainations about the pulling resistor... any link or something !

Cheers,