PDA

View Full Version : BSOD when opening Arduino serial monitor, after USB re-plug and reboot



JBeale
10-26-2012, 08:43 PM
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:

/*
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);
}

JBeale
10-26-2012, 09:28 PM
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.

JBeale
10-27-2012, 12:52 AM
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.