Teensy Joystick Stops Responding

kneave

Member
I've created a custom controller for my robotics controller, it's connected to a Raspberry Pi running Raspbian Buster. It'll run for 5-10 minutes and then stop sending data. The USB plugs are inside the enclosure so I have to reflash the Teensy to get it to start sending HID data again. After that the cycle repeats.

It's running in extreme mode as I need extra axes due to having two 3axis joysticks.

Code is at the following address:
https://github.com/kneave/TeensyJoystick/blob/main/src/main.cpp

Has anyone seen this behaviour before please? It's incredibly annoying and makes it essentially unusable for me. I'm not sure if I'm doing something daft in the code or if it's something on the host Pi?

If anyone knows what I can do to troubleshoot this please I'd greatly appreciate it.
 
Not Sure.

If one wanted to reproduce this, might help to know which Teensy you are using, what version of Arduino/Teensyduino... (I am guessing you are using Platform IO).

Which RPI? What version of Raspian? What is the code talking to on the RPI? Again unclear from description if the Teensy stopped sending? Or did the RPI stop receiving? Have you tried connecting to different host, like Windows/Linux and see if same issue?

Sometimes I have seen code hang up when it does checking using millis() or more likely micros() with code not handling wrap around of the clock.
But I believe that would take longer than 5-10 minutes...
But my quick check I only see: if (change && (millis() - lastChange > timeout))
And even if it did not work right, I don't think it will hang... I might be anal and change it like:
if (change && ((uint32_t)(millis() - lastChange) > (uint32_t)timeout))
But again I don't think that is it.


I usually avoid using String()... again doubt that is it. But you only use it once. But on off chance would probably change
Serial.println("Brightness: " + String(brightness));

to maybe: Serial.print("Brightness: "); Serial.print(brightness, DEC);


When it hangs, do you have the Serial Monitor running? Does it make a difference if you have do or don't? Maybe make the Serial.print... code conditional.
for example:
Code:
  if ([COLOR="#FF0000"]Serial [/COLOR]&& anyChange)
  {
    Serial.print("Buttons: ");
    for (int i = 0; i < numSwitches; i++)
    {
      Serial.print(allSwitches[i], DEC);
    }
    Serial.println();
  }

Again still unclear from description if teensy is hung or not sending or the RPI not receiving...

If it were me, and I had some access to Teensy and have unused pins, I would probably instrument the code with things like set a pin high at the start of some critical code and set it low at the end of it, and then monitor it with Logic analyzer. And when it no longer is sending, does the state of the Pins show that it is hanging or not. Like is loop still being called?

Alternative to this is to take over LED or the like, and use different colors for different loops and see if that shows anything. Or if you have Terminal Monitor, you can Print something, like on every N times through loop.... But if USB is being screwed up, and I had available Serial pins not used, I would probably output to different Serial object, but again that implies you have access to the Teensy and you have free pins and at least one of them is a Hardware Serial TX pin.


Sorry throwing darts, as only guessing...
 
All valid points and apologies for not including them!

Teensy 4.0
Raspberry Pi 4
Platform IO, whatever the latest is

I've commented out everything related to printing to serial, I was wondering if the buffer could be getting full or something, and the issue remains.

Good shout on using the LED to show activity though, I'll add that now. USB doesn't seem to disconnect so I suspect it's the Teensy not sending. I'll let you know once the LED bits are changed.
 
Other thoughts include watching what is going on with the RPI.

That is if you can have a terminal window open up on the RPI, and run something like: htop (or is gtop on RPI)...
That shows the different processors and maybe equally interesting is things like memory usage and see if anything pops up...
Like the memory usage keeps going up or one or more of the processor cores are pegged...
 
Sorry, I typed a response over the weekend and seem to have neglected to press send!

I used to be a developer support engineer so high/low cpu hangs and memory leaks are second nature for me to check. Always good advice though!
In my case neither are occurring, it's the Pi4 with 8GB of RAM so a leak should take a while to be an issue too so always good to keep an eye on.

Latest version is in this commit:
https://github.com/kneave/TeensyJoystick/blob/c5424fef7f254f9b4ecece482b6d16df06e240d9/src/main.cpp


I added a check to see if a HID report hadn't been sent for more than a second, this seems a good way to see if that loop is still working, and change the LED to red if so. I have jstest running in a TMUX session and periodically wiggling the joysticks to see if it's still receiving anything.

So far so good, and the only thing I've really changed is removing all the serial.print aspects, if it remains stable I'll add them back in and see if the behaviour returns.
 
It's still happening.

May be a timeout on the linux side, I'm not sure and as long as I can keep it running for five minutes I'll call that good enough for now. Incredibly annoying though for longer term usage.
 
I'm having a similar issue with a Teensy 4.0 ( Serial/Keyboard/Mouse/Joystick) plugged into a RPI 4 (5.15.32-V7l+ ) running Arduino 1.8.19 ( but works nicely in Windows 10)

It hangs even with a simple code like:
i
Code:
nt ct=0;

void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  Serial.begin(115200);
  while(!Serial && millis()<4000); 
}

void loop() {
  if (Serial) Serial.print(".");
  ct++;
  if (ct>20*5) {
    ct=0;
    if (Serial) Serial.println();
  }

  Joystick.button(2, digitalRead(2));
  Joystick.button(3, digitalRead(3));

  // a brief delay, so this runs 20 times per second
  delay(50);
}
evtest shows the devices but reports are not received by RPI ( (or sent by Teensy?) after a few minutes ( but the dots keep printing at the Serial monitor)

pi@raspberrypi:~ $ evtest
No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event0: Dell Dell USB Keyboard
/dev/input/event1: ILITEK ILITEK-TP
/dev/input/event2: ILITEK ILITEK-TP Mouse
/dev/input/event3: Teensyduino Serial/Keyboard/Mouse/Joystick
/dev/input/event4: BT5.0 Mouse
/dev/input/event5: BT5.0 Mouse Consumer Control
/dev/input/event6: Teensyduino Serial/Keyboard/Mouse/Joystick Mouse
/dev/input/event7: vc4
/dev/input/event8: vc4
/dev/input/event9: Teensyduino Serial/Keyboard/Mouse/Joystick
/dev/input/event10: Teensyduino Serial/Keyboard/Mouse/Joystick
Select the device event number [0-10]: 9
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x16c0 product 0x487 version 0x111
Input device name: "Teensyduino Serial/Keyboard/Mouse/Joystick"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 288 (BTN_TRIGGER)
Event code 289 (BTN_THUMB)
Event code 290 (BTN_THUMB2)
Event code 291 (BTN_TOP)
Event code 292 (BTN_TOP2)
Event code 293 (BTN_PINKIE)
Event code 294 (BTN_BASE)
Event code 295 (BTN_BASE2)
Event code 296 (BTN_BASE3)
Event code 297 (BTN_BASE4)
Event code 298 (BTN_BASE5)
Event code 299 (BTN_BASE6)
Event code 300 (?)
\ Event code 301 (?)
Event code 302 (?)
Event code 303 (BTN_DEAD)
Event code 704 (BTN_TRIGGER_HAPPY1)
Event code 705 (BTN_TRIGGER_HAPPY2)
Event code 706 (BTN_TRIGGER_HAPPY3)
Event code 707 (BTN_TRIGGER_HAPPY4)
Event code 708 (BTN_TRIGGER_HAPPY5)
Event code 709 (BTN_TRIGGER_HAPPY6)
Event code 710 (BTN_TRIGGER_HAPPY7)
Event code 711 (BTN_TRIGGER_HAPPY8)
Event code 712 (BTN_TRIGGER_HAPPY9)
Event code 713 (BTN_TRIGGER_HAPPY10)
Event code 714 (BTN_TRIGGER_HAPPY11)
Event code 715 (BTN_TRIGGER_HAPPY12)
Event code 716 (BTN_TRIGGER_HAPPY13)
Event code 717 (BTN_TRIGGER_HAPPY14)
Event code 718 (BTN_TRIGGER_HAPPY15)
Event code 719 (BTN_TRIGGER_HAPPY16)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 0
Min 0
Max 1023
Fuzz 3
Flat 63
Event code 1 (ABS_Y)
Value 0
Min 0
Max 1023
Fuzz 3
Flat 63
Event code 2 (ABS_Z)
Value 0
Min 0
Max 1023
Fuzz 3
Flat 63
Event code 5 (ABS_RZ)
Value 0
Min 0
Max 1023
Fuzz 3
Flat 63
Resolution 186
Event code 6 (ABS_THROTTLE)
Value 0
Min 0
Max 1023
Fuzz 3
Flat 63
Event code 16 (ABS_HAT0X)
Value 0
Min -1
Max 1
Event code 17 (ABS_HAT0Y)
Value -1
Min -1
Max 1
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)
Properties:
Testing ... (interrupt to exit)
Event: time 1656511254.547015, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1656511254.547015, type 1 (EV_KEY), code 289 (BTN_THUMB), value 0
Event: time 1656511254.547015, -------------- SYN_REPORT ------------
Event: time 1656511254.697102, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90002
Event: time 1656511254.697102, type 1 (EV_KEY), code 289 (BTN_THUMB), value 1
Event: time 1656511254.697102, -------------- SYN_REPORT ------------
Event: time 1656511257.998463, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1656511257.998463, type 1 (EV_KEY), code 290 (BTN_THUMB2), value 0
Event: time 1656511257.998463, -------------- SYN_REPORT ------------
Event: time 1656511258.048642, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90003
Event: time 1656511258.048642, type 1 (EV_KEY), code 290 (BTN_THUMB2), value 1
Event: time 1656511258.048642, -------------- SYN_REPORT -----------
 
Last edited by a moderator:
I have an RPI 4 running Ubuntu 2204, I programmed a T4 with the sketch installed evtest...

It has been running maybe 30 minutes and every time I jumper from T2 or T3 to GND
I receive the events for 9002 or 9903 going to 0 or 1...

Not sure what else to test with it...
 
Make sure you have the latest VLI firmware installed (for the VIA USB chipset), by installing rpi-eeprom,
    sudo apt install rpi-eeprom
then rebooting the 'Pi, and finally running rpi-eeprom-update,
    sudo rpi-eeprom-update -a

It looks like others have encountered this issue, too.
 
I have an RPI 4 running Ubuntu 2204, I programmed a T4 with the sketch installed evtest...

It has been running maybe 30 minutes and every time I jumper from T2 or T3 to GND
I receive the events for 9002 or 9903 going to 0 or 1...

Not sure what else to test with it...

Hmm, may be a Raspbian issue then? Will try switching if the eeprom update doesnt work
 
RPI 4 / Teensy 4 - Joystick HID

Hmm, may be a Raspbian issue then? Will try switching if the eeprom update doesnt work

I'm using the last eeprom version and it still hangs:
pi@raspberrypi:~ $ sudo rpi-eeprom-update
BOOTLOADER: up to date
CURRENT: Tue 26 Apr 2022 10:24:28 AM UTC (1650968668)
LATEST: Tue 26 Apr 2022 10:24:28 AM UTC (1650968668)
RELEASE: default (/lib/firmware/raspberrypi/bootloader/default)
Use raspi-config to change the release.

VL805_FW: Dedicated VL805 EEPROM
VL805: up to date
CURRENT: 000138a1
LATEST: 000138a1


To investigate further, I made two small changes - one at usb_joystick.h to include a return code
uint32_t send_now(void) {
return usb_joystick_send();
}


And another at usb_joystick.c to report the return code (from usb_transfer_status(xfer) )
if (transmit_previous_timeout) {return status; }

In my case the status stays forever at 0xC0080 as - so it's never cleared to continue and send the package

Not sure on how to decode the usb_transfer_status - maybe @paul can give a hand on that, but probably it's related to acknowledging the package

It will be great to reset / resume / restart , not sure if it can be done at the Teensy side - probably not

In my case I have a composite device - everything still work (Serial, Midi, Keyboard and Media keys) except the Joystick...
 
on the link that @nominal-animal shared there's some reference to change the interval - I changed mine to 2 : ( usb_desc.h at hardware\teensy\avr\cores\teensy4 )

#define JOYSTICK_INTERVAL 2


And apparently is not hanging ! I'm just running a longer test
 
My eeprom was two years out of date, I've left it running to see how long it lasts but it's promising so far. Any luck with JOYSTICK_INTERVAL?
 
working with change of JOYSTICK_INTERVAL to 2

My eeprom was two years out of date, I've left it running to see how long it lasts but it's promising so far. Any luck with JOYSTICK_INTERVAL?

Yes - it's being working since I made the change

Here's usb_dev.h part:
#elif defined(USB_AMBIENT4)
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x0470
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'}
#define MANUFACTURER_NAME_LEN 11
#define PRODUCT_NAME {'T','e','e','n','s','y','4','A','m','b','i'}
#define PRODUCT_NAME_LEN 11
#define EP0_SIZE 64
#define NUM_ENDPOINTS 7
#define NUM_INTERFACE 6
#define CDC_IAD_DESCRIPTOR 1
#define CDC_STATUS_INTERFACE 0
#define CDC_DATA_INTERFACE 1 // Serial
#define CDC_ACM_ENDPOINT 2
#define CDC_RX_ENDPOINT 3
#define CDC_TX_ENDPOINT 3
#define CDC_ACM_SIZE 16
#define CDC_RX_SIZE_480 512
#define CDC_TX_SIZE_480 512
#define CDC_RX_SIZE_12 64
#define CDC_TX_SIZE_12 64
#define MIDI_INTERFACE 2 // MIDI
#define MIDI_NUM_CABLES 1
#define MIDI_TX_ENDPOINT 4
#define MIDI_TX_SIZE_12 64
#define MIDI_TX_SIZE_480 512
#define MIDI_RX_ENDPOINT 4
#define MIDI_RX_SIZE_12 64
#define MIDI_RX_SIZE_480 512


#define KEYBOARD_INTERFACE 3 // Keyboard
#define KEYBOARD_ENDPOINT 5
#define KEYBOARD_SIZE 8
#define KEYBOARD_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
#define KEYMEDIA_INTERFACE 4 // Keyboard Media Keys
#define KEYMEDIA_ENDPOINT 6
#define KEYMEDIA_SIZE 8
#define KEYMEDIA_INTERVAL 4 // TODO: is this ok for 480 Mbit speed

#define JOYSTICK_INTERFACE 5 // Joystick
#define JOYSTICK_ENDPOINT 7
#define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick
#define JOYSTICK_INTERVAL 2


#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK

#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT7_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT


And here is the boards.txt
teensy40.menu.usb.everything=Ambient4
teensy40.menu.usb.everything.build.usbtype=USB_AMBIENT4

For some reason the status never clear after a bunch of interactions when the INTERVAL is 1 ( uint32_t status = usb_transfer_status(xfer); at usb_joystick.c)
 
Mine was working perfectly all day, I think I noticed one of the other joystick profiles has it set to 2 already too. It's an odd one but seems to work
 
Anyone know what JOYSTICK_INTERVAL actually does by the way? I've been trying to dig through the code to find out and keep hitting dead ends. I assume it's the interval between sending packets to the host machine or similar?
 
Back
Top