Wrong character output

Hey guys,

I am trying to build a buttonbox for Elite Dangerous.
Using the Arduino micro Pro board with pushbuttons and rotary encoders.
I connected all buttons and encoders. Uploaded the sketch.
And with every button I push or encoder I turn the 'TX' led lights up sending a character.

But the characters are not the ones I put in the matrix.

I get random characters instead of the ones I put in the sketch.
Can this be related to the keyboard.h file?
Here is the sketch I am trying to get working.

#include <Keypad.h>
#include <Keyboard.h>


#define ENABLE_PULLUPS
#define NUMROTARIES 4
#define NUMBUTTONS 25
#define NUMROWS 5
#define NUMCOLS 5


//define the symbols on the buttons of the keypads
char buttons[NUMROWS][NUMCOLS] = {
  {'q','w','e','r','t'},
  {'y','u','i','o','p'},
  {'a','z','d','f','g'},
  {'h','j','k','l','m'},
  {'x','c','v','b','n'},
};



struct rotariesdef {
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;æ³²ú®é塤©
};

rotariesdef rotaries[NUMROTARIES] {
  {0,1,KEY_RIGHT_ARROW,KEY_LEFT_ARROW,0},
  {2,3,KEY_DOWN_ARROW,KEY_UP_ARROW,0},
  {4,5,KEY_PAGE_UP,KEY_PAGE_DOWN,0},
  {6,7,KEY_HOME,KEY_END,0},
};


// 
//Encoders code from Ben Buxton
//More info: http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
// 

#define DIR_CCW 0x10
#define DIR_CW 0x20

#define R_START 0x0
#define R_CW_FINAL 0x1
©#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};


byte rowPins[NUMROWS] = {21,20,19,18,15}; //connect to the row pinouts of the keypad
byte colPins[NUMCOLS] = {14,16,10,9,8}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS); 



void setup() {
  Keyboard.begin();
  rotary_init();
}



void loop() { 

  CheckAllEncoders();

  CheckAllButtons();

}


void CheckAllButtons(void) {
  char key = buttbx.getKey();
  if (key != NO_KEY)  {
    Keyboard.press(KEY_LEFT_CTRL);
    Keyboard.press(KEY_LEFT_ALT);
    Keyboard.press(key);
    delay(150);
    Keyboard.releaseAll();
  }//Keyboard.write(key);
}


/* Call this once in setup(). */
void rotary_init() {
  for (int i=0;i<NUMROTARIES;i++) {
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
    #ifdef ENABLE_PULLUPS
      digitalWrite(rotaries[i].pin1, HIGH);
      digitalWrite(rotaries[i].pin2, HIGH);
    #endif
  }
}


/* Read input pins and process for events. Call this either from a
 * loop or an interrupt (eg pin change or timer).
 *
 * Returns 0 on no event, otherwise 0x80 or 0x40 depending on the direction.
 */
unsigned char rotary_process(int _i) {
   unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
  rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
  return (rotaries[_i].state & 0x30);
}

void CheckAllEncoders(void) {
  for (int i=0;i<NUMROTARIES;i++) {
    unsigned char result = rotary_process(i);
    if (result) {
      Keyboard.write(result == DIR_CCW ? rotaries[i].ccwchar : rotaries[i].cwchar ); 
    }
  }
}

The character’s can’t be random .

Have a look at ascii codes and see if you can work out what you are getting .

Also bear in mind “print” “ write” “ read” “char”, “byte” can give differing results .

If you add some print statement through your code you can debug and find out what’s going on .

1 Like

what is it?

why you sending Ctrl and Alt?

Do you get a repeatable "random character", if you press the same button?

#include <Keyboard.h>

#define ENABLE_PULLUPS
#define NUMROTARIES 4
#define NUMBUTTONS 25
#define NUMROWS 5
#define NUMCOLS 5

const uint8_t KeyCode[NUMROWS][NUMCOLS] = {
  {0x71,0x77,0x65,0x72,0x74},//'q', 'w', 'e', 'r', 't'
  {0x7A,0x75,0x69,0x6F,0x70},//'y', 'u', 'i', 'o', 'p'
  {0x61,0x79,0x64,0x66,0x67},//'a', 'z', 'd', 'f', 'g'
  {0x68,0x6A,0x6B,0x6C,0x6D},//'h', 'j', 'k', 'l', 'm'
  {0x78,0x63,0x76,0x64,0x6E} //'x', 'c', 'v', 'b', 'n'
};

struct rotariesdef {
  byte pin1;
  byte pin2;
  byte ccwchar;
  byte cwchar;
  byte state;
};

rotariesdef rotaries[NUMROTARIES] {
  {0, 1, KEY_RIGHT_ARROW, KEY_LEFT_ARROW, 0},
  {2, 3, KEY_DOWN_ARROW, KEY_UP_ARROW, 0},
  {4, 5, KEY_PAGE_UP, KEY_PAGE_DOWN, 0},
  {6, 7, KEY_HOME, KEY_END, 0},
};

#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const byte ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};

byte rowPins[NUMROWS] = {21, 20, 19, 18, 15}; //connect to the row pinouts of the keypad
byte colPins[NUMCOLS] = {14, 16, 10, 9, 8}; //connect to the column pinouts of the keypad

void setup() {
  Keyboard.begin();
  rotary_init();
}

void loop() {
  CheckAllEncoders();
  CheckAllButtons();
}

void CheckAllButtons(void) {
  for (byte c = 0; c < NUMCOLS; c++) {
    pinMode(colPins[c], OUTPUT);
    digitalWrite(colPins[c], LOW); // Begin column pulse output.
    for (byte r = 0; r < NUMROWS; r++)if (!digitalRead(rowPins[r]))Keyboard.write(KeyCode[r][c]);
    pinMode(colPins[c], INPUT_PULLUP);
  }
}

void rotary_init() {
  for (int i = 0; i < NUMROTARIES; i++) {
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
#ifdef ENABLE_PULLUPS
    digitalWrite(rotaries[i].pin1, HIGH);
    digitalWrite(rotaries[i].pin2, HIGH);
#endif
  }
  for (byte r = 0; r < NUMROWS; r++) {
    pinMode(rowPins[r], INPUT_PULLUP);
  }
}

unsigned char rotary_process(int _i) {
  unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
  rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
  return (rotaries[_i].state & 0x30);
}

void CheckAllEncoders(void) {
  for (int i = 0; i < NUMROTARIES; i++) {
    unsigned char result = rotary_process(i);
    if (result) {
      Keyboard.write(result == DIR_CCW ? rotaries[i].ccwchar : rotaries[i].cwchar );
    }
  };
}

have you tried dramatically simplifying your code to just send a known set of characters?
Do you then se what you expect?

1 Like

Yes, for instance where I expect the 'y' charactar the 'ĂĽ' appears.
So there are characters being sent, just not the ones I define in the rows and columns.
Some are replaced with a simple space or even a graphic character like the copyright sign.

The encoder part is working as it should.

And the answer is ?

1 Like

Wiring, probably a missing ground.

Yes,I get the same character when I push a button. Just not the one I specified.

Checked the ascii codes assigned to the buttons and it checked out to be Okay.

This will sound strange, but, tap on the connecting wires and watch the Serial Monitor.

Post a wiring drawing... it may prove useful.

Are you still adding CTRK and ALT to the key?

Try it with just the buttons, and no modifiers:

void loop() { 
//  CheckAllEncoders();
  CheckAllButtons();
}

void CheckAllButtons(void) {
  char key = buttbx.getKey();
  if (key != NO_KEY)  {
//    Keyboard.press(KEY_LEFT_CTRL);
//    Keyboard.press(KEY_LEFT_ALT);
    Keyboard.press(key);
    delay(150);
    Keyboard.releaseAll();
  }//Keyboard.write(key);
}

a7
1 Like

Hi, @sscholten_arduino
Welcome to the forum.

Do you have a DMM? (Digital MultiMeter)

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like

Print and write produce different results , see the ref for these instructions . It may or may not be the cause .

Try some simple code just printing then writing a value as a char or a byte then reading as char , byte etc .
The results are very different !!

Random characters could be a sign of a floating input. Make sure you’ve enabled the internal pull-ups correctly or added external pull-up resistors. Also, try adding some debouncing to your buttons and encoders; it might help stabilize the input signals.

Thanks to all those with tips and suggestions.
I got the thing working by removing the lines about pressing lft ctrl and lft alt keys.

Topic may be closed.