Paso 3: Software
El siguiente Arduino Sketch archivo debe ser compilado y cargado en el Arduino Leonardo o el Arduino Micro: JoystickToKeyboard.ino
// ColecoVision / ADAM Joystick to PC Keyboard Converter// for the Arduino Leonardo // 2014-08-24 //-----------------------------------------------------------------------------// Joystick Pins const byte gcFirePin = 2; const byte gcUpPin = 3; const byte gcDownPin = 4; const byte gcLeftPin = 5; const byte gcRightPin = 6; const byte gcModeAPin = 7; const byte gcModeBPin = 8; const byte gcFireMonitorPin = 13; const byte gcBit0Pin = 3; const byte gcBit2Pin = 4; const byte gcBit3Pin = 5; const byte gcBit1Pin = 6;// Keyboard Keys const char gcUpKey = KEY_UP_ARROW; const char gcDownKey = KEY_DOWN_ARROW; const char gcLeftKey = KEY_LEFT_ARROW; const char gcRightKey = KEY_RIGHT_ARROW; const char gcLeftFireKey = KEY_LEFT_ALT; const char gcRightFireKey = KEY_LEFT_CTRL; const char gcPurpleButtonKey = KEY_LEFT_SHIFT; const char gcBlueButtonKey = 'z'; const char gcAsteriskKey = '-'; const char gcPoundKey = '=';// Current Frame Joystick Status byte gLeftFireButton = 0; byte gRightFireButton = 0; byte gUp = 0; byte gDown = 0; byte gLeft = 0; byte gRight = 0; char gNumPadValue = ' '; byte gPurpleButton = 0; byte gBlueButton = 0; byte gBit0 = 0; byte gBit1 = 0; byte gBit2 = 0; byte gBit3 = 0;// Last Frame Joystick Status byte gLastLeftFireButton = 0; byte gLastRightFireButton = 0; byte gLastUp = 0; byte gLastDown = 0; byte gLastLeft = 0; byte gLastRight = 0; char gLastNumPadValue = ' '; byte gLastPurpleButton = 0; byte gLastBlueButton = 0;// Line Read Variables const unsigned int gcThreashold = 4; unsigned int gLeftFireCount = 0; unsigned int gRightFireCount = 0; unsigned int gUpCount = 0; unsigned int gDownCount = 0; unsigned int gLeftCount = 0; unsigned int gRightCount = 0; unsigned int gBit0Count = 0; unsigned int gBit1Count = 0; unsigned int gBit2Count = 0; unsigned int gBit3Count = 0;// Frame Variables const int gcFrameLength = 10; unsigned int gLoopsPerFrame = 0; unsigned long gLastFrameStart = 0;// Shows the status of the joystick. void ShowJoystickStatus() { // Debug Information // Serial.println(gLoopsPerFrame); digitalWrite(gcFireMonitorPin, gLeftFireButton | gRightFireButton); }void SendKeyboardStateToPc() { if ((gLastNumPadValue != ' ') && (gLastNumPadValue != gNumPadValue)) { Keyboard.release(gLastNumPadValue); } if ((gNumPadValue != ' ') && (gLastNumPadValue != gNumPadValue)) { Keyboard.press(gNumPadValue); } SendLineStateToPc(gLastLeftFireButton, gLeftFireButton, gcLeftFireKey); SendLineStateToPc(gLastRightFireButton, gRightFireButton, gcRightFireKey); SendLineStateToPc(gLastUp, gUp, gcUpKey); SendLineStateToPc(gLastDown, gDown, gcDownKey); SendLineStateToPc(gLastLeft, gLeft, gcLeftKey); SendLineStateToPc(gLastRight, gRight, gcRightKey); SendLineStateToPc(gLastPurpleButton, gPurpleButton, gcPurpleButtonKey); SendLineStateToPc(gLastBlueButton, gBlueButton, gcBlueButtonKey); }void SendLineStateToPc(byte lastState, byte currentState, char keyUsedForLine) { if ((lastState == 1) && (currentState == 0)) { Keyboard.release(keyUsedForLine); } if ((lastState == 0) && (currentState == 1)) { Keyboard.press(keyUsedForLine); } }unsigned int CheckJoystickLine(byte pin) { return (digitalRead(pin) == LOW); }void CheckJoystickLines() { const int cLineDelay = 50; // Put Joystick in Direction Mode digitalWrite(gcModeAPin, HIGH); digitalWrite(gcModeBPin, LOW); delayMicroseconds(cLineDelay); gLeftFireCount += CheckJoystickLine(gcFirePin); gUpCount += CheckJoystickLine(gcUpPin); gDownCount += CheckJoystickLine(gcDownPin); gLeftCount += CheckJoystickLine(gcLeftPin); gRightCount += CheckJoystickLine(gcRightPin); // Put Joystick in Keypad Mode digitalWrite(gcModeAPin, LOW); digitalWrite(gcModeBPin, HIGH); delayMicroseconds(cLineDelay); gRightFireCount += CheckJoystickLine(gcFirePin); gBit0Count += CheckJoystickLine(gcBit0Pin); gBit1Count += CheckJoystickLine(gcBit1Pin); gBit2Count += CheckJoystickLine(gcBit2Pin); gBit3Count += CheckJoystickLine(gcBit3Pin); }void ResetFrameVariables() { // Copy Current Frame to Last Frame gLastNumPadValue = gNumPadValue; gLastLeftFireButton = gLeftFireButton; gLastRightFireButton = gRightFireButton; gLastUp = gUp; gLastDown = gDown; gLastLeft = gLeft; gLastRight = gRight; gLastPurpleButton = gPurpleButton; gLastBlueButton = gBlueButton; // Reset Frame Loop Counter gLoopsPerFrame = 0; // Reset Joysick State gLeftFireCount = 0; gLeftFireButton = 0; gRightFireCount = 0; gRightFireButton = 0; gUpCount = 0; gUp = 0; gDownCount = 0; gDown = 0; gLeftCount = 0; gLeft = 0; gRightCount = 0; gRight = 0; gBit0Count = 0; gBit0 = 0; gBit1Count = 0; gBit1 = 0; gBit2Count = 0; gBit2 = 0; gBit3Count = 0; gBit3 = 0; gNumPadValue = ' '; gPurpleButton = 0; gBlueButton = 0; }byte DetermineJoystickLineValue(unsigned int pressCount) { return (pressCount >= gcThreashold); }void DetermineJoystickValues() { const char cKeypadValueLookup[16] = { ' ', '6', '1', '3', '9', '0', gcAsteriskKey, ' ', '2', gcPoundKey, '7', ' ', '5', '4', '8', ' '}; gLeftFireButton = DetermineJoystickLineValue(gLeftFireCount); gRightFireButton = DetermineJoystickLineValue(gRightFireCount); gUp = DetermineJoystickLineValue(gUpCount); gDown = DetermineJoystickLineValue(gDownCount); gLeft = DetermineJoystickLineValue(gLeftCount); gRight = DetermineJoystickLineValue(gRightCount); gBit0 = DetermineJoystickLineValue(gBit0Count); gBit1 = DetermineJoystickLineValue(gBit1Count); gBit2 = DetermineJoystickLineValue(gBit2Count); gBit3 = DetermineJoystickLineValue(gBit3Count); int keypadCode = (gBit3 << 3) + (gBit2 << 2) + (gBit1 << 1) + gBit0; gNumPadValue = cKeypadValueLookup[keypadCode]; // Check for SuperAction Controller Buttons. if (keypadCode == 7) { gPurpleButton = 1; } if (keypadCode == 11) { gBlueButton = 1; } }void setup() { // Setup Serial Monitor // Serial.begin(19200); // Setup Joystick Pins pinMode(gcFirePin, INPUT_PULLUP); pinMode(gcUpPin, INPUT_PULLUP); pinMode(gcDownPin, INPUT_PULLUP); pinMode(gcLeftPin, INPUT_PULLUP); pinMode(gcRightPin, INPUT_PULLUP); pinMode(gcModeAPin, OUTPUT); pinMode(gcModeBPin, OUTPUT); pinMode(gcFireMonitorPin, OUTPUT); }void loop() { unsigned long currentTime; currentTime = millis(); if (currentTime >= (gLastFrameStart + gcFrameLength)) { // Do Joystick Value Commit Logic DetermineJoystickValues(); // Send Values to Monitor ShowJoystickStatus(); // Send Keyboad State to the PC SendKeyboardStateToPc(); // Reset Frame Variables ResetFrameVariables(); // Time to start next frame gLastFrameStart = currentTime; } else { // Check the value of the input lines and make note of them. gLoopsPerFrame++; CheckJoystickLines(); } }