Issues using gyroscopic sensor as HID over serial with AAC Keys (for gaming)

Before I start describing my problem, you should know I'm a complete noob when it comes to both working with the Arduino and coding in general as this is my first project. I'm stuck and I don't have the knowledge to even know where to start troubleshooting the issue. Any assistance, suggestions, or links to resources anyone could provide would be much appreciated. Also, I'm flat broke so if hardware would make it easier but there is still a software way to fix it I'll have to end up spending the time on the free way. :stuck_out_tongue: The subject gives an idea of what I'm trying to do but to be more specific...

I have:
Arduino Mega2560
Parallax 2x16 Serial LCD (27977)
Datasheet: http://www.parallax.com/Portals/0/Downloads/docs/prod/audiovis/27976-7-9-ParallaxSerialLCD-v3.0.pdf
Parallax Gyroscope Module 3-Axis L3G4200D
Datasheet: http://www.parallax.com/portals/0/downloads/docs/prod/sens/27911-gyroscopel3g4200d-v1.0.pdf

Connections:
Serial LCD -> Arduino Mega2560 via pin 6
Gyroscopic Module -> Arduino Mega2560 via SDA (pin 20) and SCL (pin 21)

Goal:
I am trying to take output values from the gyro module and format them for AAC Keys, then send them via serial (through the arduino usb connection) to my PC running AAC Keys
AAC Keys Site:
http://www.aacinstitute.org/Resources/ProductsandServices/AACKeys/AACKeys.html

Code:
I realize the code is probably super sloppy but I tried to comment it as best I could. It's a combination of two example sketches along with some code of my own. It compiles without errors and runs exactly as expected looking solely at the Serial Monitor.
It is supposed to send " , move , (+/-)x , (+/-)y ." over serial to AAC Keys. (The + or - are required according to the AAC Keys site but the gyro module only sends x or -x, so I used what little I knew how to do to add the + character if it was a positive value.) Also, it prints out the current values to the 2x16 serial lcd.

Issue:
Cursor control works exactly as I would expect within Windows but in every FPS game I've opened it doesn't work at all (I only plan on using it for FPS). Most of the time the games acts like they're not getting input at all. With continuous movement of the module, every 5-10 seconds the screen's view will jump a small amount in game but it goes right back to not moving in the least. There are no other small movements of any kind. Outside games the cursor movement is smooth and easily controlled. It could be a problem with AAC Keys which isn't supported at all or it could be a timing issue. I don't know that I have delays everywhere it's necessary. It could obviously also be an issue that I just don't know to look for.

What I've tried:
I couldn't think of much to try since as far as I can tell the code is working. I adjusted the delay at the end of the loop many times to way past the playable rate, but with no change in the result in game.

Thanks ahead of time for you're help. I couldn't do it without you! :slight_smile:
Diagram and Code below:

const int TxPin = 6; // Set LCD Pin

#include <Wire.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23

int Addr = 105;                 // I2C address of gyro
int x, y, z, xval, yval, zval, xout, yout, zout;

void setup(){
  pinMode(TxPin, OUTPUT);
  digitalWrite(TxPin, HIGH);
  mySerial.begin(9600);
  delay(5);
  mySerial.write(17); // LCD Backlight On
  mySerial.write(12); // LCD Clear Screen
  Wire.begin();
  Serial.begin(9600);
  writeI2C(CTRL_REG1, 0x1F);    // Turn on all axes, disable power down
  writeI2C(CTRL_REG3, 0x08);    // Enable control ready signal
  writeI2C(CTRL_REG4, 0x80);    // Set scale (500 deg/sec)
  delay(100);                   // Wait to synchronize 
}

void loop(){
  getGyroValues();              // Get new values
  xval = x / 114;  // Dividing by 114 reduces noise (comment copied from example I don't really know why this is here)
  yval = y / 114;  // Dividing by 114 reduces noise (comment copied from example I don't really know why this is here)
  zval = z / 114;  // Dividing by 114 reduces noise (comment copied from example I don't really know why this is here)
  xout = xval - (xval + xval);  // Quick way to invert xval for correct game input
  yout = yval - (yval + yval);  // Quick way to invert yval for correct game input
  zout = zval - (zval + zval);  // Quick way to invert zval for correct game input

// Goal here is to print "<esc> , move , (+/-)zout , (+/-)xout ." to serial for AAC Keys. Gyro sensor outputs x and -x, AAC Keys expect +x and -x ("+" required on positive values)
  Serial.print("\x1B"); // Print escape keypress to serial.
  Serial.print( " , move , ");

if (zout > -1) // Add "+" if positive zout value
{
  Serial.print("+"); 
}

  Serial.print(zout);
  Serial.print(" , ");

if (xout > -1) // Add "+" if positive xout value
{
  Serial.print("+");
}

  Serial.print(xout);
  Serial.print(" ."); // "." Ends the command to AAC Keys

  // Print gryo data to 2x16 LCD
  mySerial.write(12); // LCD Clear Screen
  mySerial.print("X:");  mySerial.print(xout);  
  mySerial.write(135); // Move to 9th character on the first line
  mySerial.print(" Y:"); mySerial.print(yout);
  mySerial.write(13); // LCD Line Feed
  mySerial.print("Z:"); mySerial.print(zout);
  
  delay(50);  // Delay before repeating loop            
  
}

void getGyroValues () {
  byte MSB, LSB;

  MSB = readI2C(0x29);
  LSB = readI2C(0x28);
  x = ((MSB << 8) | LSB);

  MSB = readI2C(0x2B);
  LSB = readI2C(0x2A);
  y = ((MSB << 8) | LSB);

  MSB = readI2C(0x2D);
  LSB = readI2C(0x2C);
  z = ((MSB << 8) | LSB);
}

int readI2C (byte regAddr) {
    Wire.beginTransmission(Addr);
    Wire.write(regAddr);                // Register address to read
    Wire.endTransmission();             // Terminate request
    Wire.requestFrom(Addr, 1);          // Read a byte
    while(!Wire.available()) { };       // Wait for receipt
    return(Wire.read());                // Get result
}

void writeI2C (byte regAddr, byte val) {
    Wire.beginTransmission(Addr);
    Wire.write(regAddr);
    Wire.write(val);
    Wire.endTransmission();
}
xout = xval - (xval + xval);  // Quick way to invert xval for correct game input

akaxout = -xval;  // Even quicker way to invert xval for correct game input

Haha, I didn't know I could do that. :stuck_out_tongue: Thanks :slight_smile:

Would the Mouse and Keyboard libraries:
http://arduino.cc/en/Reference/MouseKeyboard
work for this? The page doesn't specify it working on the mega but it seems that if I could I would just rewrite my sketch using it.
"These core libraries allow an Arduino Leonardo, Micro, or Due board to appear as a native Mouse and/or Keyboard to a connected computer. "