I have a Teensy 4.1 with 5 buttons mapped and 6 axes. It also runs a small display which I can change with two buttons so I can have a readout of my controls for various aircraft. They work as intended except two axes seem to do more than I ask for them.
The potentiometers mapped to the X and Y axis correctly move the little cross in the windows usb controllers control panel. All axes and buttons were calibrated. However, if I open up a text editor and spin the X axis dial all the way left I get a '4' in text editor. Spinning right gives a '6'. These numbers only appear at the extreme of excusion. The Y axisa dial gives '8' and '2'. Somehow these axes are being interpreted as the num pad?
Here is the code :
Is this a known windows bug?
The potentiometers mapped to the X and Y axis correctly move the little cross in the windows usb controllers control panel. All axes and buttons were calibrated. However, if I open up a text editor and spin the X axis dial all the way left I get a '4' in text editor. Spinning right gives a '6'. These numbers only appear at the extreme of excusion. The Y axisa dial gives '8' and '2'. Somehow these axes are being interpreted as the num pad?
Here is the code :
Code:
/* button box has 6 potentiometers,5 buttons and one display
* two of the buttons function to page the display forward and back
* TOOLS->USB TYPE-> serial/keyboard/mouse/joystick
*/
#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#include <Bounce.h>
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
//array of potentiometer pins
char potPins[] = {
A0,A1,A2,A3,A4,A10
};
byte potCount = 6;
int inputPot = 0;
int screenNumber = 1;
// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(19, 10);
Bounce button1 = Bounce(20, 10); // 10 = 10 ms debounce time
Bounce button2 = Bounce(21, 10); // which is appropriate for
Bounce button3 = Bounce(22, 10); // most mechanical pushbuttons
Bounce button4 = Bounce(23, 10);
void setup() {
//Serial.begin(9600);
//while (!Serial) { delay(10); }
tft.begin();
Apache();
for (int thisPot = 0; thisPot < potCount; thisPot++)
pinMode(potPins[thisPot], INPUT);
// Configure the pins for input mode with pullup resistors.
// The pushbuttons connect from each pin to ground. When
// the button is pressed, the pin reads LOW because the button
// shorts it to ground. When released, the pin reads HIGH
// because the pullup resistor connects to +5 volts inside
// the chip. LOW for "on", and HIGH for "off" may seem
// backwards, but using the on-chip pullup resistors is very
// convenient. The scheme is called "active low", and it's
// very commonly used in electronics... so much that the chip
// has built-in pullup resistors!
pinMode(19, INPUT_PULLUP);
pinMode(20, INPUT_PULLUP);
pinMode(21, INPUT_PULLUP);
pinMode(22, INPUT_PULLUP);
pinMode(23, INPUT_PULLUP);
// Please be aware the X, Y, Z, Zr and Slider axes will have default
// settings, if you only use the buttons. This can give the appearance
// of the buttons interfering with the axes, if your PC software shows
// different default assumed values before your first button press.
// More details here:
// https://forum.pjrc.com/threads/29320-Teensy-3-1-Button-problems?p=80275#post80275
//these next lines center the axes
// same as Windows default
Joystick.Z(512);
Joystick.X(512);
Joystick.Y(512);
Joystick.Zrotate(512);
Joystick.sliderLeft(512);
Joystick.sliderRight(512);
//Joystick.slider(512);
}
void loop() {
for (int thisPot = 0; thisPot < potCount; thisPot++) {
inputPot = analogRead(potPins[thisPot]);
switch (thisPot) {
case 0:
Joystick.Z(inputPot);
break;
case 1:
Joystick.X(inputPot);
break;
case 2:
Joystick.Y(inputPot);
break;
case 3:
Joystick.Zrotate(inputPot);
break;
case 4:
Joystick.sliderLeft(inputPot);
break;
case 5:
Joystick.sliderRight(inputPot);
break;
default:
break;
}//end switch
}//end for
// Update all the buttons. There should not be any long
// delays in loop(), so this runs repetitively at a rate
// faster than the buttons could be pressed and released.
button0.update();
button1.update();
button2.update();
button3.update();
button4.update();
// Check each button for "falling" edge.
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button0.fallingEdge()) {
Joystick.button(1, 1);
}
if (button1.fallingEdge()) {
Joystick.button(2, 1);
}
if (button2.fallingEdge()) {
Joystick.button(3, 1);
}
if (button3.fallingEdge()) {
changeScreen(-1);
}
if (button4.fallingEdge()) {
changeScreen(1);
}
// Check each button for "rising" edge
// Update the Joystick buttons only upon changes.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
if (button0.risingEdge()) {
Joystick.button(1, 0);
}
if (button1.risingEdge()) {
Joystick.button(2, 0);
}
if (button2.risingEdge()) {
Joystick.button(3, 0);
}
}//end main loop
void changeScreen(int var) {
screenNumber = screenNumber + var;
if (screenNumber < 0) {
screenNumber = 5;
}
if (screenNumber > 5) {
screenNumber = 0;
}
// Serial.println("entering changeScreen function");
// Serial.print("screenNumber is ");
//Serial.print(screenNumber);
switch (screenNumber) {
case 0:
Hog();
break;
case 1:
Apache();
break;
case 2:
CPG();
break;
case 3:
Huey();
break;
case 4:
BlackHawk();
break;
case 5:
F5E();
break;
}//end switch
}//end changeScreen
void Hog() {
//unsigned long testText() {
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(HX8357_RED);
tft.setTextSize(3);
tft.println("A10-C ");
tft.println("");
tft.setTextColor(HX8357_GREEN);
tft.setTextSize(2);
tft.println(" 1 2 3\n");
tft.println("Lights Vols\n");
tft.println("AUX AIM\n");
tft.println("CONSOLE ILS\n");
tft.println("ENGINE TCN\n");
tft.println("FLT FM\n");
tft.println("FLOOD UHF\n");
tft.println("FORM VHF\n");
tft.println("--------------------------\n");
tft.println(" COLL POS SIG \n");
tft.println("ON/OFF FLSH/STDY BRT/DIM\n");
tft.println("");
tft.println(" OFF\n");
}
void Apache() {
//unsigned long testText() {
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(HX8357_RED);
tft.setTextSize(3);
tft.println("AH64\n");
tft.setTextColor(HX8357_GREEN);
tft.setTextSize(2);
tft.println(" 1 2 3\n");
tft.println();
tft.println(" L VID R VID\n");
tft.println(" L BRT R BRT\n");
tft.println(" PRI FLOOD \n");
tft.println(" STBY SIG \n");
tft.println(" FORM ACTION\n");
tft.println(" CMWS LT MSTR VOL\n");
tft.println("--------------------------\n");
tft.println(" COLL EXT FIRE \n");
tft.println(" WHT BRT LT ");
tft.println(" RED DIM RT\n");
tft.println(" OFF OFF TST\n");
tft.println(" FLSHLT ");
}
void CPG() {
//unsigned long testText() {
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(HX8357_RED);
tft.setTextSize(3);
tft.println("CPG\n");
tft.setTextColor(HX8357_GREEN);
tft.setTextSize(2);
tft.println(" AZ ACM FRZ");
tft.println(" \n");
tft.println(" L VID R VID\n");
tft.println(" L BRT R BRT\n");
tft.println(" PRI FLOOD \n");
tft.println(" SIG \n");
tft.println(" LEVEL EUFD\n");
tft.println(" GAIN MSTR VOL\n");
tft.println("--------------------------\n");
tft.println(" TEDAC\n");
tft.println(" RF SYM BRT \n");
tft.println(" ");
tft.println(" EL AZ CON\n");
tft.println();
}
void Huey() {
//unsigned long testText() {
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(HX8357_RED);
tft.setTextSize(3);
tft.println("UH1 ");
tft.println();
tft.setTextColor(HX8357_GREEN);
tft.setTextSize(2);
tft.println(" 1 2 3\n");
tft.println("Lights Vols\n");
tft.println("CONSOLE INT \n");
tft.println("PEDSTL UHF \n");
tft.println("SECNDRY VHF \n");
tft.println("PILOT MRKR BCN \n");
tft.println("COPLT ADF \n");
tft.println("--------------------------\n");
tft.println("COLL NAV ");
tft.println(" ON FLSH ");
tft.println(" ");
tft.println("DOME STDY");
tft.println("OFF \n");
tft.println(" FLSHLT\n");
tft.println("WHT/GRN BRT/DIM WHT/RED \n");
}
void BlackHawk() {
//unsigned long testText() {
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(HX8357_RED);
tft.setTextSize(3);
tft.println("BlackHawk ");
tft.println();
tft.setTextColor(HX8357_GREEN);
tft.setTextSize(2);
tft.println(" 1 2 3\n");
tft.println("PLT INST LTS Eng 1 FUEL\n");
tft.println("CP INST LTS Eng 2 FUEL\n");
tft.println("CONSOLE UP \n");
tft.println("CONSOLE DN \n");
tft.println("GLARE SHLD SWITCH LTS\n");
tft.println("FORM LTS OTHR INST LTS\n6");
tft.println("--------------------------\n");
tft.println("COLL DOME ");
tft.println("DAY BLUE AIR ENG");
tft.println("NIGHT WHITE AIR APU");
tft.println(" ");
tft.println("OFF APU GEN ON");
tft.println(" APU GEN OFF\n");
}
void F5E() {
//unsigned long testText() {
tft.fillScreen(HX8357_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(HX8357_RED);
tft.setTextSize(3);
tft.println("F5E");
tft.println();
tft.setTextColor(HX8357_GREEN);
tft.setTextSize(2);
tft.println(" 1 2 3\n");
tft.println();
tft.println(" LIGHTS\n");
tft.println(" ");
tft.println("RDR BRIGHT NAV \n");
tft.println("RDR CRSR FORM \n");
tft.println("RDR PERSIST FLT INST \n");
tft.println("VIDEO ENG INST \n");
tft.println(" CONSOLE \n");
tft.println(" FLOOD \n");
tft.println("--------------------------");
// tft.println("COLL NAV \n");
//tft.println(" ON FLSH ");
//tft.println(" ");
//tft.println("DOME");
//tft.println("OFF STDY\n");
//tft.println(" FLSHLT\n");
//tft.println("WHT/GRN BRT/DIM WHT/RED \n");
}
Is this a known windows bug?