I have made a custom USB Device with the Teesy 3.1 and have it working. Teensy Loader no longer loads a new program unless I press the reset button on the Teensy. I would like to know if this is normal or if there is something that I should change in the code to allow Teensy Loader to load programs from the IDE? I also do not see debug messages in the IDE's Serial Monitor. I would like to restore these two things if possible.
Another Question: I included the serial device as I thought it may have been necessary for Teensy Loader and/or serial debuging in the IDE. Is it needed for either function? If not, I can remove it. (Yes, I could give it a try but wanted to ask. I would also like to get the other things working before removing it.)
Project
----------------
Custom Game Pad for Raspberry Pi with
- Joystick
- 10 buttons
- 2 Keyboard buttons to act as hotkeys for OS
- Raw HID device to communicate battery level
Software
----------------
Teensy: Teensy 3.1
Teensy Loader: 1.20
OS: Windows 7 Ultimate SP 1 (64-bit)
IDE: Arduino 1.0.6 w/ Teensyduino 1.20
Hardware Setup
----------------
Teensy 3.1 (1)
Adafruit PSP 2-Axis Analog Thumb Joystick PRODUCT ID: 444 (1) connected to 3.3VDC, GND, and Analog Pins 0 & 1
Adafruit Tactile Switch Buttons (6mm slim) x 20 pack PRODUCT ID: 1489 (12) connected between GND and digital pins 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, & 11
LEDs (6) connected to GND & 150 ohm resistors with the resistors connected to digital pins 18, 19, 20, 21, 22, & 23
Code
----------------
Changes to the default configuration to create Pi Controller USB Device - View attachment Phase_03b-Final.zip
Test Code
Another Question: I included the serial device as I thought it may have been necessary for Teensy Loader and/or serial debuging in the IDE. Is it needed for either function? If not, I can remove it. (Yes, I could give it a try but wanted to ask. I would also like to get the other things working before removing it.)
Project
----------------
Custom Game Pad for Raspberry Pi with
- Joystick
- 10 buttons
- 2 Keyboard buttons to act as hotkeys for OS
- Raw HID device to communicate battery level
Software
----------------
Teensy: Teensy 3.1
Teensy Loader: 1.20
OS: Windows 7 Ultimate SP 1 (64-bit)
IDE: Arduino 1.0.6 w/ Teensyduino 1.20
Hardware Setup
----------------
Teensy 3.1 (1)
Adafruit PSP 2-Axis Analog Thumb Joystick PRODUCT ID: 444 (1) connected to 3.3VDC, GND, and Analog Pins 0 & 1
Adafruit Tactile Switch Buttons (6mm slim) x 20 pack PRODUCT ID: 1489 (12) connected between GND and digital pins 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, & 11
LEDs (6) connected to GND & 150 ohm resistors with the resistors connected to digital pins 18, 19, 20, 21, 22, & 23
Code
----------------
Changes to the default configuration to create Pi Controller USB Device - View attachment Phase_03b-Final.zip
Test Code
Code:
/* Complete USB Joystick Example
Teensy becomes a USB joystick with 16 or 32 buttons and 6 axis input
You must select Joystick from the "Tools > USB Type" menu
Pushbuttons should be connected between the digital pins and ground.
Potentiometers should be connected to analog inputs 0 to 5.
This example code is in the public domain.
*/
// Configure the number of buttons. Be careful not
// to use a pin for both a digital button and analog
// axis. The pullup resistor will interfere with
// the analog voltage.
// Incudes modifications from
// https://github.com/adafruit/USBgamepad/blob/master/teensySNES_test2/teensySNES_test2.ino
/*
This test for the Pi Control is to check the hardware
The USB Type must be set to "Pi Controller"
*/
// Joystick
const int pinAnalogXInput = 0;
const int pinAnalogYInput = 1;
// Buttons
const int pinBtnA = 0;
const int pinBtnB = 1;
const int pinBtnX = 2;
const int pinBtnY = 3;
const int pinBtnTrigLeft = 4;
const int pinBtnTrigRight = 5;
const int pinBtnBack = 6;
const int pinBtnStart = 7;
const int pinBtnMenu = 8;
const int pinBtnCoin = 9;
// Special buttons for scripts
const int pinBtnPwr = 10;
const int pinBtnBatteryLevel = 11;
// LEDs
const int pinLedPower = 23;
const int pinLed0 = 22;
const int pinLed1 = 21;
const int pinLed2 = 20;
const int pinLed3 = 19;
const int pinLed4 = 18;
//Variables for the states of the buttons
byte buttons[] = {
pinBtnA, pinBtnB, pinBtnX, pinBtnY,
pinBtnTrigLeft, pinBtnTrigRight,
pinBtnBack, pinBtnMenu, pinBtnCoin, pinBtnStart};
//Variables for the states of the special buttons
byte specialButtons[] = {
pinBtnPwr, pinBtnBatteryLevel};
//Variables for the LEDs
byte leds[] = {
pinLedPower, pinLed0, pinLed1, pinLed2, pinLed3, pinLed4};
#define NUMBUTTONS sizeof(buttons)
#define NUMSPECIALBUTTONS sizeof(specialButtons)
#define NUMLEDS sizeof(leds)
typedef void KeyFunction_t(uint8_t c);
byte allButtons[NUMBUTTONS];
byte prevButtons[NUMBUTTONS];
byte specialButtonsPressed[NUMSPECIALBUTTONS];
// RawHID packets are always 64 bytes
byte buffer[64];
elapsedMillis msUntilNextSend;
unsigned int packetCount = 0;
void setup() {
// you can print to the serial monitor while the joystick is active!
Serial.begin(9600);
// configure the joystick to manual send mode. This gives precise
// control over when the computer receives updates, but it does
// require you to manually call Joystick.send_now().
Gamepad.useManualSend(true);
for (int i=0; i<NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT_PULLUP);
}
for (int i=0; i<NUMSPECIALBUTTONS; i++) {
pinMode(specialButtons[i], INPUT_PULLUP);
}
for (int i=0; i<NUMLEDS; i++) {
pinMode(leds[i], OUTPUT);
digitalWrite(leds[i], LOW);
}
// initialize control over the keyboard:
Keyboard.begin();
Serial.println("Begin Complete Joystick Test");
}
void loop() {
processGamepad();
processKeyboard();
processHID();
// a brief delay, so this runs "only" 200 times per second
delay(50);
blinkLED();
}
unsigned long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
void blinkLED() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// set the LED with the ledState of the variable:
digitalWrite(pinLed4, !digitalRead(pinLed4));
}
}
void processGamepad() {
// read 2 analog inputs and use them for the joystick axis
Gamepad.X(analogRead(pinAnalogXInput));
Gamepad.Y(analogRead(pinAnalogYInput));
// read digital pins and use them for the buttons
for (int i=0; i<NUMBUTTONS; i++) {
if (digitalRead(buttons[i])) {
// when a pin reads high, the button is not pressed
// the pullup resistor creates the "on" signal
allButtons[i] = 0;
}
else {
// when a pin reads low, the button is connecting to ground.
allButtons[i] = 1;
}
Gamepad.button(i + 1, allButtons[i]);
}
// Because setup configured the Joystick manual send,
// the computer does not see any of the changes yet.
// This send_now() transmits everything all at once.
Gamepad.send_now();
// check to see if any button changed since last time
boolean anyChange = false;
for (int i=0; i<NUMBUTTONS; i++) {
if (allButtons[i] != prevButtons[i]) anyChange = true;
prevButtons[i] = allButtons[i];
}
// if any button changed, print them to the serial monitor
if (anyChange) {
Serial.print("Buttons: ");
for (int i=0; i<NUMBUTTONS; i++) {
Serial.print(allButtons[i], DEC);
}
Serial.println();
}
}
void processHID() {
int n;
n = RawHID.recv(buffer, 0); // 0 timeout = do not wait
if (n > 0) {
// the computer sent a message. Display the bits
// of the first byte on pin 0 to 7. Ignore the
// other 63 bytes!
Serial.print(F("Received packet, first byte: "));
Serial.println((int)buffer[0]);
for (int i=0; i<NUMLEDS; i++) {
int b = buffer[0] & (1 << i);
digitalWrite(leds[i], b);
}
}
// every 2 seconds, send a packet to the computer
if (msUntilNextSend > 2000) {
msUntilNextSend = msUntilNextSend - 2000;
// first 2 bytes are a signature
buffer[0] = 0xAB;
buffer[1] = 0xCD;
// next 24 bytes are analog measurements
for (int i=0; i<12; i++) {
int val = analogRead(i);
buffer[i * 2 + 2] = highByte(val);
buffer[i * 2 + 3] = lowByte(val);
}
// fill the rest with zeros
for (int i=26; i<62; i++) {
buffer[i] = 0;
}
// and put a count of packets sent at the end
buffer[62] = highByte(packetCount);
buffer[63] = lowByte(packetCount);
// actually send the packet
n = RawHID.send(buffer, 100);
if (n > 0) {
Serial.print(F("Transmit packet "));
Serial.println(packetCount);
packetCount = packetCount + 1;
} else {
Serial.println(F("Unable to transmit packet"));
}
}
}
void processKeyboard() {
// run through all the special buttons
for (byte i = 0; i < NUMSPECIALBUTTONS; i++) {
// are any of them pressed?
if (!digitalRead(specialButtons[i]))
{ //this button is pressed
if(specialButtonsPressed[i] != 1)
{
Serial.println(specialButtonsPressed[i], DEC);
switch (specialButtons[i]) {
case pinBtnPwr:
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_DELETE);
delay(500);
Keyboard.releaseAll();
delay(500);
digitalWrite(pinLedPower, HIGH);
break;
case pinBtnBatteryLevel:
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_SCROLL_LOCK);
Keyboard.press(KEY_PRINTSCREEN);
delay(500);
Keyboard.releaseAll();
delay(500);
break;
default:
break;
}
// Don't process the button again until released and pressed
specialButtonsPressed[i]=1;
}
}
else
{
// Button released - process on next press
specialButtonsPressed[i]=0;
}
}
}
Last edited: