Announcement

Collapse

Forum Rules and Etiquette

Our mission ...

This forum is part of our mission to promote the preservation of vintage computers through education and outreach. (In real life we also run events and have a museum.) We encourage you to join us, participate, share your knowledge, and enjoy.

This forum has been around in this format for over 15 years. These rules and guidelines help us maintain a healthy and active community, and we moderate the forum to keep things on track. Please familiarize yourself with these rules and guidelines.


Rule 1: Remain civil and respectful

There are several hundred people who actively participate here. People come from all different backgrounds and will have different ways of seeing things. You will not agree with everything you read here. Back-and-forth discussions are fine but do not cross the line into rude or disrespectful behavior.

Conduct yourself as you would at any other place where people come together in person to discuss their hobby. If you wouldn't say something to somebody in person, then you probably should not be writing it here.

This should be obvious but, just in case: profanity, threats, slurs against any group (sexual, racial, gender, etc.) will not be tolerated.


Rule 2: Stay close to the original topic being discussed
  • If you are starting a new thread choose a reasonable sub-forum to start your thread. (If you choose incorrectly don't worry, we can fix that.)
  • If you are responding to a thread, stay on topic - the original poster was trying to achieve something. You can always start a new thread instead of potentially "hijacking" an existing thread.



Rule 3: Contribute something meaningful

To put things in engineering terms, we value a high signal to noise ratio. Coming here should not be a waste of time.
  • This is not a chat room. If you are taking less than 30 seconds to make a post then you are probably doing something wrong. A post should be on topic, clear, and contribute something meaningful to the discussion. If people read your posts and feel that their time as been wasted, they will stop reading your posts. Worse yet, they will stop visiting and we'll lose their experience and contributions.
  • Do not bump threads.
  • Do not "necro-post" unless you are following up to a specific person on a specific thread. And even then, that person may have moved on. Just start a new thread for your related topic.
  • Use the Private Message system for posts that are targeted at a specific person.


Rule 4: "PM Sent!" messages (or, how to use the Private Message system)

This forum has a private message feature that we want people to use for messages that are not of general interest to other members.

In short, if you are going to reply to a thread and that reply is targeted to a specific individual and not of interest to anybody else (either now or in the future) then send a private message instead.

Here are some obvious examples of when you should not reply to a thread and use the PM system instead:
  • "PM Sent!": Do not tell the rest of us that you sent a PM ... the forum software will tell the other person that they have a PM waiting.
  • "How much is shipping to ....": This is a very specific and directed question that is not of interest to anybody else.


Why do we have this policy? Sending a "PM Sent!" type message basically wastes everybody else's time by making them having to scroll past a post in a thread that looks to be updated, when the update is not meaningful. And the person you are sending the PM to will be notified by the forum software that they have a message waiting for them. Look up at the top near the right edge where it says 'Notifications' ... if you have a PM waiting, it will tell you there.

Rule 5: Copyright and other legal issues

We are here to discuss vintage computing, so discussing software, books, and other intellectual property that is on-topic is fine. We don't want people using these forums to discuss or enable copyright violations or other things that are against the law; whether you agree with the law or not is irrelevant. Do not use our resources for something that is legally or morally questionable.

Our discussions here generally fall under "fair use." Telling people how to pirate a software title is an example of something that is not allowable here.


Reporting problematic posts

If you see spam, a wildly off-topic post, or something abusive or illegal please report the thread by clicking on the "Report Post" icon. (It looks like an exclamation point in a triangle and it is available under every post.) This send a notification to all of the moderators, so somebody will see it and deal with it.

If you are unsure you may consider sending a private message to a moderator instead.


New user moderation

New users are directly moderated so that we can weed spammers out early. This means that for your first 10 posts you will have some delay before they are seen. We understand this can be disruptive to the flow of conversation and we try to keep up with our new user moderation duties to avoid undue inconvenience. Please do not make duplicate posts, extra posts to bump your post count, or ask the moderators to expedite this process; 10 moderated posts will go by quickly.

New users also have a smaller personal message inbox limit and are rate limited when sending PMs to other users.


Other suggestions
  • Use Google, books, or other definitive sources. There is a lot of information out there.
  • Don't make people guess at what you are trying to say; we are not mind readers. Be clear and concise.
  • Spelling and grammar are not rated, but they do make a post easier to read.
See more
See less

Arduino PS2 to XT converter

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Arduino PS2 to XT converter

    Arduino PS2 to XT converter

    First of all I want to point out a couple of things:

    -Sorry for my bad English but my motherlanguage is Italian.

    -I am not the creator of this, all the credit goes to Kestutis Rutkauskas whose blog is: http://kesrut.wordpress.com the reference project can be found here: https://github.com/kesrut/tinyPS2toXTArduino

    -IMPORTANT: No one is responible in case of injuries, damage to your equipment/devices, etc..so go on only at own risk.

    -My advice is to fully read this few lines and evaluate if you can do this by yourself before starting anything.

    So let's begin...

    The purpose of this project is to use an Arduino (http://www.arduino.cc/) as a converter that allows common PS/2 to be used on XT type machines; as we know XT machines do not use the AT keyboard protocol; for this reason a simple port adapter is not sufficient but a chip based converter is required.

    Till now there were two known solutions, get an original XT keyboard (very high quality products but nowdays very pricy, cannot be used with KVM systems) or the AT2XT converter (http://www.vintage-computer.com/vcfo...oard-converter). What we are doing here is a third option faisable with very basic electronics knowledge, cheap components and little time.

    First of all you need to have an arduino board and understand how it works.. If you have never seen anything like that go to: http://arduino.cc/ and in a couple of minutes you can learn the basics of this device-don't be scared it's very very easy and there are millions of tutorials on the internet.

    Then you also need:
    1) some time
    2) 1* CONN DIN 5 PIN FEMALE PCB (CP-2350-ND on Digikey or can be easily desoldered from an old dead mobo like I did)
    3) 1*CONN MINI-DIN 6 PIN FEMALE PCB (CP-2260-ND on Digikey or can be easily desoldered from an old dead mobo like I did)
    4) some small pieces of wire

    As for the board I have used an "Arduino Uno" but other models can be used too (little changes to the code may be required,see NOTE 1 at bottom); this board has a detachable Atmega 328 that can be used standalone with few basic components but without the full arduino board after the chip is programmed.

    All you have to do assemble a small circuit board according to the given schematic that follows (sorry for the bad quality but was done quickly on paint) and program the arduino with the attached code.
    One important advice is to DISCONNECT the USB cable from the arduino before powering the XT, the arduino board will be powered by XT itself BUT without disconnecting USB it won't work! So flash the code and then disconnect the arduino from the USB!

    Before soldering anything, my suggestion is to assemble everything on a bredboard and test if it works for your computer then, you can solder the circuit on a perfboard or make your own PCB.

    Here comes the scheme (this is bottom view, so keep in mind that connectors are seen from bottom!):
    PS2XTarduino.jpg

    Here comes the code (sorry I was not able to compact this):

    #define ps_clk 2 /* must be interrupt pin (0 interrupt) */
    #define ps_data 4
    #define xt_clk 3
    #define xt_data 5

    #define START 1
    #define STOP 3
    #define PARITY 4
    #define INIT 5
    #define GROUP1_CNT 85
    #define BREAK_GRP1 0xF0
    #define MAKE_GRP2 0xE0
    #undef DEBUG

    byte cycles = 0 ;
    unsigned char value = 0 ;
    byte state = INIT ;
    byte got_data = 0 ;

    struct ps2_struct_group
    {
    unsigned char character ;
    unsigned char make ;
    unsigned is_char ;
    unsigned char xt_make ;
    } ;

    typedef struct ps2_struct_group ps2_group1_type ;
    typedef struct ps2_struct_group ps2_group2_type ;

    ps2_group1_type ps2_group1[] =
    {
    {'a', 0x1C, 1, 0x1E},
    {'b', 0x32, 1, 0x30},
    {'c', 0x21, 1, 0x2E},
    {'d', 0x23, 1, 0x20},
    {'e', 0x24, 1, 0x12},
    {'f', 0x2B, 1, 0x21},
    {'g', 0x34, 1, 0x22},
    {'h', 0x33, 1, 0x23},
    {'i', 0x43, 1, 0x17},
    {'j', 0x3B, 1, 0x24},
    {'k', 0x42, 1, 0x25},
    {'l', 0x4B, 1, 0x26},
    {'m', 0x3A, 1, 0x32},
    {'n', 0x31, 1, 0x31},
    {'o', 0x44, 1, 0x18},
    {'p', 0x4D, 1, 0x19},
    {'q', 0x15, 1, 0x10},
    {'r', 0x2D, 1, 0x13},
    {'s', 0x1B, 1, 0x1F},
    {'t', 0x2C, 1, 0x14},
    {'u', 0x3C, 1, 0x16},
    {'v', 0x2A, 1, 0x2F},
    {'w', 0x1D, 1, 0x11},
    {'x', 0x22, 1, 0x2D},
    {'y', 0x35, 1, 0x15},
    {'z', 0x1A, 1, 0x2C},
    {'0', 0x45, 1, 0x0B},
    {'1', 0x16, 1, 0x02},
    {'2', 0x1E, 1, 0x03},
    {'3', 0x26, 1, 0x04},
    {'4', 0x25, 1, 0x05},
    {'5', 0x2E, 1, 0x06},
    {'6', 0x36, 1, 0x07},
    {'7', 0x3D, 1, 0x08},
    {'8', 0x3E, 1, 0x09},
    {'9', 0x46, 1, 0x0A},
    {'`', 0x0E, 1, 0x29},
    {'-', 0x4E, 1, 0x0C},
    {'=', 0x55, 1, 0x0D},
    {'\\', 0x5D, 1, 0x2B},
    {'\b', 0x66, 0, 0x0E}, // backsapce
    {' ', 0x29, 1, 0x39}, // space
    {'\t', 0x0D, 0, 0x0F}, // tab
    {' ', 0x58, 0, 0x3A}, // caps
    {' ', 0x12, 0, 0x2A}, // left shift
    {' ', 0x14, 0, 0x1D}, // left ctrl
    {' ', 0x11, 0, 0x38}, // left alt
    {' ', 0x59, 0, 0x36}, // right shift
    {'\n', 0x5A, 1, 0x1C}, // enter
    {' ', 0x76, 0, 0x01}, // esc
    {' ', 0x05, 0, 0x3B}, // F1
    {' ', 0x06, 0, 0x3C}, // F2
    {' ', 0x04, 0, 0x3D}, // F3
    {' ', 0x0C, 0, 0x3E}, // F4
    {' ', 0x03, 0, 0x3F}, // F5
    {' ', 0x0B, 0, 0x40}, // F6
    {' ', 0x83, 0, 0x41}, // F7
    {' ', 0x0A, 0, 0x42}, // F8
    {' ', 0x01, 0, 0x43}, // f9
    {' ', 0x09, 0, 0x44}, // f10
    {' ', 0x78, 0, 0x57}, // f11
    {' ', 0x07, 0, 0x58}, // f12
    {' ', 0x7E, 0, 0x46}, // SCROLL
    {'[', 0x54, 1, 0x1A},
    {' ', 0x77, 0, 0x45}, // Num Lock
    {'*', 0x7C, 1, 0x37}, // Keypad *
    {'-', 0x7B, 1, 0x4A}, // Keypad -
    {'+', 0x79, 1, 0x4E}, // Keypad +
    {'.', 0x71, 1, 0x53}, // Keypad .
    {'0', 0x70, 1, 0x52}, // Keypad 0
    {'1', 0x69, 1, 0x4F}, // Keypad 1
    {'2', 0x72, 1, 0x50}, // Keypad 2
    {'3', 0x7A, 1, 0x51}, // Keypad 3
    {'4', 0x6B, 1, 0x4B}, // Keypad 4
    {'5', 0x73, 1, 0x4C}, // Keypad 5
    {'6', 0x74, 1, 0x4D}, // Keypad 6
    {'7', 0x6C, 1, 0x47}, // Keypad 7
    {'8', 0x75, 1, 0x48}, // Keypad 8
    {'9', 0x7D, 1, 0x49}, // Keypad 9
    {']', 0x5B, 1, 0x1B},
    {';', 0x4C, 1, 0x27},
    {'\'', 0x52, 1, 0x28},
    {',', 0x41, 1, 0x33},
    {'.', 0x49, 1, 0x34},
    {'/', 0x4A, 1, 0x35},
    } ;

    ps2_group2_type ps2_group2[] =
    {
    {' ', 0x5B, 0, 0x1F}, // left gui
    {' ', 0x1D, 0, 0x14}, // right ctrl
    {' ', 0x5C, 0, 0x27}, // right gui
    {' ', 0x38, 0, 0x11}, // right alt
    {' ', 0x5D, 0, 0x2F}, // apps
    {' ', 0x52, 0, 0x70}, // insert
    {' ', 0x47, 0, 0x6C}, // home
    {' ', 0x49, 0, 0x7D}, // page up
    {' ', 0x53, 0, 0x71}, // delete
    {' ', 0x4F, 0, 0x69}, // end
    {' ', 0x51, 0, 0x7A}, // page down
    {' ', 0x48, 0, 0x75}, // u arrow
    {' ', 0x4B, 0, 0x6B}, // l arrow
    {' ', 0x50, 0, 0x72}, // d arrow
    {' ', 0x4D, 0, 0x74}, // r arrow
    {' ', 0x1C, 0, 0x5A}, // kp en
    } ;

    void setup()
    {
    #ifdef DEBUG
    Serial.begin(9600) ;
    #endif
    pinMode(ps_clk, INPUT) ;
    pinMode(ps_data,INPUT) ;
    pinMode(xt_clk, OUTPUT) ;
    pinMode(xt_data, OUTPUT) ;
    digitalWrite(xt_clk, HIGH) ;
    digitalWrite(xt_data, HIGH) ;
    attachInterrupt(0, clock, FALLING);
    }

    unsigned char _read()
    {
    if (got_data)
    {
    got_data = 0 ;
    return value ;
    }
    return 0 ;
    }

    void _write(unsigned char value)
    {
    while (digitalRead(xt_clk) != HIGH) ;
    unsigned char bits[8] ;
    byte p = 0 ;
    byte j = 0 ;
    for (j=0 ; j < 8; j++)
    {
    if (value & 1) bits[j] = 1 ;
    else bits[j] = 0 ;
    value = value >> 1 ;
    }
    digitalWrite(xt_clk, LOW) ;
    digitalWrite(xt_data, HIGH) ;
    delayMicroseconds(120) ;
    digitalWrite(xt_clk, HIGH) ;
    delayMicroseconds(66) ;
    digitalWrite(xt_clk, LOW) ;
    delayMicroseconds(30) ;
    digitalWrite(xt_clk, HIGH) ;
    byte i = 0 ;
    for (i=0; i < 8; i++)
    {
    digitalWrite(xt_clk, HIGH) ;
    digitalWrite(xt_data, bits[p]) ;
    delayMicroseconds(95) ;
    digitalWrite(xt_clk, LOW) ;
    digitalWrite(xt_data, LOW) ;
    p++ ;
    }
    digitalWrite(xt_clk, HIGH) ;
    digitalWrite(xt_data, LOW) ;
    delay(1) ;
    }

    byte i = 0 ;
    void loop()
    {
    label_start:
    unsigned char code = _read() ;
    #ifdef DEBUG
    if (code != 0) Serial.println(code, HEX) ;
    #endif
    if (code == BREAK_GRP1)
    {
    delay(10) ;
    unsigned char break_code = _read() ;
    unsigned char i = 0 ;
    while (i < GROUP1_CNT)
    {
    if (ps2_group1[i].make == break_code)
    {
    pinMode(xt_clk, OUTPUT) ;
    pinMode(xt_data, OUTPUT) ;
    _write(ps2_group1[i].xt_make | 0x80) ;
    break ;
    }
    i++ ;
    }
    goto label_start;
    }
    if (code != 0)
    {
    unsigned char i = 0 ;
    while (i < GROUP1_CNT)
    {
    if (ps2_group1[i].make == code)
    {
    #ifdef DEBUG
    Serial.write(ps2_group1[i].character) ;
    #endif
    _write(ps2_group1[i].xt_make) ;
    break ;
    }
    i++ ;
    }
    }
    if (digitalRead(xt_clk) == LOW) // power-on self test
    {
    delay(10) ;
    _write(0xAA) ;
    }
    }

    void clock()
    {
    if (state == INIT)
    {
    if (digitalRead(ps_data) == LOW)
    {
    state = START ;
    cycles = 0 ;
    got_data = 0 ;
    value = 0 ;
    return ;
    }
    }
    if (state == START)
    {
    value |= (digitalRead(ps_data) << cycles) ;
    cycles++ ;
    if (cycles == state = PARITY ;
    return ;
    }
    if (state == PARITY)
    {
    state = STOP ;
    return ;
    }
    if (state == STOP)
    {
    if (digitalRead(ps_data) == HIGH)
    {
    state = INIT ;
    got_data = 1 ;
    return ;
    }
    }
    }

    Here comes a link with an archive with the code and an higher quality pic of the schematic:

    http://www.adrive.com/public/DFY4fm/...ino-master.zip


    As the creator of this project specifies on the github page, this project is under development so there may be something that does not work flawlessly (some keyboard keys can be misplaced depending on your keyboard layout) but you can easily edit the code to fix those minor issues. Feel free to contribute on this thread..

    Personally I have built the adapter and it works in a very satisfying way.. it only took a while for me to figure out the cabling but with the schematics should be clear enought..


    NOTE 1: at the beginning of the code the digital pins used are initialized.. the pins may depend on your arduino board.. Kestutis Rutkauskas the creator of this project used an Arduino Leonardo so it's code began with:

    #define ps_clk 3 /* must be interrupt pin (0 interrupt) */
    #define ps_data 4
    #define xt_clk 2
    #define xt_data 5

    Here are some pics of my adapter at early stage (sorry for bad quality pics but at that time I was on hurry)

    2014-09-16 11.07.29.jpg 2014-09-16 11.07.39.jpg

    Here is my final solution (it is a board that looks like a module for the arduino, this was done for easy installation.. not a very clean board but does it's job)

    2014-09-25 16.34.20.jpg
    Last edited by zinamo; September 27, 2014, 09:17 AM.

    #2
    Great find, zinamo! I'd be interested in seeing pics of your project.

    Comment


      #3
      I added some pics, they are not very good but I hope still usefull

      Comment


        #4
        I might take a stab at rewriting that code and trying it out with a teensy. (since I have several spares, 2.0 and 3.0 -- though teensy 3 would be overkill).

        There's a few things I'd clean up.

        1) use SWITCH/CASE instead of the IF/RETURN on the clock ISR.

        2) use a flat array of XT keycodes indexed by AT value -- even though you would have blanks in the array, the loss of an entire column of that data would more than make up for it in terms of memory footprint, and it would be WAY faster than that 'loop searching for it'.

        3) trap the multi-byte codes by checking bit 7 and using the proper "way it works" of 0xEv or 0xFv where v is the number of bytes that follows. Dunno if you noticed but:

        Keypad Enter:
        E0 5A

        Pause/Break:
        E1 14 77
        E1 F0 14
        F0 77

        low nybble + 1 == number of bytes that follows when bit 7 is set.

        4) Get parity checking in there.

        5) Not really seeing a reason to waste memory and overhead on storing the bits in an array and looping twice on the WRITE command... just & 1 inside the output loop and do a shr where timing isn't as critical.

        Code:
        void _write(unsigned char value) {
        	while (digitalRead(xt_clk) != HIGH);
        	digitalWrite(xt_clk, LOW);
        	digitalWrite(xt_data, HIGH);
        	delayMicroseconds(120);
        	digitalWrite(xt_clk, HIGH);
        	delayMicroseconds(66);
        	digitalWrite(xt_clk, LOW);
        	delayMicroseconds(30);
        	digitalWrite(xt_clk, HIGH);
        	for (byte i = 0; i < 8; i++) {
        		digitalWrite(xt_clk, HIGH);
        		digitalWrite(xt_data, value & 1);
        		delayMicroseconds(95);
        		digitalWrite(xt_clk, LOW);
        		digitalWrite(xt_data, LOW);
        		value >>= 1;
        	}
        	digitalWrite(xt_clk, HIGH);
        	digitalWrite(xt_data, LOW);
        	delay(1);
        }
        Though isn't the clock high before the loop redundant to the one inside it? Or is it immediately pulled down by the hardware for some reason I'm unfamiliar with? (Not really up on how the XT keyboard handles things).

        Might be fun to see if it could be dumbed down to run on something like a ATtiny20.
        From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
        CUTCODEDOWN.COM

        Comment


          #5
          Ok, this is good for a laugh. I started playing with building one of these on a breadboard with a teensy, when suddenly it hit me...

          Not a single one of my 8088 class machines takes a PC/XT keyboard. PCjr, Sharp PC-7000... assortment of Tandy 1000's... I've got nothing to test it on!
          From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
          CUTCODEDOWN.COM

          Comment


            #6
            Originally posted by deathshadow View Post
            Not a single one of my 8088 class machines takes a PC/XT keyboard.
            Well, you could always build a second one to translate XT to PS/2 and use them back-to-back!

            Zinamo, I tried your code and it worked on an XT, but it looked like it had keybounce. Every character showed up doubled. When I typed 'dir', I got 'ddiirr'. Found that with some judicious stabbing at the keys, it was possible to get it right - but it was tough. Perhaps tomorrow I can spend some time with your code and figure out what is going on. I tried a couple IBM keyboards and an HP. All acted the same.

            Ultimately, I'd like to use something like this to be able to use a PS/2 keyboard on an IBM PCjr. That's going to be a little crazy because of some of the oddball scan code combinations.

            Comment


              #7
              Hello jharre,
              well first of all I don't know where this issue comes from but initially I had the same exact problem, under kesrut (the creator of this project) suggestion, I solved it by altering the delay value in this portion of the code:

              if (code == BREAK_GRP1)
              {
              delay(10) ;

              the default value set by kesrut was 4, I replaced it with 10 and it worked, you can try using 1, 2, 20, 50, 100 to see if it is working better.. if no, you can also try deleting the delay command.. just remember to disconnect USB after each update before starting the XT let me know if it is working...

              Comment


                #8
                Here is one more pic of the adapter mounted over the arduino:
                2014-10-03 20.58.30.jpg
                the two wires you see on top are used because my board was less wide that the arduino itself so I had to find a solution

                Comment


                  #9
                  This is an interesting concept...I may have to give this a go myself...an excuse to buy a new electronic toy. Leaves me also wondering what else is possible...such as will it work in reverse to use an XT keyboard to drive an AT machine? Or how about for slightly oddball machines like the early Tandy 1000's and 2000...and I'm sure there are others.

                  Wesley

                  Comment


                    #10
                    @ jharre: was the issue you had solved?

                    @ wesleyfurr: what you say is very interesting mostly because as far as I know older XT keyboards where built in very high quality.. and also the use on other machine would be good I have wondered if it is possible to build such an adapter for using an AT keyboard with an Olivetti M24/AT&T 6300.. that would be awesome.. but I think I am not able to do that.. but if someone is up to the challenge

                    Comment


                      #11
                      I found this link after looking at the original github project. I needed this for an old Z80 computer that uses an IBM PC keyboard which I don't have on hand. I programmed my Arduino UNO (copy) but all I saw were CRs when pressing any keys.

                      I then had a search for the clocking/data protocol used by the XT and found the following which I used as my reference:

                      http://www.avrfreaks.net/comment/825221#comment-825221

                      I see others here have had various timing related issues so maybe what I present here might be of some help. From what I could work out the _write() function has issues with timing. In the replacement _write() function below I enabled the value=0xaa line then fed the XT clock and data to an analogue oscilliscope so that I could see what was really happening. Sending out the same value over and over is needed on a scope that does not have data storage.

                      Part of the problem in the original code is the lack of any delay in the data loop between digitalWrite(xt_clk, LOW) and digitalWrite(xt_clk, HIGH). The only delay produced would come from the inline code loop itself.

                      I've not played around with other delays outside this function or tried to improve the code generally. My aim was to get it working for my use. It may not work for others but it now looks correct on my scope.

                      Code:
                      void _write(unsigned char value)
                      {
                        //value=0xaa;  // <---------------------- force this value for testing
                       
                         while (digitalRead(xt_clk) != HIGH) ;
                         unsigned char bits[8] ;
                         byte p = 0 ;
                         byte j = 0 ;
                         for (j=0 ; j < 8; j++)
                         {
                           if (value & 1) bits[j] = 1 ;
                           else bits[j] = 0 ;
                           value = value >> 1 ;
                         }
                         digitalWrite(xt_clk, LOW);
                         digitalWrite(xt_data, HIGH); // start bit (2 data bit time)
                         delayMicroseconds(120) ;
                         digitalWrite(xt_clk, HIGH) ;
                         delayMicroseconds(66) ;
                         digitalWrite(xt_clk, LOW) ;
                         delayMicroseconds(30) ;
                      //don't need this here as happens in loop:   digitalWrite(xt_clk, HIGH) ;
                         byte i = 0 ;
                         for (i=0; i < 8; i++)
                         {
                            digitalWrite(xt_data, bits[p]);
                            delayMicroseconds(30);
                            digitalWrite(xt_clk, HIGH);
                            delayMicroseconds(66);
                            digitalWrite(xt_clk, LOW) ;
                            delayMicroseconds(30);
                            p++ ;
                         }
                         digitalWrite(xt_data, LOW);
                         delayMicroseconds(30);
                         digitalWrite(xt_clk, HIGH);
                         delayMicroseconds(66);
                         delay(1);
                      }
                      For testing purposes only I used this loop() function:

                      Code:
                      static unsigned char code;
                      
                      void loop()
                      {
                       unsigned char x;
                      
                       // gets a key code and sends it over and over until new key pressed
                       if ((x = _read()) != 0)
                          {
                           code = x;
                      #ifdef DEBUG
                           Serial.println(code, HEX);
                      #endif
                          }
                       else
                          _write(code);
                      }

                      Comment


                        #12
                        I've built this Arduino-based solution too (with the help of this topic), but I'm having the double key problem as well.
                        Upping the delay time doesn't work for me either, what else can I try? I have no experience in programming the Arduino at all.
                        Last edited by irix; August 24, 2016, 01:41 AM.

                        Comment


                          #13
                          I believe the double key is because the ps2 keyboard sends the key twice.
                          Once to for key down and once for key up.
                          I don't recall how the XT/AT deals with that.
                          I don't like the way they are hard pulling the lines to high for the ps2 side.
                          On code I wrote for ps2, I did the following:

                          pinMode(pin, INPUT_PULLUP ); // is an output high

                          and

                          digitalWrite(pin, LOW );
                          pinMode(pin, OUTPUT ): // for an output 0

                          The buss is suppose to be bidirectional. This code
                          works with the Arduino as bidirectional using the soft
                          pullups in the chip.

                          Dwight
                          Last edited by Dwight Elvey; August 24, 2016, 01:40 PM.

                          Comment


                            #14
                            Yup scancode for key down then 0xf0, scancode for key up.
                            Reach me: vcfblackhole _at_ protonmail dot com.

                            Comment


                              #15
                              Yes, I've noticed that 'key up' sends the key again.
                              I don't quite get how I can fix this.

                              Comment

                              Working...
                              X