4x3 Matrix Keypad and USBKeyboard emulation

Hello guys,
I want to create a custom panel for my online simulator using matrix keypad 4x3 and library USBKeyboard that can send key stroke to pc for simulate the normal usb keyboard.
my idea is the follow:
ARDUINO UNO board, connect the keypad with an IC PCF8574P( with address 0x20) and wire library for use only two wire, use the usb shield with 2 diode (zener 3,6v 0,5w) and three resistors.
I try to write a code for that project but don't work. but if i use only one code this work fine, in order if i simulate a USBkeyboard with one switch it works and if i use only the two wire keypad it works fine but if i combine both not working.

the code is the follow:

#include "UsbKeyboard.h"
#include <Wire.h>
#include <i2ckeypad.h>

#define ROWS 4
#define COLS 3

//matrix keypad Address
#define PCF8574_ADDR 0x20

//Object keypad
i2ckeypad kpd = i2ckeypad(PCF8574_ADDR, ROWS, COLS);


char key;

void setup()
{
   // Disable timer0 since it can mess with the USB timing. Note that
  // this means some functions such as delay() will no longer work.
  TIMSK0&=!(1<<TOIE0);

  // Clear interrupts while performing time-critical operations
 cli();

  // Force re-enumeration so the host will detect us
  usbDeviceDisconnect();
  delayMs(250);
  usbDeviceConnect();

  // Set interrupts again
  sei();

  Wire.begin();  //inizialize Wire library
  kpd.init();    //inizialize object keypad
  
}

void loop()
{
  UsbKeyboard.update();

 key=kpd.get_key();
 
  if (key != ' \0 ') {
    UsbKeyboard.sendKeyStroke(KEY_H, MOD_SHIFT_LEFT);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_O);
    UsbKeyboard.sendKeyStroke(KEY_SPACE);
    UsbKeyboard.sendKeyStroke(KEY_W, MOD_SHIFT_LEFT);
    UsbKeyboard.sendKeyStroke(KEY_O);
    UsbKeyboard.sendKeyStroke(KEY_R);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_D);
    UsbKeyboard.sendKeyStroke(KEY_ENTER);
    
  }

}

/**
* Define our own delay function so that we don't have to rely on
* operation of timer0, the interrupt used by the internal delay()
*/
void delayMs(unsigned int ms)
{
  for (int i = 0; i < ms; i++) {
    delayMicroseconds(1000);
  }
}

i don't have idea why isn't working, i spent three days but i don't understand why =( =( =(

i wait for you help me! :slight_smile: :slight_smile:

Which USB shield are your using? The USB Host Shield?

The easiest for you is to use an Arduino Leonardo because it has the necessary USB interface integrated into the processor. With the UNO you have the necessary hardware onboard too but you'll have to program the ATmega16U2 with an ICSP to get what you want.
I never used the USB host shield so I don't know if it's able to be a USB slave too.

Thanks pylon for replay, the shield that i use is the follow in the link http://www.practicalarduino.com/projects/virtual-usb-keyboard
And its stand alone working, but if combine with the heypad nothing is ok s =(

Thanks a lot
marko86

If you have both connected, what exactly is going wrong? Do you register no key strokes? Do you get the wrong keys? Is the transmission to the host incorrect?

Not working is not really a description of a problem... :slight_smile:

Pylon,
Thanks for replay, the problem is the instruction:
char key=kpd.get_key();
in the loop, infact if i comment that instruction the USB peripheral is recognize perfectly. But the problem is that, this instruction read the data from keypad and without that i cannot send nothing, because i cannot read the data from keypad! :astonished:

Is a Conflict but i don't know why, i have no error during the compiling and burning of chip! =( =(

Have you tried using just the keypad alone, sending the output to the serial interface?

Have you checked the wiring? Try making a picture of the wiring and post it. The code that you identified as the problem is asking for the status of the keypad. If the keypad does not answer because it's wired incorrectly, the Arduino is waiting forever.

I try with sketch separately and they working fine without problem.
for the wiring is the default of library for both (USB and KeyBoard).
but is that instruction that cause the problem: char key=kpd.get_key();

the problem is, if i connect the usb port out of arduino for emulate the keyboard without that instruction, it works, but if i connect the arduino with that instruction (char key=kpd.get_key():wink: the usc isn't recognized from my pc.

Try commenting out the following line in your code:

// TIMSK0&=!(1<<TOIE0);

Although I cannot find any code part in i2ckeypad and Wire libraries that use delay(), millis() or micros(), it may be that I missed something. If it works with this modification we know at least where to look in more detail.

Am I getting you right, that it works if you just comment out the kpd.get_key() call but leave the kpd.init() call in?

What changes have you done to the ic2keypad library (you must have done changes because the version linked in the playground does not compile in current IDE versions)? Post your version to let us see the changes.

Hi Thanks for replay,

i try to comment the timer but nothing change, the error to recognize the USB device is the same.
i leave the inizialization of keypad (kpd.init()) but only if i comment the kpd.get_key() it works.

it's so strange!! :~ :~