BSOD when opening Arduino serial monitor, after USB re-plug and reboot

JBeale

Well-known member
I'm using Teensy 3.0 Windows Beta 6 (Oct.19 2012) on Windows XP Pro Version 2002 SP3 (32-bit). The Arduino environment got locked up for some reason, so I killed Arduino and Teensy Loader from task manager, and unplugged and re-plugged the USB connector on Teensy 3. I restarted Arduino and pressed the black button on Teensy and the bootloader showed the normal "Reboot OK" sign. So far, so good, but when I opened the Arduino serial port I got a BSOD. This also happened twice a few weeks ago on an earlier beta, and I think the sequence of events was the same but my memory is fuzzy.

EDIT: happened again today. It was at the moment of opening the Arduino serial monitor.

Here is the particular sketch:
Code:
/*
  Interface between Teensy 3 board and Linear Tech LTC2440 24-bit ADC
  Oct. 26 2012 John Beale

   LTC2440  <---------->  Teensy
   10: /EXT : ground (use external serial clock)
   11: /CS <- to digital pin 10  (SS pin)
   12: MISO -> to digital pin 12 (MISO pin)
   13: SCLK <- to digital pin 13 (SCK pin)
   15: BUSY -> to digital pin 9 (low when result ready)

   1,8,9,16: GND :  all grounds must be connected
   2: Vcc :   +5V supply
   3: REF+ :  +5V reference
   4: REF- :  GND
   5: IN+  :  Input+
   6: IN-  :  Input-
   7: SDI  : +5V  (select 6.9 Hz output rate, or GND for 880 Hz rate)
   14: Fo : GND  (select internal 9 MHz oscillator)

*/

#include <SPI.h>  // include the SPI library

#define VREF (5.0)    // ADC voltage reference
#define PWAIT (198)   // milliseconds delay between readings
#define SLAVESELECT 10  // digital pin 10 for CS/
#define BUSYPIN 9     // digital pin 9 for BUSY or READY/
#define LED 13


const int nsamples = 200;  // how many ADC readings to average together

// SPI_CLOCK_DIV16 gives me a 1.0 MHz SPI clock, with 16 MHz crystal on Arduino

void setup() {
 
 Serial.begin(115200);  // set up serial comm to PC at this baud rate
   
 pinMode (BUSYPIN, INPUT);
 digitalWrite(SLAVESELECT,LOW);   // take the SS pin low to select the chip
 delayMicroseconds(1);

 SPI.begin(); // initialize SPI, covering MOSI,MISO,SCK signals
 pinMode (SLAVESELECT, OUTPUT);
 digitalWrite(SLAVESELECT,HIGH);   // take the SS pin high to start new ADC conversion

 SPI.setBitOrder(MSBFIRST);  // data is clocked in MSB first
 SPI.setDataMode(SPI_MODE0);  // SCLK idle low (CPOL=0), MOSI read on rising edge (CPHI=0)  (not on Teensy3 ?)
 SPI.setClockDivider(SPI_CLOCK_DIV16);  // set SPI clock at 1 MHz. Arduino xtal = 16 MHz, LTC2440 max = 20 MHz
// digitalWrite(LED,HIGH);
 delay(5000);
// digitalWrite(LED,LOW);
 Serial.println("# LTC2440 v1.2 Oct.26 2012  jpb");  
 Serial.println("min,uVolts,pkpk,stdev");
 for (int i=0;i<2;i++) {  // throw away the first few readings, which seem to be way off
  SpiRead();
 }
} // end setup()

// =============================================================================
// Main Loop:
// acquire 'nsamples' readings, convert to units of volts, and send out on serial port

void loop() {

int i;
double mins;
double uVolts;  // average reading in microvolts

double datSum;  // accumulated sum of input values
double sMax;
double sMin;
long n;            // count of how many readings so far
double x,mean,delta,sumsq,m2,variance,stdev,pp;  // to calculate standard deviation   

  sMax = -VREF;  // set max to minimum possible reading
  sMin = VREF;   // set min to max possible reading
  sumsq = 0; // initialize running squared sum of differences
  n = 0;     // have not made any ADC readings yet
  datSum = 0;  // accumulated sum of readings starts at zero
  mean = 0; // start off with running mean at zero
  m2 = 0;
  
  for (i=0; i<nsamples; i++) {
    x = SpiRead();
    datSum += x;
    if (x > sMax) sMax = x;
    if (x < sMin) sMin = x;
                      // from http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
    n++;
    delta = x - mean;
    mean += delta/n;
    m2 += (delta * (x - mean));

  } // end for (i..)

  variance = m2/(n-1);  // (n-1):Sample Variance  (n): Population Variance
  stdev = 1E6*sqrt(variance);  // Calculate standard deviation in microvolts
  pp = 1E6 * (sMax - sMin);   // peak-to-peak difference of readings, in uV
  
  uVolts = datSum * (1E6) / n;

mins = (double) millis() / 60000;   // elapsed time in minutes

/*
//  ===== Print out ADC data as average value and statistics
Serial.print(mins,3); 
Serial.print(", ");
Serial.print(uVolts,3);
Serial.print(", ");
Serial.print(pp,3);
Serial.print(", ");
Serial.print(stdev,3);
Serial.println();
*/

} // end main loop


// =================================================================
// SpiRead() -- read 4 bytes from LTC2440 chip via SPI, return Volts
// =================================================================

double SpiRead(void) {

  long result = 0;
  byte sig = 0;    // sign bit
  byte b;
  double v;
  
  //Serial.println("Wait for ready/ low.");
  while (digitalReadFast(BUSYPIN)==HIGH) {}  // wait until ADC result is ready
  //Serial.println("Now doing SPI transfer");
    
  digitalWrite(SLAVESELECT,LOW);   // take the SS pin low to select the chip
  delayMicroseconds(1);  // probably not needed, only need 25 nsec delay
 
  b = SPI.transfer(0xff);   // B3
  if ((b & 0x20) ==0) sig=1;  // is input negative ?
  b &=0x1f;    // discard bits 25..31
  result = b;
  result <<= 8;  
  b = SPI.transfer(0xff);   // B2
  result |= b;
  result = result<<8;
  b = SPI.transfer(0xff);   // B1
  result |= b;
  result = result<<8;
  b = SPI.transfer(0xff);   // B0
  result |= b;
   
  digitalWrite(SLAVESELECT,HIGH);   // take the SS pin high to bring MISO to hi-Z and start new conversion
  
  if (sig) result |= 0xf0000000;    // if input is negative, insert sign bit (0xf0.. or 0xe0... ?)        
  Serial.println(result);
  v = result;
  v = v / 16.0;                             // scale result down , last 4 bits are "sub-LSBs"
  v = v * VREF / (2 * 16777216); // +Vfullscale = +Vref/2, max scale (2^24 = 16777216)
  return(v);  
}
 

Attachments

  • 2012-10-26 12.25.59.jpg
    2012-10-26 12.25.59.jpg
    212.9 KB · Views: 492
  • 2012-10-12 12.14.07.jpg
    2012-10-12 12.14.07.jpg
    198.9 KB · Views: 406
Last edited:
EDIT: Teensy not bricked- works and re-loads normally when connected to differerent USB port on same PC.

At first I thought my Teensy 3 was dead. The computer no longer saw it as a serial device when connected via USB, and pushing the small black button no longer caused the bootloader to respond. As far as I could tell, it was actually still running the last loaded sketch (after a five second delay on startup, generates SPI clock signals on pin 13, as intended) but the bootloader seemed to be kaput.

Of course to confirm this I'll need to try it on a different computer... Ah, it still does work on another port! First USB port on PC went bad? can the OS "blacklist" one particular USB port? That might make sense, if the PC remembered that a specific port and/or device had caused a BSOD.
 
Last edited:
Ok, this may be just an issue with one particular computer. After the earlier two BSODs today, I had my Teensy 3 happily acquiring data and sending it via USB to PC and it had been doing so for about an hour. At that point I connected my Canon S95 camera to a different USB port, and immediately got a BSOD! I have had that camera for several years, and this never happened with it on this or any other computer. Probably something messed up on the PC I'm thinking.
 
Back
Top