element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum How to use Arduino Uno to connect USB keyboard to matrix keyboard?
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Verified Answer
  • Replies 8 replies
  • Answers 1 answer
  • Subscribers 393 subscribers
  • Views 1746 views
  • Users 0 members are here
  • ports
  • keyboard
  • matrix
  • usb
  • timing
  • uno
  • reducing
Related

How to use Arduino Uno to connect USB keyboard to matrix keyboard?

Former Member
Former Member over 12 years ago

Either I am looking in the wrong places or nobody has done this before.

 

What I am looking for is a way to read a USB keyboard that is attached to an extra USB port (as in the examples with D- and D+ to two/three? ports) and then write a matrix code to output.

 

To explain what I am trying to do in more detail. The old Sinclair ZX computers have a matrix keyboard.

For example the ZX81 has a 5x8 matrix. Five lines are selected one by one and pulled low over and over again. The pressed key pulls one out of 8 columns low. Shift key is special as it is the switch for the first bit only.

These membrane matrix keyboards tend to breakdown, their life expectancy is lower than 30 years :-)

So I'd like to find some way of using a standard USB keyboard instead.

 

I see several challenges:

 

1. Reading the USB keyboard. Looks like the USBHost library cannot be used for this???

 

2. Reading 5 lines (5x8 matrix) from the old retro computer line-select output (via interrupts), then if a character was received from the keyboard, translating it into 8 bit output. Should be doable as I know exactly which key is on what location, for instance if the current line is the first one, and a key '3' has been pressed without shift, then I can send a 00010000 byte, the first bit being shift. If the key was shift-3 (like '#' on some keyboards) then send 10010000.

 

3. Probably I got a shortage of ports on the Uno, if 3+5+8 are needed. Perhaps a way to feed a shift register with 8 bits output through one/two ports?

Or use the chipKIT Max32 that I have for this, hmmm lots more ports.

 

4. Somehow adjust to the timing factors of the old computer (keyboard repeats? control-shift-alt combinations?) and utilize buffers from the USB keyboard...

Of course the timing from the interrupts has the most important role. But I suspect the USB keyboard works with keypresses and releases, that might complicate things?

 

Can you guys please advise.

 

Regards, Martin

  • Sign in to reply
  • Cancel

Top Replies

  • Former Member
    Former Member over 10 years ago +1 verified
    Update. As no one solved this problem I have initiated a project for doing this. This project is finally finished: I have now an Arduino Uno with USB Host Shield, the USB Host Library 2.0 (from GitHub…
Parents
  • Former Member
    0 Former Member over 9 years ago

    See picture for the 4051 circuit (E is pin3). Using a 4066 for Shift 'bypass' to enable shifted keys (A0 to D0).

     

     

    image

    The Arduino Sketch code:

    #include
    <hidboot.h>

    #include
    <usbhub.h>

    //
    Satisfy IDE, which only needs to see the include statment in the ino.

    #ifdef
    dobogusinclude

    #include
    <spi4teensy3.h>

    #include
    <SPI.h>

    #endif

     

    // Version
    0.5, 30 April 2015 by Martin Ederveen, Flywheel IT.

    // This
    version includes the logic for transfer to 8x5 keyboard matrix.

    // Like
    used in 1980's computers as Sinclair ZX81.

    //
    Together with USB Shield on Arduino converts a USB keyboard to work with an 8x5

    //
    matrix, as used in a ZX81.

    //
    14-05-2015 changed output to bit coded version for use with CD74HC4051

     

    // Logic
    explained:

    // ZX81
    uses Address lines A8-A15 to scan the 8x5 keyboard matrix.

    // The
    scanning signal is a LOW in sequence on these lines.

    // If a
    key is pressed, a corresponding code will exist on Data lines D0-D4,

    //
    called KeyBD in on the ZX81, input lines into the ULA.

    // The
    Arduino enables the correct Address line and the corresponding Data lines.

    // It
    reads the USB input, translates the pressed key into Address (column) and

    // Data
    (row) codes and enables it through setting the corresponding output ports.

    // Shift
    is treated as an exception, as it is used together with other keys.

    // So it
    is enabled through a special port.

    // The logic
    is done through TTL hardware.

     

     

    boolean
    sh = false; // init Shift indicator

     

    class
    KbdRptParser : public KeyboardReportParser

    {

        void PrintKey(uint8_t mod, uint8_t key);

     

      protected:

        void OnControlKeysChanged(uint8_t before,
    uint8_t after);

     

        void OnKeyDown        (uint8_t mod, uint8_t key);

        void OnKeyUp              (uint8_t mod, uint8_t key);

        void OnKeyPressed(uint8_t key);

    };

     

    void
    KbdRptParser::PrintKey(uint8_t m, uint8_t key)

    {

      MODIFIERKEYS mod;

      *((uint8_t*)&mod) = m;

      Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");

      Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");

      Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");

      Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");

     

      Serial.print(" >");

      PrintHex<uint8_t>(key, 0x80);

      Serial.print("< ");

     

      Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");

      Serial.print((mod.bmRightShift  == 1) ? "S" : " ");

      Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");

      Serial.println((mod.bmRightGUI    == 1) ? "G" : " ");

      

    };

     

    void KbdRptParser::OnKeyDown(uint8_t
    mod, uint8_t key)

    {

      Serial.print("DN ");

      PrintKey(mod, key);

      uint8_t c = OemToAscii(mod, key);

     

      if (c) {

        OnKeyPressed(c);

     

        // Process the key that has been pressed

        ProcessKey(mod, key);

      }

    }

     

    void
    KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {

     

      MODIFIERKEYS beforeMod;

      *((uint8_t*)&beforeMod) = before;

     

      MODIFIERKEYS afterMod;

      *((uint8_t*)&afterMod) = after;

     

      if (beforeMod.bmLeftCtrl !=
    afterMod.bmLeftCtrl) {

        Serial.println("LeftCtrl
    changed");

      }

      if (beforeMod.bmLeftShift !=
    afterMod.bmLeftShift) {

        sh = !sh;

        if (sh) SetShift();

        else ResetShift();

     

        Serial.println("LeftShift
    changed");

      }

      if (beforeMod.bmLeftAlt !=
    afterMod.bmLeftAlt) {

        Serial.println("LeftAlt
    changed");

      }

      if (beforeMod.bmLeftGUI !=
    afterMod.bmLeftGUI) {

        Serial.println("LeftGUI
    changed");

      }

     

      if (beforeMod.bmRightCtrl !=
    afterMod.bmRightCtrl) {

        Serial.println("RightCtrl
    changed");

      }

      if (beforeMod.bmRightShift !=
    afterMod.bmRightShift) {

        sh = !sh;

        if (sh) SetShift();

        else ResetShift();

     

        Serial.println("RightShift
    changed");

      }

      if (beforeMod.bmRightAlt !=
    afterMod.bmRightAlt) {

        Serial.println("RightAlt
    changed");

      }

      if (beforeMod.bmRightGUI !=
    afterMod.bmRightGUI) {

        Serial.println("RightGUI
    changed");

      }

     

    }

     

    void
    KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)

    {

      Serial.print("UP ");

      PrintKey(mod, key);

     

      // Disable rows and columns

      DisableAll();

    }

     

    void
    KbdRptParser::OnKeyPressed(uint8_t key)

    {

      Serial.print("ASCII: ");

      Serial.println((char)key);

    };

     

    USB     Usb;

    //USBHub     Hub(&Usb);

    HIDBoot<HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);

     

    uint32_t
    next_time;

     

    KbdRptParser
    Prs;

     

    void
    setup()

    {

      Serial.begin( 115200 );

    #if
    !defined(__MIPSEL__)

      while (!Serial); // Wait for serial port to
    connect - used on Leonardo, Teensy and other boards with built-in USB CDC
    serial connection

    #endif

      Serial.println("Start");

     

      if (Usb.Init() == -1)

        Serial.println("OSC did not
    start.");

     

      delay( 200 );

     

      next_time = millis() + 5000;

     

      HidKeyboard.SetReportParser(0,
    (HIDReportParser*)&Prs);

     

     

    //
    Actually Port 0 and 1 are in use in this prototype, so cannnot use PORTD

    //
    Serialprint uses this, so unless deactivating serialprint, need to find

    //
    alternative ports

    // DDRD
    = B11111111; // sets Arduino port D, pins 0-7 as output

    //  PORTD = B11111111; // init all HIGH

     

     

      // Enable ports for A8-A15 address columns
    and D0-D4 data rows

      // using Arduino Port 2-7 for select, 8 for
    enable and 9 for Shift bypass

      // address lines A8-A15 select S0-S2

      pinMode(2, OUTPUT); // aS0

      pinMode(3, OUTPUT); // aS1

      pinMode(4, OUTPUT); // aS2

      // data lines D0-D4 select S0-S2

      pinMode(5, OUTPUT); // dS0

      pinMode(6, OUTPUT); // dS1

      pinMode(7, OUTPUT); // sS2

     

      // enable rows and columns

      pinMode(8, OUTPUT); // enable

     

      // Shift indicator bypasse enable

      pinMode(9, OUTPUT); // Shift

     

      // Init of all ports this way

      digitalWrite(2, HIGH); // init

      digitalWrite(3, HIGH); // init

      digitalWrite(4, HIGH); // init

      digitalWrite(5, HIGH); // init

      digitalWrite(6, HIGH); // init

      digitalWrite(7, HIGH); // init

      digitalWrite(8, HIGH); // init

      digitalWrite(9, LOW); // init

     

    }

     

    void SetShift()
    {

      digitalWrite(9, HIGH); // Shift = Yes

    }

     

    void
    ResetShift() {

      digitalWrite(9, LOW); // Shift = No

    }

     

    void
    DisableAll () {

      digitalWrite(8, HIGH); // disable

    }

     

    void
    EnableAll () {

      digitalWrite(8, LOW); // enable

    }

     

    void
    SelectA8() {

      digitalWrite(2, LOW);

      digitalWrite(3, LOW);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA9() {

      digitalWrite(2, HIGH);

      digitalWrite(3, LOW);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA10() {

      digitalWrite(2, LOW);

      digitalWrite(3, HIGH);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA11() {

      digitalWrite(2, HIGH);

      digitalWrite(3, HIGH);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA12() {

      digitalWrite(2, LOW);

      digitalWrite(3, LOW);

      digitalWrite(4, HIGH);

    }

     

    void
    SelectA13() {

      digitalWrite(2, HIGH);

      digitalWrite(3, LOW);

      digitalWrite(4, HIGH);

    }

     

    void
    SelectA14() {

      digitalWrite(2, LOW);

      digitalWrite(3, HIGH);

      digitalWrite(4, HIGH);

    }

     

    void
    SelectA15() {

      digitalWrite(2, HIGH);

      digitalWrite(3, HIGH);

      digitalWrite(4, HIGH);

    }

     

    void
    SetD0() {

      digitalWrite(5, LOW);

      digitalWrite(6, LOW);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD1() {

      digitalWrite(5, HIGH);

      digitalWrite(6, LOW);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD2() {

      digitalWrite(5, LOW);

      digitalWrite(6, HIGH);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD3() {

      digitalWrite(5, HIGH);

      digitalWrite(6, HIGH);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD4() {

      digitalWrite(5, LOW);

      digitalWrite(6, LOW);

      digitalWrite(7, HIGH);

      EnableAll();

    }

     

    void
    ProcessKey(uint8_t m, uint8_t key) {

     

      // Find the column for the key

      switch (key) {

     

        // A8 column

        case 0x1D : { // Z A8 and D1

          SetD1();

          SelectA8();

          break;

        }

        case 0x1B : { // X A8 and D2

          SetD2();

          SelectA8();

          break;

        }

        case 0x06 : { // C A8 and D3

          SetD3();

          SelectA8();

          break;

        }

        case 0x19 : { // V A8 and D4

          SetD4();

          SelectA8();

          break;

        }

     

    // A9
    column

        case 0x04 : { // A A9 and D0

          SetD0();

          SelectA9();

          break;

        }

        case 0x16 : { // S A9 and D1

          SetD1();

          SelectA9();

          break;

        }

        case 0x07 : { // D A9 and D2

          SetD2();

          SelectA9();

          break;

        }

        case 0x09 : { // F A9 and D3

        
    SetD3();

          SelectA9();

          break;

        }

        case 0x0A : { // G A9 and D4

          SetD4();

          SelectA9();

          break;

        }   

     

    // A10
    column

        case 0x14 : { // Q A10 and D0

          SetD0();

          SelectA10();

          break;

        }

        case 0x1A : { // W A10 and D1

          SetD1();

          SelectA10();

          break;

        }

        case 0x08 : { // E A10 and D2

          SetD2();

          SelectA10();

          break;

        }

        case 0x15 : { // R A10 and D3

          SetD3();

          SelectA10();

          break;

        }

        case 0x17 : { // T A10 and D4

          SetD4();

          SelectA10();

          break;

        }   

     

    // A11
    column

        case 0x1E : { // 1 A11 and D0

          SetD0();

          SelectA11();

          break;

        }

        case 0x1F : { // 2 A11 and D1

          SetD1();

          SelectA11();

          break;

        }

        case 0x20 : { // 3 A11 and D2

          SetD2();

          SelectA11();

          break;

        }

        case 0x21 : { // 4 A11 and D3

          SetD3();

          SelectA11();

          break;

        }

        case 0x22 : { // 5 A11 and D4

          SetD4();

          SelectA11();

          break;

        }

     

    // A12
    column

        case 0x27 : { // 0 A12 and D0

          SetD0();

          SelectA12();

          break;

        }

        case 0x26 : { // 9 A12 and D1

          SetD1();

          SelectA12();

          break;

        }

        case 0x25 : { // 8 A12 and D2

          SetD2();

          SelectA12();

          break;

        }

        case 0x24 : { // 7 A12 and D3

          SetD3();

          SelectA12();

          break;

        }

        case 0x23 : { // 6 A12 and D4

          SetD4();

          SelectA12();

          break;

        }

     

    // A13
    column

        case 0x13: { // P A13 and D0

          SetD0();

          SelectA13();

          break;

        }

        case 0x12 : { // O A13 and D1

          SetD1();

          SelectA13();

          break;

        }

        case 0x0C : { // I A13 and D2

          SetD2();

          SelectA13();

          break;

        }

        case 0x18 : { // U A13 and D3

          SetD3();

          SelectA13();

          break;

        }

        case 0x1C : { // Y A13 and D4

          SetD4();

          SelectA13();

          break;

        }

     

    // A14
    column

        case 0x28 : { // ENTER A14 and D0

          SetD0();

          SelectA14();

          break;

        }

        case 0x0F : { // L A14 and D1

          SetD1();

          SelectA14();

          break;

        }

        case 0x0E : { // K A14 and D2

          SetD2();

          SelectA14();

          break;

        }

        case 0x0D : { // J A14 and D3

          SetD3();

          SelectA14();

          break;

        }

        case 0x0B : { // H A14 and D4

          SetD4();

          SelectA14();

          break;

        }

     

    // A15
    column

        case 0x2C : { // SPACE A15 and D0

          SetD0();

          SelectA15();

          break;

        }

        case 0x37 : { // . A15 and D1

          SetD1();

          SelectA15();

          break;

        }

        case 0x10 : { // M A15 and D2

          SetD2();

          SelectA15();

          break;

        }

        case 0x11 : { // N A15 and D3

          SetD3();

          SelectA15();

          break;

        }

        case 0x05 : { // B A15 and D4

          SetD4();

          SelectA15();

          break;

        }

      }

    } // end
    ProcessKey

     

     

    void
    loop()

    {

      Usb.Task();

    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • Former Member
    0 Former Member over 9 years ago

    See picture for the 4051 circuit (E is pin3). Using a 4066 for Shift 'bypass' to enable shifted keys (A0 to D0).

     

     

    image

    The Arduino Sketch code:

    #include
    <hidboot.h>

    #include
    <usbhub.h>

    //
    Satisfy IDE, which only needs to see the include statment in the ino.

    #ifdef
    dobogusinclude

    #include
    <spi4teensy3.h>

    #include
    <SPI.h>

    #endif

     

    // Version
    0.5, 30 April 2015 by Martin Ederveen, Flywheel IT.

    // This
    version includes the logic for transfer to 8x5 keyboard matrix.

    // Like
    used in 1980's computers as Sinclair ZX81.

    //
    Together with USB Shield on Arduino converts a USB keyboard to work with an 8x5

    //
    matrix, as used in a ZX81.

    //
    14-05-2015 changed output to bit coded version for use with CD74HC4051

     

    // Logic
    explained:

    // ZX81
    uses Address lines A8-A15 to scan the 8x5 keyboard matrix.

    // The
    scanning signal is a LOW in sequence on these lines.

    // If a
    key is pressed, a corresponding code will exist on Data lines D0-D4,

    //
    called KeyBD in on the ZX81, input lines into the ULA.

    // The
    Arduino enables the correct Address line and the corresponding Data lines.

    // It
    reads the USB input, translates the pressed key into Address (column) and

    // Data
    (row) codes and enables it through setting the corresponding output ports.

    // Shift
    is treated as an exception, as it is used together with other keys.

    // So it
    is enabled through a special port.

    // The logic
    is done through TTL hardware.

     

     

    boolean
    sh = false; // init Shift indicator

     

    class
    KbdRptParser : public KeyboardReportParser

    {

        void PrintKey(uint8_t mod, uint8_t key);

     

      protected:

        void OnControlKeysChanged(uint8_t before,
    uint8_t after);

     

        void OnKeyDown        (uint8_t mod, uint8_t key);

        void OnKeyUp              (uint8_t mod, uint8_t key);

        void OnKeyPressed(uint8_t key);

    };

     

    void
    KbdRptParser::PrintKey(uint8_t m, uint8_t key)

    {

      MODIFIERKEYS mod;

      *((uint8_t*)&mod) = m;

      Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");

      Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");

      Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");

      Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");

     

      Serial.print(" >");

      PrintHex<uint8_t>(key, 0x80);

      Serial.print("< ");

     

      Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");

      Serial.print((mod.bmRightShift  == 1) ? "S" : " ");

      Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");

      Serial.println((mod.bmRightGUI    == 1) ? "G" : " ");

      

    };

     

    void KbdRptParser::OnKeyDown(uint8_t
    mod, uint8_t key)

    {

      Serial.print("DN ");

      PrintKey(mod, key);

      uint8_t c = OemToAscii(mod, key);

     

      if (c) {

        OnKeyPressed(c);

     

        // Process the key that has been pressed

        ProcessKey(mod, key);

      }

    }

     

    void
    KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {

     

      MODIFIERKEYS beforeMod;

      *((uint8_t*)&beforeMod) = before;

     

      MODIFIERKEYS afterMod;

      *((uint8_t*)&afterMod) = after;

     

      if (beforeMod.bmLeftCtrl !=
    afterMod.bmLeftCtrl) {

        Serial.println("LeftCtrl
    changed");

      }

      if (beforeMod.bmLeftShift !=
    afterMod.bmLeftShift) {

        sh = !sh;

        if (sh) SetShift();

        else ResetShift();

     

        Serial.println("LeftShift
    changed");

      }

      if (beforeMod.bmLeftAlt !=
    afterMod.bmLeftAlt) {

        Serial.println("LeftAlt
    changed");

      }

      if (beforeMod.bmLeftGUI !=
    afterMod.bmLeftGUI) {

        Serial.println("LeftGUI
    changed");

      }

     

      if (beforeMod.bmRightCtrl !=
    afterMod.bmRightCtrl) {

        Serial.println("RightCtrl
    changed");

      }

      if (beforeMod.bmRightShift !=
    afterMod.bmRightShift) {

        sh = !sh;

        if (sh) SetShift();

        else ResetShift();

     

        Serial.println("RightShift
    changed");

      }

      if (beforeMod.bmRightAlt !=
    afterMod.bmRightAlt) {

        Serial.println("RightAlt
    changed");

      }

      if (beforeMod.bmRightGUI !=
    afterMod.bmRightGUI) {

        Serial.println("RightGUI
    changed");

      }

     

    }

     

    void
    KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)

    {

      Serial.print("UP ");

      PrintKey(mod, key);

     

      // Disable rows and columns

      DisableAll();

    }

     

    void
    KbdRptParser::OnKeyPressed(uint8_t key)

    {

      Serial.print("ASCII: ");

      Serial.println((char)key);

    };

     

    USB     Usb;

    //USBHub     Hub(&Usb);

    HIDBoot<HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);

     

    uint32_t
    next_time;

     

    KbdRptParser
    Prs;

     

    void
    setup()

    {

      Serial.begin( 115200 );

    #if
    !defined(__MIPSEL__)

      while (!Serial); // Wait for serial port to
    connect - used on Leonardo, Teensy and other boards with built-in USB CDC
    serial connection

    #endif

      Serial.println("Start");

     

      if (Usb.Init() == -1)

        Serial.println("OSC did not
    start.");

     

      delay( 200 );

     

      next_time = millis() + 5000;

     

      HidKeyboard.SetReportParser(0,
    (HIDReportParser*)&Prs);

     

     

    //
    Actually Port 0 and 1 are in use in this prototype, so cannnot use PORTD

    //
    Serialprint uses this, so unless deactivating serialprint, need to find

    //
    alternative ports

    // DDRD
    = B11111111; // sets Arduino port D, pins 0-7 as output

    //  PORTD = B11111111; // init all HIGH

     

     

      // Enable ports for A8-A15 address columns
    and D0-D4 data rows

      // using Arduino Port 2-7 for select, 8 for
    enable and 9 for Shift bypass

      // address lines A8-A15 select S0-S2

      pinMode(2, OUTPUT); // aS0

      pinMode(3, OUTPUT); // aS1

      pinMode(4, OUTPUT); // aS2

      // data lines D0-D4 select S0-S2

      pinMode(5, OUTPUT); // dS0

      pinMode(6, OUTPUT); // dS1

      pinMode(7, OUTPUT); // sS2

     

      // enable rows and columns

      pinMode(8, OUTPUT); // enable

     

      // Shift indicator bypasse enable

      pinMode(9, OUTPUT); // Shift

     

      // Init of all ports this way

      digitalWrite(2, HIGH); // init

      digitalWrite(3, HIGH); // init

      digitalWrite(4, HIGH); // init

      digitalWrite(5, HIGH); // init

      digitalWrite(6, HIGH); // init

      digitalWrite(7, HIGH); // init

      digitalWrite(8, HIGH); // init

      digitalWrite(9, LOW); // init

     

    }

     

    void SetShift()
    {

      digitalWrite(9, HIGH); // Shift = Yes

    }

     

    void
    ResetShift() {

      digitalWrite(9, LOW); // Shift = No

    }

     

    void
    DisableAll () {

      digitalWrite(8, HIGH); // disable

    }

     

    void
    EnableAll () {

      digitalWrite(8, LOW); // enable

    }

     

    void
    SelectA8() {

      digitalWrite(2, LOW);

      digitalWrite(3, LOW);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA9() {

      digitalWrite(2, HIGH);

      digitalWrite(3, LOW);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA10() {

      digitalWrite(2, LOW);

      digitalWrite(3, HIGH);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA11() {

      digitalWrite(2, HIGH);

      digitalWrite(3, HIGH);

      digitalWrite(4, LOW);

    }

     

    void
    SelectA12() {

      digitalWrite(2, LOW);

      digitalWrite(3, LOW);

      digitalWrite(4, HIGH);

    }

     

    void
    SelectA13() {

      digitalWrite(2, HIGH);

      digitalWrite(3, LOW);

      digitalWrite(4, HIGH);

    }

     

    void
    SelectA14() {

      digitalWrite(2, LOW);

      digitalWrite(3, HIGH);

      digitalWrite(4, HIGH);

    }

     

    void
    SelectA15() {

      digitalWrite(2, HIGH);

      digitalWrite(3, HIGH);

      digitalWrite(4, HIGH);

    }

     

    void
    SetD0() {

      digitalWrite(5, LOW);

      digitalWrite(6, LOW);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD1() {

      digitalWrite(5, HIGH);

      digitalWrite(6, LOW);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD2() {

      digitalWrite(5, LOW);

      digitalWrite(6, HIGH);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD3() {

      digitalWrite(5, HIGH);

      digitalWrite(6, HIGH);

      digitalWrite(7, LOW);

      EnableAll();

    }

     

    void
    SetD4() {

      digitalWrite(5, LOW);

      digitalWrite(6, LOW);

      digitalWrite(7, HIGH);

      EnableAll();

    }

     

    void
    ProcessKey(uint8_t m, uint8_t key) {

     

      // Find the column for the key

      switch (key) {

     

        // A8 column

        case 0x1D : { // Z A8 and D1

          SetD1();

          SelectA8();

          break;

        }

        case 0x1B : { // X A8 and D2

          SetD2();

          SelectA8();

          break;

        }

        case 0x06 : { // C A8 and D3

          SetD3();

          SelectA8();

          break;

        }

        case 0x19 : { // V A8 and D4

          SetD4();

          SelectA8();

          break;

        }

     

    // A9
    column

        case 0x04 : { // A A9 and D0

          SetD0();

          SelectA9();

          break;

        }

        case 0x16 : { // S A9 and D1

          SetD1();

          SelectA9();

          break;

        }

        case 0x07 : { // D A9 and D2

          SetD2();

          SelectA9();

          break;

        }

        case 0x09 : { // F A9 and D3

        
    SetD3();

          SelectA9();

          break;

        }

        case 0x0A : { // G A9 and D4

          SetD4();

          SelectA9();

          break;

        }   

     

    // A10
    column

        case 0x14 : { // Q A10 and D0

          SetD0();

          SelectA10();

          break;

        }

        case 0x1A : { // W A10 and D1

          SetD1();

          SelectA10();

          break;

        }

        case 0x08 : { // E A10 and D2

          SetD2();

          SelectA10();

          break;

        }

        case 0x15 : { // R A10 and D3

          SetD3();

          SelectA10();

          break;

        }

        case 0x17 : { // T A10 and D4

          SetD4();

          SelectA10();

          break;

        }   

     

    // A11
    column

        case 0x1E : { // 1 A11 and D0

          SetD0();

          SelectA11();

          break;

        }

        case 0x1F : { // 2 A11 and D1

          SetD1();

          SelectA11();

          break;

        }

        case 0x20 : { // 3 A11 and D2

          SetD2();

          SelectA11();

          break;

        }

        case 0x21 : { // 4 A11 and D3

          SetD3();

          SelectA11();

          break;

        }

        case 0x22 : { // 5 A11 and D4

          SetD4();

          SelectA11();

          break;

        }

     

    // A12
    column

        case 0x27 : { // 0 A12 and D0

          SetD0();

          SelectA12();

          break;

        }

        case 0x26 : { // 9 A12 and D1

          SetD1();

          SelectA12();

          break;

        }

        case 0x25 : { // 8 A12 and D2

          SetD2();

          SelectA12();

          break;

        }

        case 0x24 : { // 7 A12 and D3

          SetD3();

          SelectA12();

          break;

        }

        case 0x23 : { // 6 A12 and D4

          SetD4();

          SelectA12();

          break;

        }

     

    // A13
    column

        case 0x13: { // P A13 and D0

          SetD0();

          SelectA13();

          break;

        }

        case 0x12 : { // O A13 and D1

          SetD1();

          SelectA13();

          break;

        }

        case 0x0C : { // I A13 and D2

          SetD2();

          SelectA13();

          break;

        }

        case 0x18 : { // U A13 and D3

          SetD3();

          SelectA13();

          break;

        }

        case 0x1C : { // Y A13 and D4

          SetD4();

          SelectA13();

          break;

        }

     

    // A14
    column

        case 0x28 : { // ENTER A14 and D0

          SetD0();

          SelectA14();

          break;

        }

        case 0x0F : { // L A14 and D1

          SetD1();

          SelectA14();

          break;

        }

        case 0x0E : { // K A14 and D2

          SetD2();

          SelectA14();

          break;

        }

        case 0x0D : { // J A14 and D3

          SetD3();

          SelectA14();

          break;

        }

        case 0x0B : { // H A14 and D4

          SetD4();

          SelectA14();

          break;

        }

     

    // A15
    column

        case 0x2C : { // SPACE A15 and D0

          SetD0();

          SelectA15();

          break;

        }

        case 0x37 : { // . A15 and D1

          SetD1();

          SelectA15();

          break;

        }

        case 0x10 : { // M A15 and D2

          SetD2();

          SelectA15();

          break;

        }

        case 0x11 : { // N A15 and D3

          SetD3();

          SelectA15();

          break;

        }

        case 0x05 : { // B A15 and D4

          SetD4();

          SelectA15();

          break;

        }

      }

    } // end
    ProcessKey

     

     

    void
    loop()

    {

      Usb.Task();

    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube