A tale of two Teensy's (Version 3.2)

ceremona

Well-known member
So I have two Teensy 3.2 MCU's and both seem to fail differently due to the following code fragment:

Code:
void setup(){
  randomSeed(analogRead(0));
 // pinMode(GSR,INPUT);
  analogWriteResolution(8);
  Serial.begin(9600);
  while (!Serial);
  pinMode(LED_BUILTIN, OUTPUT); 
  pinMode(speak1Pin, OUTPUT);

The only relevant thing to look at is this is the "while(!Serial);" line.

One teensy will run on this code but will only run from my laptop USB power. The other Teensy will not run at all from any power source. Weird.

When I comment out the "while(!Serial);" line both Teensy's run fine.
 
Last edited:
... until they see it they wait . . . a battery or computer not running a Serial Monitor will not activate Serial and while (!Serial) will sit and wait . . .

try this and after 4 seconds of no connect it will continue. If you don't require or use Serial - take out the while()

while (!Serial && (millis() <4000));
 
Ok, thanks for the improved code advice, but it still doesn't explain why one Teensy consistently works while the other Teensy consistently will not.
 
Ok, thanks for the improved code advice, but it still doesn't explain why one Teensy consistently works while the other Teensy consistently will not.

Perhaps there's something else relevant in the rest of the code you didn't show? Or maybe there's other hardware you've connected?

You can understand how we're forced to guess, since you've shown so little?
 
Fair point, Paul.

Rebooting my computer is one idea but does it explain why both teensy wont run the code on a usb power source other than my computer? Maybe. Yes, it compiles on both teensy's but I don't think the compile phase is hardware depended, so that should't matter.

No other hardware connected. I only have a usb cable to a teensy ( teensy is not even connected to a breadboard of any kind. ...just a teensy dangling in the wind).

Here's the full monty of my code:
<code>




// Play random tones in 4 different coils

const int speak1Pin = 9; // Teensy3 has Speaker on pwm digital pin 9
const int speak2Pin = 10;
const int speak3Pin = 3;
const int speak4Pin = 4;
const int speak1Dir = 11;
const int speak2Dir = 12;
const int speak3Dir = 7;
const int speak4Dir = 8;
//const int GSR = 5;
bool time1=false; bool time2=false; bool time3=false; bool time4=false;
elapsedMillis time;
//void Speak(int);
void Speak1(void); // we’re going to call this function at 8kHz
void Speak2(void);
void Speak3(void);
void Speak4(void);
IntervalTimer Speak1Timer; // interval timepassedr construct to call Speaker
IntervalTimer Speak2Timer;
IntervalTimer Speak3Timer;
IntervalTimer Speak4Timer;
uint32_t count1, count2, count3, count4;

void setup(){
randomSeed(analogRead(0));
// pinMode(GSR,INPUT);
analogWriteResolution(8);
Serial.begin(9600);
//while (!Serial);
pinMode(LED_BUILTIN, OUTPUT); // duh, LED is an output
pinMode(speak1Pin, OUTPUT); // the PWM speaker output is an output
pinMode(speak1Dir, OUTPUT);
analogWriteFrequency(speak1Pin, 50000);
analogWrite(speak1Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak1Dir,LOW);
// Speak1Timer.begin(Speak1, 800); //sets the ISR rate in microseconds for the TardisSpeaker – 8kHz rate
pinMode(speak2Pin, OUTPUT);
pinMode(speak2Dir, OUTPUT);
analogWriteFrequency(speak2Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
analogWrite(speak2Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak2Dir,LOW);
// Speak2Timer.begin(Speak2, 1000); //sets the ISR rate in microseconds for the TardisSpeaker – 8kHz rate
pinMode(speak3Pin, OUTPUT); // the PWM speaker output is an output
pinMode(speak3Dir, OUTPUT);
analogWriteFrequency(speak3Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
analogWrite(speak3Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak3Dir,LOW);
// Speak3Timer.begin(Speak3, 1300);
pinMode(speak4Pin, OUTPUT); // the PWM speaker output is an output
pinMode(speak4Dir, OUTPUT);
analogWriteFrequency(speak4Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
analogWrite(speak4Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak4Dir,LOW);
// Speak4Timer.begin(Speak4, 1600);
}

void loop() {


if (time<3000) {
if(time1==false) {
Serial.println("loop 1");
Speak1Timer.end();
Speak1Timer.begin(Speak1,random(800,1500));
time1=true; time2=false; time3=false; time4=false;
}
digitalWrite(7,HIGH);digitalWrite(8,HIGH); digitalWrite(11,HIGH); digitalWrite(12,HIGH);
//Serial.println(HIGH);
digitalWrite(LED_BUILTIN,LOW);
}
if (time< 6000 && time>=3000 ) {
if(time2==false) {
Serial.println("in 2 loop");
Speak2Timer.end();
Speak2Timer.begin(Speak2,random(800,1500));
time1=false; time2=true; time3=false; time4=false;
}
digitalWrite(7,LOW); digitalWrite(8,LOW); digitalWrite(11,LOW); digitalWrite(12,LOW);
}
if (time< 9000 && time>= 6000) {
//Serial.println("at 9000");
if(time3==false) {
Serial.println("in 3 loop");
Speak3Timer.end();
Speak3Timer.begin(Speak3,random(800,1500));
time1=false; time2=false; time3=true; time4=false;
}
digitalWrite(LED_BUILTIN,HIGH);
digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(11,HIGH); digitalWrite(12,HIGH);
}
if (time>=9000) {
if (time>12000) time=0;
if(time4==false) {
Serial.println("in 4 loop");
Speak4Timer.end();
Speak4Timer.begin(Speak4,random(800,1500));
time1=false; time2=false; time3=false; time4=true;
}
digitalWrite(7,LOW); digitalWrite(8,LOW);digitalWrite(11,LOW);digitalWrite(12,LOW);
}
}

void Speak1(void){
if (count1%2) analogWrite(speak1Pin,0); else analogWrite(speak1Pin,255); // flip flops the voltage on/off according to even/odd timer count
count1++; // increment sample
}
void Speak2(void){
if (count2%2) analogWrite(speak2Pin,0); else analogWrite(speak2Pin,255); //
count2++; // increment sample
}
void Speak3(void){
if (count3%2) analogWrite(speak3Pin,0); else analogWrite(speak3Pin,255); //
count3++; // increment sample
}
void Speak4(void){
if (count4%2) analogWrite(speak4Pin,0); else analogWrite(speak4Pin,255); //
count4++; // increment sample

}

//void Speak(int pin){
// if (count1%2) analogWrite(pin,0); else analogWrite(pin,255); //
// count1++; // increment sample
//}
</code>

Pardon some of the comments which make no sense. The code is constantly changing.
 
No includes. I tried to find the code tags in the form but they seemed to be missing, so I thought manually putting on <code> would work. Apparently not.
 
Code:
// Play random tones in 4 different coils

const int speak1Pin = 9; // Teensy3 has Speaker on pwm digital pin 9
const int speak2Pin = 10; 
const int speak3Pin = 3;
const int speak4Pin = 4;
const int speak1Dir = 11;
const int speak2Dir = 12;
const int speak3Dir = 7;
const int speak4Dir = 8;
//const int GSR = 5;
bool time1=false; bool time2=false; bool time3=false; bool time4=false;
elapsedMillis time;
//void Speak(int);
void Speak1(void); // we’re going to call this function at 8kHz
void Speak2(void);
void Speak3(void);
void Speak4(void);
IntervalTimer Speak1Timer; // interval timepassedr construct to call Speaker
IntervalTimer Speak2Timer;
IntervalTimer Speak3Timer;
IntervalTimer Speak4Timer;
uint32_t count1, count2, count3, count4;

void setup(){
randomSeed(analogRead(0));
// pinMode(GSR,INPUT);
analogWriteResolution(8);
Serial.begin(9600);
//while (!Serial);
pinMode(LED_BUILTIN, OUTPUT); // duh, LED is an output
pinMode(speak1Pin, OUTPUT); // the PWM speaker output is an output
pinMode(speak1Dir, OUTPUT);
analogWriteFrequency(speak1Pin, 50000); 
analogWrite(speak1Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak1Dir,LOW);
// Speak1Timer.begin(Speak1, 800); //sets the ISR rate in microseconds for the TardisSpeaker – 8kHz rate
pinMode(speak2Pin, OUTPUT);
pinMode(speak2Dir, OUTPUT);
analogWriteFrequency(speak2Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
analogWrite(speak2Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak2Dir,LOW);
// Speak2Timer.begin(Speak2, 1000); //sets the ISR rate in microseconds for the TardisSpeaker – 8kHz rate
pinMode(speak3Pin, OUTPUT); // the PWM speaker output is an output
pinMode(speak3Dir, OUTPUT);
analogWriteFrequency(speak3Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
analogWrite(speak3Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak3Dir,LOW);
// Speak3Timer.begin(Speak3, 1300);
pinMode(speak4Pin, OUTPUT); // the PWM speaker output is an output
pinMode(speak4Dir, OUTPUT);
analogWriteFrequency(speak4Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
analogWrite(speak4Pin, 0); // pull down the speaker to 0 to reduce current consumption
digitalWrite(speak4Dir,LOW);
// Speak4Timer.begin(Speak4, 1600);
}

void loop() {


if (time<3000) {
if(time1==false) {
Serial.println("loop 1");
Speak1Timer.end();
Speak1Timer.begin(Speak1,random(800,1500));
time1=true; time2=false; time3=false; time4=false;
}
digitalWrite(7,HIGH);digitalWrite(8,HIGH); digitalWrite(11,HIGH); digitalWrite(12,HIGH); 
//Serial.println(HIGH);
digitalWrite(LED_BUILTIN,LOW);
} 
if (time< 6000 && time>=3000 ) {
if(time2==false) {
Serial.println("in 2 loop"); 
Speak2Timer.end();
Speak2Timer.begin(Speak2,random(800,1500));
time1=false; time2=true; time3=false; time4=false;
}
digitalWrite(7,LOW); digitalWrite(8,LOW); digitalWrite(11,LOW); digitalWrite(12,LOW); 
}
if (time< 9000 && time>= 6000) {
//Serial.println("at 9000");
if(time3==false) {
Serial.println("in 3 loop"); 
Speak3Timer.end();
Speak3Timer.begin(Speak3,random(800,1500));
time1=false; time2=false; time3=true; time4=false;
}
digitalWrite(LED_BUILTIN,HIGH);
digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(11,HIGH); digitalWrite(12,HIGH); 
}
if (time>=9000) {
if (time>12000) time=0;
if(time4==false) {
Serial.println("in 4 loop"); 
Speak4Timer.end();
Speak4Timer.begin(Speak4,random(800,1500));
time1=false; time2=false; time3=false; time4=true;
}
digitalWrite(7,LOW); digitalWrite(8,LOW);digitalWrite(11,LOW);digitalWr ite(12,LOW);
}
}

void Speak1(void){
if (count1%2) analogWrite(speak1Pin,0); else analogWrite(speak1Pin,255); // flip flops the voltage on/off according to even/odd timer count
count1++; // increment sample
}
void Speak2(void){
if (count2%2) analogWrite(speak2Pin,0); else analogWrite(speak2Pin,255); //
count2++; // increment sample
}
void Speak3(void){
if (count3%2) analogWrite(speak3Pin,0); else analogWrite(speak3Pin,255); //
count3++; // increment sample
}
void Speak4(void){
if (count4%2) analogWrite(speak4Pin,0); else analogWrite(speak4Pin,255); //
count4++; // increment sample

}

//void Speak(int pin){
// if (count1%2) analogWrite(pin,0); else analogWrite(pin,255); //
// count1++; // increment sample
//}
 
Question: With the while(!Serial) commented out you said this runs fine on either Teensy?

As noted above Neither should run past that while(!Serial) until something connects to the USB Serial. Is this Windows? I'm not sure I saw that given. Windows will restore a given Teensy to an 'assigned' COM# port anytime it is connected. If something is monitoring that COM# - and not the other - that would explain the behavior.

If I am following - put the same sketch with the while(!Serial) on both and restart the PC and plug each in. With nothing else running neither will get past that while. Put this line before the while "pinMode(LED_BUILTIN, OUTPUT);" and then this also before the while "digitalWrite(LED_BUILTIN,1);" perhaps put his after the while "digitalWrite(LED_BUILTIN,0);"


Not much better to read . . . Code formatting got lost ?

In the IDE do 'Ctrl+T' to format the code before cut and paste. Also perhaps the 'CODE' tags were not upper case?

code.PNG
 
Last edited:
Code:
// Play tones in 4 different coils

const int speak1Pin = 9; // Teensy3 has Speaker on pwm digital pin 9
const int speak2Pin = 10;
const int speak3Pin = 3;
const int speak4Pin = 4;
const int speak1Dir = 11;
const int speak2Dir = 12;
const int speak3Dir = 7;
const int speak4Dir = 8;
//const int GSR       = 5;
bool time1 = false; bool time2 = false; bool time3 = false; bool time4 = false;
elapsedMillis time;
//void Speak(int);
void Speak1(void); // we’re going to call this function at 8kHz
void Speak2(void);
void Speak3(void);
void Speak4(void);
IntervalTimer Speak1Timer; // interval timepassedr construct to call Speaker
IntervalTimer Speak2Timer;
IntervalTimer Speak3Timer;
IntervalTimer Speak4Timer;
uint32_t count1, count2, count3, count4;

void setup() {
  randomSeed(analogRead(0));
  // pinMode(GSR,INPUT);
  analogWriteResolution(8);
  Serial.begin(9600);
  //while (!Serial);
  pinMode(LED_BUILTIN, OUTPUT); // duh, LED is an output
  pinMode(speak1Pin, OUTPUT); // the PWM speaker output is an output
  pinMode(speak1Dir, OUTPUT);
  analogWriteFrequency(speak1Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
  analogWrite(speak1Pin, 0); // pull down the speaker to 0 to reduce current consumption
  digitalWrite(speak1Dir, LOW);
  //  Speak1Timer.begin(Speak1, 800); //sets the ISR rate in microseconds for the TardisSpeaker – 8kHz rate
  pinMode(speak2Pin, OUTPUT);
  pinMode(speak2Dir, OUTPUT);
  analogWriteFrequency(speak2Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
  analogWrite(speak2Pin, 0); // pull down the speaker to 0 to reduce current consumption
  digitalWrite(speak2Dir, LOW);
  //  Speak2Timer.begin(Speak2, 1000); //sets the ISR rate in microseconds for the TardisSpeaker – 8kHz rate
  pinMode(speak3Pin, OUTPUT); // the PWM speaker output is an output
  pinMode(speak3Dir, OUTPUT);
  analogWriteFrequency(speak3Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
  analogWrite(speak3Pin, 0); // pull down the speaker to 0 to reduce current consumption
  digitalWrite(speak3Dir, LOW);
  //  Speak3Timer.begin(Speak3, 1300);
  pinMode(speak4Pin, OUTPUT); // the PWM speaker output is an output
  pinMode(speak4Dir, OUTPUT);
  analogWriteFrequency(speak4Pin, 50000); // Teensy 3.0 lets you do 400kHz comfortably, no aliasing or high freq artifacts
  analogWrite(speak4Pin, 0); // pull down the speaker to 0 to reduce current consumption
  digitalWrite(speak4Dir, LOW);
  //  Speak4Timer.begin(Speak4, 1600);
}

void loop() {
  //analogRead(GSR));
  if (time < 3000) {
    if (time1 == false) {
      Serial.println("loop 1");
      Speak1Timer.end();
      Speak1Timer.begin(Speak1, random(800, 1500));
      time1 = true; time2 = false; time3 = false; time4 = false;
    }
    digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(11, HIGH); digitalWrite(12, HIGH);
    //Serial.println(HIGH);
    digitalWrite(LED_BUILTIN, LOW);
  }
  if (time < 6000 && time >= 3000 ) {
    if (time2 == false) {
      Serial.println("in 2 loop");
      Speak2Timer.end();
      Speak2Timer.begin(Speak2, random(800, 1500));
      time1 = false; time2 = true; time3 = false; time4 = false;
    }
    digitalWrite(7, LOW); digitalWrite(8, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW);
  }
  if (time < 9000 && time >= 6000) {
    //Serial.println("at 9000");
    if (time3 == false) {
      Serial.println("in 3 loop");
      Speak3Timer.end();
      Speak3Timer.begin(Speak3, random(800, 1500));
      time1 = false; time2 = false; time3 = true; time4 = false;
    }
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(11, HIGH); digitalWrite(12, HIGH);
  }
  if (time >= 9000) {
    if (time > 12000) time = 0;
    if (time4 == false) {
      Serial.println("in 4 loop");
      Speak4Timer.end();
      Speak4Timer.begin(Speak4, random(800, 1500));
      time1 = false; time2 = false; time3 = false; time4 = true;
    }
    digitalWrite(7, LOW); digitalWrite(8, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW);
  }
}

void Speak1(void) {
  if (count1 % 2) analogWrite(speak1Pin, 0); else analogWrite(speak1Pin, 255); // flip flops the voltage on/off according to even/odd timer count
  count1++; // increment sample
}
void Speak2(void) {
  if (count2 % 2) analogWrite(speak2Pin, 0); else analogWrite(speak2Pin, 255); //
  count2++; // increment sample
}
void Speak3(void) {
  if (count3 % 2) analogWrite(speak3Pin, 0); else analogWrite(speak3Pin, 255); //
  count3++; // increment sample
}
void Speak4(void) {
  if (count4 % 2) analogWrite(speak4Pin, 0); else analogWrite(speak4Pin, 255); //
  count4++; // increment sample

}

//void Speak(int pin){
//    if (count1%2) analogWrite(pin,0); else analogWrite(pin,255); //
//    count1++; // increment sample
//}
 
Question: With the while(!Serial) commented out you said this runs fine on either Teensy?

As noted above Neither should run past that while(!Serial) until something connects to the USB Serial. Is this Windows? I'm not sure I saw that given. Windows will restore a given Teensy to an 'assigned' COM# port anytime it is connected. If something is monitoring that COM# - and not the other - that would explain the behavior.

If I am following - put the same sketch with the while(!Serial) on both and restart the PC and plug each in. With nothing else running neither will get past that while. Put this line before the while "pinMode(LED_BUILTIN, OUTPUT);" and then this also before the while "digitalWrite(LED_BUILTIN,1);" perhaps put his after the while "digitalWrite(LED_BUILTIN,0);"
 
The while(!Serial) was commented out because it is what seemed to cause the teensy to fail (well, one of the teensy's anyway). It was uncommented in the scenario I first described. This "while" line is already put before the LED_BUILTIN lines and is placed right after the Serial.begin(9600) line. I only commented it out as it was in-place. I am running OSX 10.11.
 
I am running OSX 10.11.

In all of your testing, are you sure you've selected the correct device in Tools > Ports every time you've switched boards?

Most Macs have at least bluetooth serial device. If you had the correct /dev/cu.usbmodemXYZ device selected, then unplugged the board and switched to the other one, failure to carefully reselect the other port name could easily end up in a situation where you're opening the bluetooth serial port. That would result in the Teensy getting stuck in "while (!Serial)", and the serial monitor will open and print nothing, giving the appearance it connected to your Teensy.
 
Given that this is a MAC - please follow posts from Paul - his note explains how the Serial is being acknowledged on MAC.

The while(!Serial) was commented out because it is what seemed to cause the teensy to fail (well, one of the teensy's anyway). It was uncommented in the scenario I first described. This "while" line is already put before the LED_BUILTIN lines and is placed right after the Serial.begin(9600) line. I only commented it out as it was in-place. I am running OSX 10.11.

I was only looking to confirm that as written with while commented - BOTH Teensy's do work.

As noted below - I was asking for the LED_BUILTIN to be enabled output and set ON before the while - so that it would show a sign of life in any case.

If I am following - put the same sketch with the while(!Serial) on both and restart the PC and plug each in. With nothing else running neither will get past that while. Put this line before the while "pinMode(LED_BUILTIN, OUTPUT);" and then this also before the while "digitalWrite(LED_BUILTIN,1);" perhaps put his after the while "digitalWrite(LED_BUILTIN,0);"
 
Ok. We have a winner. Paul.

I still don't understand why it would behave differently with two different teensy's as it did but when I manually reselected the port, the teensy that would never work came back to life even with the while(). Good thought defragster. Now that I am a little more hip to the way my system serial port can suck (and I thought I already knew how bad), I will be more vigilant to do code checks before the Serial calls.
 
One extra little question though... Why is it that the code would upload fine to the teensy (checked the teensyduino logs) and yet the port isn't selected in the arduino ide? I can appreciate that they are two separate processes and so, therefore... But I wonder if the teensyduino code is using better code or system calls than the Ardiuno IDE when it comes to re-establishing the serial connection on OSX when a new device is plugged in?
 
BTW. The bluetooth device was never selected on the arduino IDE. Bluetooth and the arduino devices showed as available but neither were selected after a new insert in this case. Seems like sometimes it autoselects correctly, sometimes not. Though it would consisently autoselect for one teensy and not the other if this was the problem. I can't test the other (working) teensy right now because it's across town.
 
One extra little question though... Why is it that the code would upload fine to the teensy (checked the teensyduino logs) and yet the port isn't selected in the arduino ide? I can appreciate that they are two separate processes and so, therefore... But I wonder if the teensyduino code is using better code or system calls than the Ardiuno IDE when it comes to re-establishing the serial connection on OSX when a new device is plugged in?

You don't say if you had to press the 'Button' to get uploads to work? When in bootloader mode it becomes a HID type device that is uniquely recognized by the teensy loader and not a serial device that can be confused.

The IDE PORT selection is for debug text output from the Teensy - that port is dropped by the IDE during upload.

<if the MAC works like Windows>

After selecting upload the IDE is out of the way the teensy loader will take the 'first' teensy it comes across and does a signaling over that port to have the Teensy go to bootloader mode (drops the baud rate to a unique low value).

If you want to program not the 'first' teensy - do a Verify build and then press the button on that desired Teensy.
 
Back
Top