Sketch Fails to Restart After Power Cycle

When the sketch#1 is uploaded, it WILL NOT restart after a power cycle and must be reloaded.

When the Blink program from the built in examples is uploaded it WILL restart after a power cycle.

When the ReadAnalogueVoltage from the built in examples is uploaded it WILL NOT restart after a power cycle.

Sketch #1

-drives a sensor which communicates with Micro#1 via I2C on pins 2 and 3

-drives Xbee#1 which communicates with Micro#1 on pins 5 and MOSI

Xbee#1 is paired with Xbee#2 on another breadboard on which also sits Micro #2 and an LCD for output. Xbee#2 uses pins 3 and MOSI to communicate with Micro#2.

Sketch#2 restarts properly in Micro#2.

When Micro#1 and Micro#2 are swapped and sketch#1 loaded in Micro#2 the situation is the same, ie sketch#1 WILL NOT restart.

Saving this annoying situation, the whole thing works well. Valid data is acquired by the sensor, sent properly from one Xbee to the other and is accurately displayed on the LCD.

It cannot be (at least I don’t think it can be)

-a fault on either bootloader

-a fault on either Micro

-unlikely to be RFI or other EMI interfering with the bootloader restarting the sketch as the Blink program does restart

I must find out what is going on before I start shooting in the dark.

HERE IS THE CODE FOR SKETCH#1

/****SKETCH_DAremoteDriver
READS BME280, CALCULATES DA, SENDS DATA TO COORD. XBEE****/

#include <SoftwareSerial.h>
#include <Wire.h>
#include <math.h> 
#include <cactus_io_BME280_I2C.h> 

const float c0 = 6.1078;           //constants for satVapourPress
const float c1 = 7.5;
const float c2 = 237.3;
const float RdryAir = 286.9;       // gas constant for dry air J/kg K
const float RwaterVapour = 461.5;  // gas constant for water vapour J/kg K
const float dA1 = 44.3308;         // constants for densityAlt
const float dA2 = 42.2665;
const float dA3 = 0.234969;
const float kmToFt = 3280.0;        // converts km to feet
const float cToK = 273.15;          // converts *C to *K
const float mbToPasc = 100;         // converts millibars to pascals

const int Rx = 16; //the micro can't use pin 2 for Rx
const int Tx = 5;

float satVapPress;        // saturation vapour pressure mb
float parPressWatVap;     // partial pressure of water vapour mb
float parPressDryAir;     // partial pressure of dry air mb
float airDensity;         // air density kg/m3
float densityAlt;         // density altitude in feet
float tempVar1;           // temporary variables for long equations
float tempVar2;
float temperature;        // sensor temperature value
float rh;                 // sensor relative humidity value
float pressure;           // sensor pressure value

int tempDA;

/****SO THAT END POINT XBEE 2 BYTE DATA CAN BE SENT AND REASSEMBLED AT COORDINATOR XBEE****/
int LSBtempDA;
int MSBtempDA;
int LSBpressure;
int MSBpressure;
int divisor = 256;
int rhInt;
int temperatureInt;
int pressureInt;

SoftwareSerial xbee(Rx, Tx);
BME280_I2C bme;           // Create BME280 object I2C using address 0x77
  
void setup() 
    {
    //delay(5000);


    //pinMode(2, INPUT_PULLUP);
    
    Serial.begin(9600);
    while (!Serial);   //because it takes a while to make the serial connection which is why println would not display
    xbee.begin(9600);
    
    Serial.println("Bosch BME280 Pressure - Humidity - Temp Sensor | cactus.io"); 
   
    if (!bme.begin()) 
       { 
       Serial.println("Could not find a valid BME280 sensor, check wiring!"); 
       while (1); 
       //pins A4 (SCK) and A5 (SDA), used for I2C on the Uno are pins 2 (SDA) and 3 (SCL) on the micro
        } 
        
    bme.setTempCal(-0.5);        // Temp was very close so subtract 0 degree 
    Serial.println("Pressure\tHumdity\t\tTemp\t\tsatVapPress\tparPressWatVap\tparPressDryAir\tairDensity\tdensityAlt"); 
    }

void loop()
    { 
    bme.readSensor(); 
    temperature = bme.getTemperature_C();
    pressure = bme.getPressure_MB();
    rh = bme.getHumidity();

    satVapPress = c0 * pow(10, (c1 * temperature) / (c2 + temperature));   //calculate water vapour saturation pressure
    parPressWatVap = satVapPress  * rh / 100;                              //calculate water vapour partial pressure
    parPressDryAir = pressure - parPressWatVap;                            //calculate dry air partial pressure

    tempVar1 = parPressDryAir * mbToPasc / (RdryAir * (temperature + cToK));          //first term of airDensity
    tempVar2 =  parPressWatVap * mbToPasc / (RwaterVapour * (temperature + cToK));    //second term of airDensity
    airDensity = tempVar1 + tempVar2;                                                 //calculate air density

    int densityAlt = round((dA1 - dA2 * pow(airDensity, dA3)) * kmToFt);   //calculate density altitude in feet

    Serial.print(pressure); Serial.print(" mb\t");        
    Serial.print(rh); Serial.print(" %\t\t");               
    Serial.print(temperature); Serial.print(" *C\t");    
    Serial.print(satVapPress);  Serial.print(" mb\t"); 
    Serial.print(parPressWatVap);  Serial.print(" mb\t\t"); 
    Serial.print(parPressDryAir);  Serial.print(" mb\t");    
    Serial.print(airDensity);  Serial.print(" kg/m3\t"); 
    Serial.print(densityAlt);  Serial.println(" ft");

    tempDA = abs(densityAlt);

    /****Each call sends 3 bytes to coordinator xbee packing its read buffer with 12 bytes.***/
    DisassembleSendData(densityAlt);
    DisassembleSendData(temperature);
    DisassembleSendData(pressure);
    DisassembleSendData(rh);

    delay(4000);    // Add a 4 second delay     
    }


void DisassembleSendData (float dataToDisassemble)
  {
  int tempVar;
  int LSB;
  int MSB;
  int divisor = 256;
  
  /***Disassembles sensor data into 3 bytes***/
  tempVar = dataToDisassemble;
  LSB = tempVar % divisor; 
  MSB = (tempVar - LSB) / divisor; 
  
  /***Sends 2 bytes to coordinator xbee read buffer***/
  xbee.write(LSB);
  xbee.write(MSB); 
  }

HERE IS THE CODE FOR SKETCH#2

****This drives the Coordinator Xbee.  It receives data from the Remote Xbee, conditions it
and presents it for output.****/

#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

SoftwareSerial xbee(16, 3); //Rx TX
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

int temperature;
int rh;
int pressure;
char c;
int densAlt;
int LSB;
int MSB;
int fractionalPart;
int LSBpressure;
int MSBpressure;
int divisor = 256;

int counter = 0;

char units;

void setup() 
  {
  Serial.begin(9600);
  xbee.begin(9600);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  Serial.println("hi fred");
  Serial.print("in setup");
  //lcd.print("hello, world!xxx");
  }

void loop() 
  {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  
  if (xbee.available() >= 8)
    {
    //Density altitude data     
    //fractionalPart = xbee.read();      
    LSB = xbee.read();
    MSB = xbee.read();
    units = 'f'; 
    //AssemblePrintData(fractionalPart, LSB, MSB, units);
    AssemblePrintData(LSB, MSB, units);

    //Temperature data
    //fractionalPart = xbee.read();      
    LSB = xbee.read();
    MSB = xbee.read(); 
    units = 'C'; 
    //AssemblePrintData(fractionalPart, LSB, MSB, units);
    AssemblePrintData(LSB, MSB, units);
    
    lcd.setCursor(0, 1);

    //Pressure data
    //fractionalPart = xbee.read();      
    LSB = xbee.read();
    MSB = xbee.read();
    units = 'm';  
    //AssemblePrintData(fractionalPart, LSB, MSB, units);
    AssemblePrintData(LSB, MSB, units);

    //Relative humidity data
    //fractionalPart = xbee.read();      
    LSB = xbee.read();
    MSB = xbee.read();
    units = '%';  
    //AssemblePrintData(fractionalPart, LSB, MSB, units);
    AssemblePrintData(LSB, MSB, units);
    }
  //Serial.println("out of if");
    
  }

void AssemblePrintData(int LSB, int MSB, char units) //(int xbee.read(), int xbee.read(), int xbee.read()) ???
  {
  lcd.print((MSB * divisor + LSB)); /*lcd.print("."); lcd.print(abs(fractionalPart));*/ lcd.print(units); lcd.print(" ");
  Serial.print((MSB * divisor + LSB));/* Serial.print("."); Serial.print(abs(fractionalPart));*/ Serial.println();
  }

What’s that commented out delay(5000) for?

On upload, you already have a delay after power up, on a cold power up you don’t. Is that delay significant?

It is my understanding, which experience has shown is not always correct, that on a cold power up the boot loader delays for a few seconds to see if a new program is to be downloaded. If not, the existing program is restarted. Does this not qualify as a delay on cold power up?

One possibility that was explored was that RFI or some other form of EFI was confusing the boot loader into thinking that a new program was about to be downloaded, and after some time (10 sec. perhaps) it timed out and just did nothing. The suggestion was made to use pull ups on any floating pins to fix this which was done but without positive result.

The baffling thing is that one Micro behaves well, restarting its program on cold power up reliably.

In any event, I have substituted an Uno for the misbehaving Micro and the program in the Uno always restarts on cold power up.