- Joined
- May 23, 2002
Well I'm almost complete with my NES HTPC! I'm waiting for the parts to mount the mobo, and lastly completing the code for the controller!
I'm using a teensy 2.0 USB chip, with an accelerometer attached. Right now the code works for the controller portion...anytime a button is pressed it send the corresponding letter.
The mouse portion kind of works and that's where I'm getting into issues. I have it setup so when I press both the start and select buttons on the NES controller it will activate the accelerometer and send the mouse commands. It works, but the problem is it still outputs the keyboard letters which I'm not sure why. I've attached the full code below, the code is broken into sections with full code last. I have the if statement setup to run the fcnmouse if the 2 buttons are pressed, and that works, however, the else statement is still run or something because the letters are sent.
Lastly, the mouse click isn't working...I think this is propietary code unique to arduino but i've commented the code out and it's at the bottom of the fcn mouse because it won't compile.
*edit* after gaming, I can't send 2 key inputs at once...it always sends each key one at a time? Help would be greatly appreciate!
*LASTLY* please note the vast majority for the code below was completed by Ladyada! I take no credit for the abortion I did to her code!
http://www.ladyada.net/make/usbgamepad/index.html
decalring values and constants:
void setup:
void loop:
fcnmouse:
fcnController:
Full code alltogether for copy/paste:
I'm using a teensy 2.0 USB chip, with an accelerometer attached. Right now the code works for the controller portion...anytime a button is pressed it send the corresponding letter.
The mouse portion kind of works and that's where I'm getting into issues. I have it setup so when I press both the start and select buttons on the NES controller it will activate the accelerometer and send the mouse commands. It works, but the problem is it still outputs the keyboard letters which I'm not sure why. I've attached the full code below, the code is broken into sections with full code last. I have the if statement setup to run the fcnmouse if the 2 buttons are pressed, and that works, however, the else statement is still run or something because the letters are sent.
Lastly, the mouse click isn't working...I think this is propietary code unique to arduino but i've commented the code out and it's at the bottom of the fcn mouse because it won't compile.
*edit* after gaming, I can't send 2 key inputs at once...it always sends each key one at a time? Help would be greatly appreciate!
*LASTLY* please note the vast majority for the code below was completed by Ladyada! I take no credit for the abortion I did to her code!
http://www.ladyada.net/make/usbgamepad/index.html
decalring values and constants:
Code:
const int pAnXin = 3;
const int pAnYin = 2;
const int pAnZin = 1;
const int pAnDumb = 0;
#define KEYREPEAT 100 // milliseconds
#define KEYDELAY 200 // delay from first to second character
const int pUp = 0;
const int pRight = 1;
const int pDown = 2;
const int pLeft = 3;
const int pB = 4;
const int pA = 5;
const int pSelect = 6;
const int pStart = 7;
const int pinLED = 11;
//Variables for the states of the NES buttons
byte buttons[] = {pUp, pRight, pDown, pLeft, pB, pA, pSelect, pStart};
byte keys[] = {KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H};
#define NUMBUTTONS sizeof(buttons)
//How far the accelerometer is tilted before the controller starts moving the mouse:
const int cintMovementThreshold = 18;
//The average zero acceleration values read from the accelerometer for each axis:
const int cintZeroXValue = 328;
const int cintZeroYValue = 328;
const int cintZeroZValue = 328;
//The maximum (positive) acceleration values read from the accelerometer for each axis:
const int cintMaxXValue = 396;
const int cintMaxYValue = 396;
const int cintMaxZValue = 396;
//The minimum (negative) acceleration values read from the accelerometer for each axis:
const int cintMinXValue = 256;
const int cintMinYValue = 256;
const int cintMinZValue = 256;
//The sign of the mouse movement relative to the acceleration:
const int cintXSign = -1;
const int cintYSign = -1;
const int cintZSign = 1;
//const float cfloatMovementMultiplier = 1;
//The maximum speed in each axis (x and y) that the cursor should move:
const int cintMaxMouseMovement = 15;
//This reduces the 'twitchiness' of the cursor by calling a delay function at the end of the main loop.
const int cintMouseDelay = 6;
Code:
void setup() {
//Analog Reference, use default
analogReference( DEFAULT );
//Setup the pin modes.
pinMode( pinLED, OUTPUT );
//Enable pullup resitor on the pins.
for (byte i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT_PULLUP);
}
}
Code:
void loop() {
//Determine if chip will be used as a mouse or controller
if (digitalRead(buttons[pStart]) == 0 && digitalRead(buttons[pSelect]) ==0) {
//Process the accelerometer to make the cursor move.
fcnMouse();
}
else {
//Progess the NES controller buttons to send keystrokes.
fcnController();
}
//Delay to avoid 'twitchiness' and bouncing inputs due to too fast of sampling.
delay(cintMouseDelay);
}
Code:
//Function to process the acclerometer as a mouse and send clicks
void fcnMouse()
{
//Initialize values for the mouse cursor movement.
int intMouseXMovement = 0;
int intMouseYMovement = 0;
//Read the dummy analog channel this must be done first because the X analog channel was first and was unstable, it dropped or pegged periodically regardless of pin or source.
analogRead( pAnDumb );
//Read accelerometer readings
int intAnalogXReading = analogRead(pAnXin);
int intAnalogYReading = analogRead(pAnYin);
int intAnalogZReading = analogRead(pAnZin);
//Calculate mouse movement if the analog X reading is ouside of the zero threshold...
if( cintMovementThreshold < abs( intAnalogXReading - cintZeroXValue ) ) {
//...calculate X mouse movement based on how far the X acceleration is from its zero value.
intMouseXMovement = cintXSign * ( ( ( (float)( 2 * cintMaxMouseMovement ) / ( cintMaxXValue - cintMinXValue ) ) * ( intAnalogXReading - cintMinXValue ) ) - cintMaxMouseMovement );
}
else {
//Within the zero threshold, the cursor does not move in the X.
intMouseXMovement = 0;
}
//If the analog Y reading is outside of the zero threshold...
if( cintMovementThreshold < abs( intAnalogYReading - cintZeroYValue ) ) {
//...calculate Y mouse movement based on how far the Y acceleration is from its zero value.
intMouseYMovement = cintYSign * ( ( ( (float)( 2 * cintMaxMouseMovement ) / ( cintMaxYValue - cintMinYValue ) ) * ( intAnalogYReading - cintMinYValue ) ) - cintMaxMouseMovement );
//it could use some improvement, like making it trigonometric.
}
else {
//Within the zero threshold, the cursor does not move in the Y.
intMouseYMovement = 0;
}
Mouse.move(intMouseXMovement, intMouseYMovement);
// //Left and right click for buttons
//
// if (digitalRead(buttons[pB])==0) {
//
// Mouse.click(1,0,0);
//
// }
//
// else if (digitalRead(buttons[pA])==0) {
//
// Mouse.click(0,0,1);
//
// }
//
// else {Mouse.click(0,0,0);
//
// }
}
Code:
//Function to process the buttons from the NES controller
void fcnController() {
static long currentkey = 0;
byte nothingpressed = 1;
// run through all the buttons
for (byte i = 0; i < NUMBUTTONS; i++) {
// are any of them pressed?
if (! digitalRead(buttons[i])) {
nothingpressed = 0; // at least one button is pressed!
// if its a new button, release the old one, and press the new one
if (currentkey != keys[i]) {
Keyboard.set_key1(0);
Keyboard.send_now();
Keyboard.set_key1(keys[i]);
currentkey = keys[i];
Keyboard.send_now();
delay(KEYDELAY);
} else {
// the same button is pressed, so repeat!
Keyboard.set_key1(keys[i]);
Keyboard.send_now();
delay(KEYREPEAT);
}
}
}
if (nothingpressed) {
// release all keys
Keyboard.set_key1(0);
Keyboard.send_now();
}
}
Full code alltogether for copy/paste:
Code:
const int pAnXin = 3;
const int pAnYin = 2;
const int pAnZin = 1;
const int pAnDumb = 0;
#define KEYREPEAT 100 // milliseconds
#define KEYDELAY 200 // delay from first to second character
const int pUp = 0;
const int pRight = 1;
const int pDown = 2;
const int pLeft = 3;
const int pB = 4;
const int pA = 5;
const int pSelect = 6;
const int pStart = 7;
const int pinLED = 11;
//Variables for the states of the NES buttons
byte buttons[] = {pUp, pRight, pDown, pLeft, pB, pA, pSelect, pStart};
byte keys[] = {KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H};
#define NUMBUTTONS sizeof(buttons)
//How far the accelerometer is tilted before the controller starts moving the mouse:
const int cintMovementThreshold = 18;
//The average zero acceleration values read from the accelerometer for each axis:
const int cintZeroXValue = 328;
const int cintZeroYValue = 328;
const int cintZeroZValue = 328;
//The maximum (positive) acceleration values read from the accelerometer for each axis:
const int cintMaxXValue = 396;
const int cintMaxYValue = 396;
const int cintMaxZValue = 396;
//The minimum (negative) acceleration values read from the accelerometer for each axis:
const int cintMinXValue = 256;
const int cintMinYValue = 256;
const int cintMinZValue = 256;
//The sign of the mouse movement relative to the acceleration:
const int cintXSign = -1;
const int cintYSign = -1;
const int cintZSign = 1;
//const float cfloatMovementMultiplier = 1;
//The maximum speed in each axis (x and y) that the cursor should move:
const int cintMaxMouseMovement = 15;
//This reduces the 'twitchiness' of the cursor by calling a delay function at the end of the main loop.
const int cintMouseDelay = 6;
void setup() {
//Analog Reference, use default
analogReference( DEFAULT );
//Setup the pin modes.
pinMode( pinLED, OUTPUT );
//Enable pullup resitor on the pins.
for (byte i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT_PULLUP);
}
}
void loop() {
//Determine if chip will be used as a mouse or controller
if (digitalRead(buttons[pStart]) == 0 && digitalRead(buttons[pSelect]) ==0) {
//Process the accelerometer to make the cursor move.
fcnMouse();
}
else {
//Progess the NES controller buttons to send keystrokes.
fcnController();
}
//Delay to avoid 'twitchiness' and bouncing inputs due to too fast of sampling.
delay(cintMouseDelay);
}
//Function to process the acclerometer as a mouse and send clicks
void fcnMouse()
{
//Initialize values for the mouse cursor movement.
int intMouseXMovement = 0;
int intMouseYMovement = 0;
//Read the dummy analog channel this must be done first because the X analog channel was first and was unstable, it dropped or pegged periodically regardless of pin or source.
analogRead( pAnDumb );
//Read accelerometer readings
int intAnalogXReading = analogRead(pAnXin);
int intAnalogYReading = analogRead(pAnYin);
int intAnalogZReading = analogRead(pAnZin);
//Calculate mouse movement if the analog X reading is ouside of the zero threshold...
if( cintMovementThreshold < abs( intAnalogXReading - cintZeroXValue ) ) {
//...calculate X mouse movement based on how far the X acceleration is from its zero value.
intMouseXMovement = cintXSign * ( ( ( (float)( 2 * cintMaxMouseMovement ) / ( cintMaxXValue - cintMinXValue ) ) * ( intAnalogXReading - cintMinXValue ) ) - cintMaxMouseMovement );
}
else {
//Within the zero threshold, the cursor does not move in the X.
intMouseXMovement = 0;
}
//If the analog Y reading is outside of the zero threshold...
if( cintMovementThreshold < abs( intAnalogYReading - cintZeroYValue ) ) {
//...calculate Y mouse movement based on how far the Y acceleration is from its zero value.
intMouseYMovement = cintYSign * ( ( ( (float)( 2 * cintMaxMouseMovement ) / ( cintMaxYValue - cintMinYValue ) ) * ( intAnalogYReading - cintMinYValue ) ) - cintMaxMouseMovement );
//it could use some improvement, like making it trigonometric.
}
else {
//Within the zero threshold, the cursor does not move in the Y.
intMouseYMovement = 0;
}
Mouse.move(intMouseXMovement, intMouseYMovement);
// //Left and right click for buttons
//
// if (digitalRead(buttons[pB])==0) {
//
// Mouse.click(1,0,0);
//
// }
//
// else if (digitalRead(buttons[pA])==0) {
//
// Mouse.click(0,0,1);
//
// }
//
// else {Mouse.click(0,0,0);
//
// }
}
//Function to process the buttons from the NES controller
void fcnController() {
static long currentkey = 0;
byte nothingpressed = 1;
// run through all the buttons
for (byte i = 0; i < NUMBUTTONS; i++) {
// are any of them pressed?
if (! digitalRead(buttons[i])) {
nothingpressed = 0; // at least one button is pressed!
// if its a new button, release the old one, and press the new one
if (currentkey != keys[i]) {
Keyboard.set_key1(0);
Keyboard.send_now();
Keyboard.set_key1(keys[i]);
currentkey = keys[i];
Keyboard.send_now();
delay(KEYDELAY);
} else {
// the same button is pressed, so repeat!
Keyboard.set_key1(keys[i]);
Keyboard.send_now();
delay(KEYREPEAT);
}
}
}
if (nothingpressed) {
// release all keys
Keyboard.set_key1(0);
Keyboard.send_now();
}
}
Last edited: