Teensy 2.0 Serial I/O sometimes hangs

Status
Not open for further replies.
I have a Teensy 2.0 mounted on a Perma Proto board with 10 voltage dividers. Those are fed by 12 volt signals into 10 terminals mounted on top of the box containing the Teensy and other components (see images). 12 volts comes into the box, and is converted to 5 volts for the Teensy and a dual relay board.

The Teensy just waits for instructions from the PC, and if it receives an ASCII "1", it activates relay #1, an ASCII "0" deactivates (opens) relay #1, and the only other command is an ASCII "9", which starts the reading process. Relay 2 is activated, it waits 1 second for the sensors connected to settle, and the 10 GPIO inputs are read and accumulated, and the result fed out the serial port to the PC. Very simple, yet it hangs fairly often. If the Teensy loader program is running, I can press the reset button on the Teensy, and it reloads and reboots. Otherwise, I have to kill the power from both the USB port and the 5V regulator.

This is for a production line, and simply cannot hang like this. I've used Teensy's for a long time and cannot figure out why it hangs. If anyone has any ideas what I'm doing to cause this, or if there is a better way to get data to and from the Teensy 2.0 and the Windows 10 PC, please let me know.

Thanks in advance for your help!

Here's the code:
Code:
const int ledPin = 11;  // 11->Teensy 2.0; 13->Teensy 3.0 +
const int relayPin1 = 15;
const int relayPin2 = 14;
int counter = 0;
int incomingByte = 0;
char foo[128];
int availCount=0;

// the setup() method runs once, when the sketch starts
void setup()
{
  Serial.begin(9600); // USB is always 12 Mbit/sec
  pinMode(ledPin, OUTPUT);

  // The dual relay we're using is opto-isolated, which means the logic is reversed.
  // Therefore, to ensure the power output is off, set the control pins HIGH immediately
  // to ensure the relays are off.
  pinMode(relayPin1, OUTPUT);
  digitalWrite(relayPin1, HIGH);
  
  pinMode(relayPin2, OUTPUT);
  digitalWrite(relayPin2, HIGH);

  /* 
   * Set pins as input
   */
  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  
}

void loop()
{

  // Check the input queue. This is how we know when to turn the relays on and off.
  availCount = Serial.available();
  if (availCount > 0) {

    incomingByte = Serial.read();
    availCount = 0;

    // Relay board is opto-isolated, so the inputs are negative logic
    if (incomingByte == 49) {        // ASCII 1 - Relay 1 on
      digitalWrite(relayPin1, LOW);
    } else if (incomingByte == 48) { // ASCII 0 - Relay 1 off
      digitalWrite(relayPin1, HIGH);
    } else if (incomingByte == 57) { // ASCII 9 - Read all inputs and report

      // Turn on the sensor relay
      digitalWrite(relayPin2, LOW);

      delay(1000); // Give the relay a chance to settle

       // Read all the sensor inputs and return the data
      int dState = 0;

      int ii;
      for (ii=0; ii<10; ii++) {
        if (digitalRead(ii) == HIGH) {
          dState += (1 << ii);
        }
      }

      digitalWrite(relayPin2, HIGH);
      sprintf(foo, "%d", dState);
      Serial.println(foo);
    }

  }
  digitalWrite(ledPin, HIGH);   // set the LED on
  delay(30); // Leave the LED on for 0.03 second
  digitalWrite(ledPin, LOW);    // set the LED off
  delay(270);
}
 
TeensyPermaProto.jpgTeensyGPIOBox#1.jpg
 
'Sometimes hangs' ? Not sure what that means and what goes with that?

Does the LED stop blinking with this code running in loop() when Serial hangs?:
Code:
// …

  digitalWrite(ledPin, HIGH);   // set the LED on
  delay(30); // Leave the LED on for 0.03 second
  digitalWrite(ledPin, LOW);    // set the LED off
  delay(270);

It sounds like this has been in use and working well for some time up to this point?

That use of delay()'s will halt the loop() for .3 seconds each pass before checking for this : availCount = Serial.available();
 
Hanging Serial with Teensy 2.0

Hi - Thanks for the response.

Yes, it looks like the LED stops blinking and is steady on. But if I shake the lid that it's mounted in, I can see that it's flashing on and off very quickly.

What I mean about hanging is that the Teensy will no longer respond to commands. I use the Serial Monitor to send the commands, and after a while, it stops responding. It might take two or three commands, or 20 or more.

This is not yet in production. I'm building a system for installation when I finish. It was originally set up to just loop, and read the GPIO states and send the results every 1/2 second. That code below just flashed the LED so I could tell it was still running. That is also it's current purpose. That original system also hung sometimes, so I switched to sending commands to try and fix the problem. Doesn't seem to. I'm open to other ways to do this.

Another thing that happens is that it seems to skip the delay(1000) call. I'll send command 9 so that it turns on relay 2, and waits one second, the reads the GPIO inputs and sends back the results. When it hangs, it will often turn on relay 2, and then immediately turn it off, like it ignored the delay call.

I thought perhaps I was running out of memory, but I'm not allocating any. All the variables are global or stack based.

If I don't send any commands, it will run for days. I'm really stumped about what is happening.

Thanks for helping.

'Sometimes hangs' ? Not sure what that means and what goes with that?

Does the LED stop blinking with this code running in loop() when Serial hangs?:
Code:
// …

  digitalWrite(ledPin, HIGH);   // set the LED on
  delay(30); // Leave the LED on for 0.03 second
  digitalWrite(ledPin, LOW);    // set the LED off
  delay(270);

It sounds like this has been in use and working well for some time up to this point?

That use of delay()'s will halt the loop() for .3 seconds each pass before checking for this : availCount = Serial.available();
 
Looks like the wires between the Teensy and relay board are permanently soldered? Any way you can disconnect the relays but still run the same code on Teensy? Then you could see if the crashing still happens without the power consumption and other electrical activity of whatever those relays control.

Or if you can't disconnect the wires, maybe try the same code with the digitalWrite that turns on the relay commented out. Can Teensy do everything else successfully? My point is the problem may be a bug or oversight somewhere in the code unrelated to the relays and power switching. Or it might only happen if the relays are connected and switching. Knowing which of those might help to at least focus your effort to the right place.
 
Again maybe grabbing at straws... But if it were me, some of the things I would try include:

a) Get rid of sprintf and your 128 byte array foo.
What happens if you replace:
Code:
      sprintf(foo, "%d", dState);
      Serial.println(foo);
with:
Code:
Serial.println(dstate, DEC);
with foo removed?

b) More debug stuff. I would hook up logic analyzer and use some of the IO pins, where set certain pins into states around pieces of code and try to see where it hangs... (If it hangs)...
b1) Could both programs (Teensy 2 and host be changed) such that maybe T sends back more info, like it received the command... So you can find out where it stopped...

c) don't know how fast you are sending this data. Or if they can happen right after each other... But if not I would probably make sure your queue is empty after each command....
Code:
if (availCount > 0) {

    incomingByte = Serial.read();
    availCount = 0;

    // Relay board is opto-isolated, so the inputs are negative logic
    ...
    // Skip all other bytes in queue... 
    while (Serial.read() != -1) ; 

  }

Again just grabbing at different straws....
 
Hi Paul and KurtE,

Thanks for the response. I disconnected the relay signal wires and made the changes KurtE expressed. The board that the Teensy is soldered to connects to the box through these little lever connectors you can see in the previous picture. So I can just pull up on the lever and take the wires out.

I did that with the relay signals, and have run the "9" command over 200 times, and have not been able to get it to crash. It looks like that is where the problem is.

I hooked an oscope to the relay signal line, and it looks fine. Then I hooked the probe up to the Teensy's power input. I keep getting this when the relay switches on.

TeenyPowerGlitch.PNG

Do you think that 2 volt glitch could cause issues like I'm seeing? If so, maybe just a capacitor on the 5 volt supply would fix it. What do all ya'll think?

Thanks again!
Steve
 
Update - I had a 47 uF, 6.3 V electrolytic capacitor left over from another project, and I held it right next to the Teensy 5V input, and could not get it to fail. I'm getting my solder iron out to attach it securely. I'll let you know after more testing. Thanks for all your help!
 
If problems still happen rarely, maybe also try adding a 1N5817 or similar schottky diode between the incoming power and the capacitor & Teensy. The diode will allow the current to come into the capacitor, but not flow back out when the power supply source drops momentarily.

Of course, a more capable power supply might also be something worth considering. Or if this is running only from the USB power, maybe a dedicated power source known to be sufficient for the relays and other hardware might be the more proper solution.
 
It has now run for several hours, accessing the sensors by turning on the relay over 1300 times, with no errors. I'm calling it good. Thanks to both of you for all your help!

TeensyGlitchFix.jpg

Steve
 
Status
Not open for further replies.
Back
Top