Teensy 4.0 - PC does not reconnect after Watchdog reset

Status
Not open for further replies.

jimmie

Well-known member
I would appreciate the community's help with this pesky problem.

I have a Teensy 4.0 which is connected to a serial sensor. I am not sure why yet, but the Teensy was crashing after about 30 minutes of communicating with the sensor. Not knowing what was causing this, I added a watchdog which did succeed in restarting the Teensy. (my knowledge of how to debug micro crashes in non-existent).

The problem is that my Teensy needs to communicate with a PC (via USB) and when the watchdog restarts the Teensy, the PC never reconnects. Upon the Teensy restarting, I have to close the com port on the PC and then reopen it to strat communicating.

Is there a way around this?
 
First, in Arduino click Help > About to check which version of Teensyduino you are using. Old versions had a known problem where watchdog and soft reboot didn't work. It's fixed in newer versions.

Your OS matters too. Windows 7, 8, XP & Vista have a serial driver bug where the COM port does not work the next time you connect, if a program has the port open while Teensy was unexpected disconnected. The only solution is to upgrade to Window 10 (or Linux or MacOS). Or use the non-Serial device types in Tools > USB Type, to avoid Microsoft's buggy (on pre-10 Windows) USBSER.SYS driver. The HID driver is very reliable on all versions of Windows.

The software you're using on the PC side matters. The Arduino Serial Monitor should automatically reconnect. But most other software is not savvy to devices disappearing and coming back. You didn't mention which software, or OS, or TD version. Please first test with the Arduino Serial Monitor.

If you're still having a problem, please post a small program which demonstrates the watchdog reboot.
 
Thank you very much Paul. Here are all the answers and also my code.

1) Windows 10
2) Arduino 1.8.9
3) Teensyduino 1.5.3


Is there a way to "set" DTR or RTS lines so PC senses disconnect? I checked with the PC software vendor and he says that their control can detect com port changes only if the DTR or RTS lines are changed ....

-----------------------------------------------

Here is my setup code and loop code. The loop mainly runs the attached code repeatedly but I do not know why it crashes after about 10-30 minutes (hence the use of the watchdog). If I can avoid these crashes, the problem will be solved.

Code:
#include "Watchdog_t4.h"
WDT_T4<WDT1> wdt;

void setup()
{
  Serial.begin(115200);
  delay(100);
  while (!Serial.dtr()) {                                 // wait for terminal to connect
  }
  WDT_timings_t config;
  config.trigger = 5; /* in seconds, 0->128 */
  config.timeout = 10; /* in seconds, 0->128 */
  config.callback = myCallback;
  wdt.begin(config);
  //-----------------------------------------------------------------------------
}

void myCallback()
{
  ////Serial.println("FEED THE DOG SOON, OR RESET!");
}

void loop()
{
//--------------------------------------------------
    readdatmySensor();   
//--------------------------------------------------
   static uint32_t callback_test = millis();
  if ( millis() - callback_test > 5500 ) {
    callback_test = millis();
    wdt.feed();       /* comment to stop feeding the watchdog */
  }
}
 

Attachments

  • DAT.ino
    3.5 KB · Views: 61
Last edited:
Did you test with the Arduino Serial Monitor? Does the Arduino Serial Monitor automatically reconnect when your board reboots? Even if you're using other software, knowing whether it works properly with the Arduino Serial Monitor can establish whether to focus your effort on the Teensy side or on the PC software side.


Is there a way to "set" DTR or RTS lines so PC senses disconnect?

DTR & RTS are virtual signals, communicated from your PC to Teensy using USB control transfers.


I checked with the PC software vendor and he says that their control can detect com port changes only if the DTR or RTS lines are changed ....

That makes absolutely no sense at all. Both DTR and RTS are unidirectional virtual signals which originate on the PC (USB host). They are transmitted to Teensy (USB device). Teensy has no way to change these bits, since they originate on the PC and they are communicated only in the PC-to-Teensy direction!

Even you own code demonstrates this:

Code:
  while (!Serial.dtr()) {                                 // wait for terminal to connect
  }

On Teensy, you can only read the DTR status. You can't change it on the Teensy side, because the CDC ACM protocol used for USB serial doesn't have any way to transmit this bit to the PC.

Likewise for real hardware serial ports, the physical DTR signal (on pin 4 of the DB9 connector) is physically an output which is always transmitting. That pin on a real PC hardware serial port only transmits. PCs never receive a DTR signal.
 
Thank you Paul for your detailed answer. I also learnt about how DTR and RTS work, makes sense.

Yes, the Arduino Serial Monitor does connect.

If at all possible, is there anyway you can take a quick look at the sketch I attached? I do not understand why the Teensy 4.0 is crashing? Sometimes it works for over an hour but then it eventually crashes. If I can prevent the Teensy 4.0 from crashing and executing its watchdog, the problem will be solved ....

I wish I knew how to debug these crashes because they are intermittent and my knowledge of this area is very limited.
 
I had a very quick look at your code. Unfortunately it is not complete or I'm just overlooking the definition of mySensorSerial. I assume this is a reference to one of the hardware serials (Serial1...Serial6) where your sensor is connected to?

The only thing I stumbled over is your waitBuff() function

Code:
void waitBuff(int count ) {
  while (mySensorSerial.available() < count)
    delayMicroseconds(1);
}
In case your sensor is not sending at least count bytes (e.g. because of some transmission error on the serial line) the while loop will spin forever. You could easily check if you are stuck in this function by toggling a pin after the delay and watching it with a scope or LA. You could also try to replace the delayMicroseconds by a call to yield() or by delay(1). IIRC I once had issues with USB Serial when some code was spinning in a tight loop for a long time. The delay(1) or the yield() might help to keep USB Serial alive.

If it turns out that this is the root of your problem you should add some timeout mechanism to your waitBuff function. (actually this is a good idea in any case)

These of course are wild guesses only but it should be easy to check.
 
I also saw a Serial5.flush() but no other Serial5 use, and the flush() call seem to be intending to discard input rather than complete transmitting output. Probably not the problem, but just an observation. Also couldn't make much sense of the missing mySensorSerial definition...
 
I also saw a Serial5.flush() but no other Serial5 use, and the flush() call seem to be intending to discard input rather than complete transmitting output. Probably not the problem, but just an observation. Also couldn't make much sense of the missing mySensorSerial definition...

I suspect he has done something like this: #define MySensorSerial Serial5
to make his code more readable.
 
Thank you very much Luni, Paul and PDOS.

Yes, I am using
Code:
#define MySensorSerial Serial5
.

I have changed
Code:
Serial5.flush() to  MySensorSerial.clear()
and will replace
Code:
delayMicroseconds(1); with delay(1)
. I will also explore adding a timeout to the While loop to see if this will prevent the crashes.
 
Status
Not open for further replies.
Back
Top