Skip to content

Commit 271a58a

Browse files
authored
Merge pull request #659 from adafruit/TheKitty-patch-21
Create teensySNES_test2.ino
2 parents 62f6470 + cfece9a commit 271a58a

1 file changed

Lines changed: 257 additions & 0 deletions

File tree

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
const int pinAnalogXInput = 3;
2+
const int pinAnalogYInput = 1;
3+
const int pinAnalogZInput = 2;
4+
const int pinAnalogDummyInput = 0;
5+
6+
#define KEYREPEAT 100 // milliseconds
7+
#define KEYDELAY 200 // delay from first to second character
8+
9+
const int pinBtnUp = 0;
10+
const int pinBtnRight = 1;
11+
const int pinBtnDown = 2;
12+
const int pinBtnLeft = 3;
13+
14+
const int pinBtnSelect = 4;
15+
const int pinBtnStart = 5;
16+
17+
const int pinBtnB = 7;
18+
const int pinBtnA = 8;
19+
const int pinBtnY = 10;
20+
const int pinBtnX = 9;
21+
22+
const int pinBtnTrigLeft = 6;
23+
const int pinBtnTrigRight = 23;
24+
25+
const int pinLEDOutput = 11;
26+
27+
//Variables for the states of the SNES buttons
28+
byte buttons[] = { pinBtnUp, pinBtnRight, pinBtnDown, pinBtnLeft, pinBtnSelect, pinBtnStart,
29+
pinBtnB, pinBtnA, pinBtnY, pinBtnX, pinBtnTrigLeft, pinBtnTrigRight
30+
};
31+
short keys[] = {KEY_U, KEY_R, KEY_D, KEY_L, KEY_ENTER, KEY_TAB, KEY_B, KEY_A, KEY_Y, KEY_X, KEY_P, KEY_Q};
32+
33+
#define NUMBUTTONS sizeof(buttons)
34+
35+
typedef void KeyFunction_t(uint8_t c);
36+
37+
KeyFunction_t* buttonActive[NUMBUTTONS];
38+
KeyFunction_t* keyList[] = {myset_key6, myset_key5, myset_key4, myset_key3, myset_key2, myset_key1};
39+
int keySlot = sizeof(keyList) / sizeof(KeyFunction_t*);
40+
41+
//Change these values if accelerometer reading are different:
42+
//How far the accerometer is tilted before
43+
//the Teensy starts moving the mouse:
44+
const int cintMovementThreshold = 18;
45+
46+
//The average zero acceleration values read
47+
//from the accelerometer for each axis:
48+
const int cintZeroXValue = 328;
49+
const int cintZeroYValue = 328;
50+
const int cintZeroZValue = 328;
51+
52+
//The maximum (positive) acceleration values read
53+
//from the accelerometer for each axis:
54+
const int cintMaxXValue = 396;
55+
const int cintMaxYValue = 396;
56+
const int cintMaxZValue = 396;
57+
58+
//The minimum (negative) acceleration values read
59+
//from the accelerometer for each axis:
60+
const int cintMinXValue = 256;
61+
const int cintMinYValue = 256;
62+
const int cintMinZValue = 256;
63+
64+
//The sign of the mouse movement relative to the acceleration.
65+
//If your cursor is going in the opposite direction you think it
66+
//should go, change the sign for the appropriate axis.
67+
const int cintXSign = 1;
68+
const int cintYSign = -1;
69+
const int cintZSign = 1;
70+
71+
//const float cfloatMovementMultiplier = 1;
72+
73+
//The maximum speed in each axis (x and y)
74+
//that the cursor should move. Set this to a higher or lower
75+
//number if the cursor does not move fast enough or is too fast.
76+
const int cintMaxMouseMovement = 10;
77+
78+
//This reduces the 'twitchiness' of the cursor by calling
79+
//a delay function at the end of the main loop.
80+
//There is a better way to do this without delaying the whole
81+
//microcontroller, but that is left for another time or person.
82+
const int cintMouseDelay = 8;
83+
84+
85+
void setup()
86+
{
87+
//This is not needed and set to default but can be useful if you
88+
//want to get the full range out of the analog channels when
89+
//reading from the 3.3V ADXL335.
90+
//If the analog reference is used, the thresholds, zeroes,
91+
//maxima and minima will need to be re-evaluated.
92+
analogReference( DEFAULT );
93+
94+
//Setup the pin modes.
95+
pinMode( pinLEDOutput, OUTPUT );
96+
97+
//Special for the Teensy is the INPUT_PULLUP
98+
//It enables a pullup resitor on the pin.
99+
for (byte i=0; i< NUMBUTTONS; i++) {
100+
pinMode(buttons[i], INPUT_PULLUP);
101+
}
102+
103+
//Uncomment this line to debug the acceleromter values:
104+
// Serial.begin();
105+
106+
}
107+
108+
109+
void loop()
110+
{
111+
// //debugging the start button...
112+
digitalWrite ( pinLEDOutput, digitalRead(pinBtnStart));
113+
114+
115+
//Process the accelerometer to make the cursor move.
116+
//Comment this line to debug the accelerometer values:
117+
fcnProcessAccelerometer();
118+
119+
//Progess the SNES controller buttons to send keystrokes.
120+
fcnProcessButtons();
121+
122+
123+
//Delay to avoid 'twitchiness' and bouncing inputs
124+
//due to too fast of sampling.
125+
//As said above, there is a better way to do this
126+
//than delay the whole MCU.
127+
delay(cintMouseDelay);
128+
}
129+
130+
131+
//Function to process the acclerometer data
132+
//and send mouse movement information to the host computer.
133+
void fcnProcessAccelerometer()
134+
{
135+
//Initialize values for the mouse cursor movement.
136+
int intMouseXMovement = 0;
137+
int intMouseYMovement = 0;
138+
139+
//Read the dummy analog channel
140+
//This must be done first because the X analog channel was first
141+
//and was unstable, it dropped or pegged periodically regardless
142+
//of pin or source.
143+
analogRead( pinAnalogDummyInput );
144+
145+
//Read accelerometer readings
146+
int intAnalogXReading = analogRead(pinAnalogXInput);
147+
int intAnalogYReading = analogRead(pinAnalogYInput);
148+
int intAnalogZReading = analogRead(pinAnalogZInput);
149+
150+
//Calculate mouse movement
151+
//If the analog X reading is ouside of the zero threshold...
152+
if( cintMovementThreshold < abs( intAnalogXReading - cintZeroXValue ) )
153+
{
154+
//...calculate X mouse movement based on how far the X acceleration is from its zero value.
155+
intMouseXMovement = cintXSign * ( ( ( (float)( 2 * cintMaxMouseMovement ) / ( cintMaxXValue - cintMinXValue ) ) * ( intAnalogXReading - cintMinXValue ) ) - cintMaxMouseMovement );
156+
//it could use some improvement, like making it trigonometric.
157+
}
158+
else
159+
{
160+
//Within the zero threshold, the cursor does not move in the X.
161+
intMouseXMovement = 0;
162+
}
163+
164+
//If the analog Y reading is ouside of the zero threshold...
165+
if( cintMovementThreshold < abs( intAnalogYReading - cintZeroYValue ) )
166+
{
167+
//...calculate Y mouse movement based on how far the Y acceleration is from its zero value.
168+
intMouseYMovement = cintYSign * ( ( ( (float)( 2 * cintMaxMouseMovement ) / ( cintMaxYValue - cintMinYValue ) ) * ( intAnalogYReading - cintMinYValue ) ) - cintMaxMouseMovement );
169+
//it could use some improvement, like making it trigonometric.
170+
}
171+
else
172+
{
173+
//Within the zero threshold, the cursor does not move in the Y.
174+
intMouseYMovement = 0;
175+
}
176+
177+
Mouse.move(intMouseXMovement, intMouseYMovement);
178+
179+
}
180+
181+
//Function to process the buttons from the SNES controller
182+
void fcnProcessButtons()
183+
{
184+
bool keysPressed = false;
185+
bool keysReleased = false;
186+
187+
// run through all the buttons
188+
for (byte i = 0; i < NUMBUTTONS; i++) {
189+
190+
// are any of them pressed?
191+
if (! digitalRead(buttons[i]))
192+
{ //this button is pressed
193+
keysPressed = true;
194+
if (!buttonActive[i]) //was it pressed before?
195+
activateButton(i); //no - activate the keypress
196+
}
197+
else
198+
{ //this button is not pressed
199+
if (buttonActive[i]) { //was it pressed before?
200+
releaseButton(i); //yes - release the keypress
201+
keysReleased = true;
202+
}
203+
}
204+
}
205+
206+
if (keysPressed || keysReleased)
207+
Keyboard.send_now(); //update all the keypresses
208+
209+
}
210+
211+
void activateButton(byte index)
212+
{
213+
if (keySlot) //any key slots left?
214+
{
215+
keySlot--; //Push the keySlot stack
216+
buttonActive[index] = keyList[keySlot]; //Associate the keySlot function pointer with the button
217+
(*keyList[keySlot])(keys[index]); //Call the key slot function to set the key value
218+
}
219+
}
220+
221+
void releaseButton(byte index)
222+
{
223+
keyList[keySlot] = buttonActive[index]; //retrieve the keySlot function pointer
224+
buttonActive[index] = 0; //mark the button as no longer pressed
225+
(*keyList[keySlot])(0); //release the key slot
226+
keySlot++; //pop the keySlot stack
227+
}
228+
229+
void myset_key1(uint8_t c)
230+
{
231+
Keyboard.set_key1(c);
232+
}
233+
234+
void myset_key2(uint8_t c)
235+
{
236+
Keyboard.set_key2(c);
237+
}
238+
239+
void myset_key3(uint8_t c)
240+
{
241+
Keyboard.set_key3(c);
242+
}
243+
244+
void myset_key4(uint8_t c)
245+
{
246+
Keyboard.set_key4(c);
247+
}
248+
249+
void myset_key5(uint8_t c)
250+
{
251+
Keyboard.set_key5(c);
252+
}
253+
254+
void myset_key6(uint8_t c)
255+
{
256+
Keyboard.set_key6(c);
257+
}

0 commit comments

Comments
 (0)