Arduino Nano V3 only runs sketch correctly after hitting reset or starting serial monitor

Dear Friends,

I have been working on this project for a long time now, writing the code and testing it with great results. Once I decided that the code was ok, I tried to run the Nano simply by plugging it to the USB port, and the code does not run, I hit reset and it goes, or I can open the serial monitor and the code runs as well since it does a reset as well.

There have been a solution for the Uno boards by adding a Diode between the reset pin and the 5V. it shunts the spike that disrupts the reset when power is cycled. This solution did not work on the Nano, and there is no solution online to find. Please help.

As I mentioned, the code runs flawlessly if I run it directly after upload through the monitor or by hitting the reset button.

Appreciate any ideas.

Cheers,

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

#include <TimeLib.h>
#include <Wire.h>
#include <avr/wdt.h>
#include "BlueDot_BME280.h"



RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";


BlueDot_BME280 bme1;                                     //Object for Sensor 1
BlueDot_BME280 bme2;                                     //Object for Sensor 2

int bme1Detected = 0;                                    //Checks if Sensor 1 is available
int bme2Detected = 0;                                    //Checks if Sensor 2 is available


void setup() {

Serial.begin(9600);
Serial.println(F("SpeedLock"));

radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening(); 




//*********************************************************************
//*************BASIC SETUP - SAFE TO IGNORE**************************** 

//This program is set for the I2C mode

 bme1.parameter.communication = 0;                    //I2C communication for Sensor 1 (bme1)
 bme2.parameter.communication = 0;                    //I2C communication for Sensor 2 (bme2)
 


//*********************************************************************
//*************BASIC SETUP - SAFE TO IGNORE****************************
 
//Set the I2C address of your breakout board  

 bme1.parameter.I2CAddress = 0x77;                    //I2C Address for Sensor 1 (bme1)
 bme2.parameter.I2CAddress = 0x76;                    //I2C Address for Sensor 2 (bme2)

 

//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE*************************
 
//Now choose on which mode your device will run
//On doubt, just leave on normal mode, that's the default value

//0b00:     In sleep mode no measurements are performed, but power consumption is at a minimum
//0b01:     In forced mode a single measured is performed and the device returns automatically to sleep mode
//0b11:     In normal mode the sensor measures continually (default value)

 bme1.parameter.sensorMode = 0b11;                    //Setup Sensor mode for Sensor 1
 bme2.parameter.sensorMode = 0b11;                    //Setup Sensor mode for Sensor 2 


               
//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE*************************

//Great! Now set up the internal IIR Filter
//The IIR (Infinite Impulse Response) filter suppresses high frequency fluctuations
//In short, a high factor value means less noise, but measurements are also less responsive
//You can play with these values and check the results!
//In doubt just leave on default

//0b000:      factor 0 (filter off)
//0b001:      factor 2
//0b010:      factor 4
//0b011:      factor 8
//0b100:      factor 16 (default value)

 bme1.parameter.IIRfilter = 0b011;                   //IIR Filter for Sensor 1
 bme2.parameter.IIRfilter = 0b011;                   //IIR Filter for Sensor 2

 

//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE*************************

 //Next you'll define the oversampling factor for the humidity measurements
//Again, higher values mean less noise, but slower responses
//If you don't want to measure humidity, set the oversampling to zero

//0b000:      factor 0 (Disable humidity measurement)
//0b001:      factor 1
//0b010:      factor 2
//0b011:      factor 4
//0b100:      factor 8
//0b101:      factor 16 (default value)

 bme1.parameter.humidOversampling = 0b000;            //Humidity Oversampling for Sensor 1
 bme2.parameter.humidOversampling = 0b000;            //Humidity Oversampling for Sensor 2

 

//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE*************************

//Now define the oversampling factor for the temperature measurements
//You know now, higher values lead to less noise but slower measurements

//0b000:      factor 0 (Disable temperature measurement)
//0b001:      factor 1
//0b010:      factor 2
//0b011:      factor 4
//0b100:      factor 8
//0b101:      factor 16 (default value)

 bme1.parameter.tempOversampling = 0b000;              //Temperature Oversampling for Sensor 1
 bme2.parameter.tempOversampling = 0b000;              //Temperature Oversampling for Sensor 2

 

//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE*************************

//Finally, define the oversampling factor for the pressure measurements
//For altitude measurements a higher factor provides more stable values
//On doubt, just leave it on default

//0b000:      factor 0 (Disable pressure measurement)
//0b001:      factor 1
//0b010:      factor 2
//0b011:      factor 4
//0b100:      factor 8
//0b101:      factor 16 (default value)  

 bme1.parameter.pressOversampling = 0b011;             //Pressure Oversampling for Sensor 1
 bme2.parameter.pressOversampling = 0b011;             //Pressure Oversampling for Sensor 2 

  

//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE*************************

//For precise altitude measurements please put in the current pressure corrected for the sea level
//On doubt, just leave the standard pressure as default (1013.25 hPa);

 bme1.parameter.pressureSeaLevel = 1013.25;            //default value of 1013.25 hPa (Sensor 1)
 bme2.parameter.pressureSeaLevel = 1013.25;            //default value of 1013.25 hPa (Sensor 2)

//Also put in the current average temperature outside (yes, really outside!)
//For slightly less precise altitude measurements, just leave the standard temperature as default (15°C and 59°F);

 bme1.parameter.tempOutsideCelsius = 15;               //default value of 15°C
 bme2.parameter.tempOutsideCelsius = 15;               //default value of 15°C

 bme1.parameter.tempOutsideFahrenheit = 59;            //default value of 59°F
 bme2.parameter.tempOutsideFahrenheit = 59;            //default value of 59°F




//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE!************************

//The Watchdog Timer forces the Arduino to restart whenever the program hangs for longer than 8 seconds.
//This is useful when the program enters an infinite loop and stops giving any feedback on the serial monitor.
//However the Watchdog Timer may also be triggered whenever a single program loop takes longer than 8 seconds.
//Per default the Watchdog Timer is turned off (commented out).
//Do you need to run the Arduino for a long time without supervision and your program loop takes less than 8 seconds? Then remove the comments below!
 
//wdt_enable(WDTO_8S);                                 //Watchdog Timer counts for 8 seconds before starting the reset sequence
   


//*********************************************************************
//*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!*******

if (bme1.init() != 0x60)
{    
 Serial.println(F("Ops! First BME280 Sensor not found!"));
 bme1Detected = 0;
}

else
{
 Serial.println(F("First BME280 Sensor detected!"));
 bme1Detected = 1;
}

if (bme2.init() != 0x60)
{    
 Serial.println(F("Ops! Second BME280 Sensor not found!"));
 bme2Detected = 0;
}

else
{
 Serial.println(F("Second BME280 Sensor detected!"));
 bme2Detected = 1;
}

if ((bme1Detected == 0)&(bme2Detected == 0))
{
 Serial.println();
 Serial.println();
 Serial.println(F("Troubleshooting Guide"));
 Serial.println(F("*************************************************************"));
 Serial.println(F("1. Let's check the basics: Are the VCC and GND pins connected correctly? If the BME280 is getting really hot, then the wires are crossed."));
 Serial.println();
 Serial.println(F("2. Did you connect the SDI pin from your BME280 to the SDA line from the Arduino?"));
 Serial.println();
 Serial.println(F("3. And did you connect the SCK pin from the BME280 to the SCL line from your Arduino?"));
 Serial.println();
 Serial.println(F("4. One of your sensors should be using the alternative I2C Address(0x76). Did you remember to connect the SDO pin to GND?"));
 Serial.println();
 Serial.println(F("5. The other sensor should be using the default I2C Address (0x77. Did you remember to leave the SDO pin unconnected?"));
 Serial.println();

 
 
 while(1);
}
 
Serial.println();
Serial.println();

 

}

//The programm start idle state here...

void loop() 
{  
double StatP; //Static pressure value from sensor reading bme2
double DynP;  //Dynamic pressure value from sensor reading bme1
double correction; //a variable to determine the amount of correction applied to the StatP value each void loop
double critThreshold = 30.0;  //Value which triggers the transmition of data, Kmh (speed)
double transmittime = 60.0;  //how long we should transmit the data after exceeding the threshold
int SpeedOutput; //A variable for the calculated speed (IAS), in KMH. 
double landingtime = 10.0;
time_t loopStart, timenow;    //for timing the transmition loop
double StartAltitude;
int Altitude;  




 
correction = (bme1.readPressure()*100) - (bme2.readPressure()*100); //Determining offset between sensors
 
StatP = (bme2.readPressure()*100+correction); //Statp pressure is registered and the correction value is added (For first use!)
DynP = (bme1.readPressure()*100); //DynP is registered (For first use!)
 
SpeedOutput = ((sqrt(2*(DynP - StatP)/1.225))*3.6); //Formula, IAS=sqr2*(Dynamic P. - Static P.)/Air density *3.6convert m/s to Kmh. Speed is registered (first use) 

 while(SpeedOutput < critThreshold)   //Main threshold loop, waiting for take off
 {
    //Holds in the loop while speed is bellow threshold
    Serial.print(F("Waiting takeoff\n")); 
    StatP = (bme2.readPressure()*100+correction);           //Data registered inside the loop
    DynP = (bme1.readPressure()*100);
    SpeedOutput = ((sqrt(2*(DynP - StatP)/1.225))*3.6);
    delay(1000);
 }
 loopStart = now();
 timenow = now();
 StartAltitude = (bme2.readAltitudeMeter());  //this registers the altitude before lift off

while((timenow-loopStart) < transmittime) //Start of transmitting data for determined time (transmittime)
 {
    StatP = (bme2.readPressure()*100+correction);           //Data registered inside the loop
    DynP = (bme1.readPressure()*100);
    SpeedOutput = ((sqrt(2*(DynP - StatP)/1.225))*3.6);

       Serial.print(F("Correction\t\t")); 
       Serial.println(correction);

       Serial.print(F("SensorAltitude\t\t")); 
       Serial.println(bme2.readAltitudeMeter());
       
       Altitude = bme2.readAltitudeMeter() - StartAltitude; //this takes sensor altitude messurement and calculates relative height
       Serial.print(F("Altitude\t\t"));
       Serial.println(Altitude);

       Serial.print(F("IAS\t\t")); 
       Serial.println(SpeedOutput);

  
       radio.write(&Altitude, sizeof(int));  
       
         radio.write(&SpeedOutput, sizeof(int));  
     

      
       
 
      Serial.print(F("Dynamic Pressure\t\t")); 
      Serial.println(DynP);
       
      Serial.print(F("Static Pressure\t\t")); 
      Serial.println(StatP);

       Serial.print(F("Time\t\t"));
       Serial.println(timenow-loopStart);
       


  timenow = now();

delay(500);

 }   

loopStart = now();
timenow = now();

 while((timenow-loopStart) < landingtime) //Start registering landing time
 {
    StatP = (bme2.readPressure()*100+correction);           //Data registered inside the loop
    DynP = (bme1.readPressure()*100);
    SpeedOutput = ((sqrt(2*(DynP - StatP)/1.225))*3.6);

          while(SpeedOutput > critThreshold)   //Secondary threshold loop, waiting for landing
          {
             //Holds in the loop while speed is above threshold
              Serial.print(F("Wating for landing\n")); 
                     StatP = (bme2.readPressure()*100+correction);           //Data registered inside the loop
                     DynP = (bme1.readPressure()*100);
                     SpeedOutput = ((sqrt(2*(DynP - StatP)/1.225))*3.6);
                       Serial.print(F("IAS\t\t")); 
                       Serial.println(SpeedOutput);
                       
                     delay(1000);
              
          loopStart = now();
          }

     
       

   timenow = now();

delay(1000);

 }   
 



delay(1000);


}




Please follow the advice given in the link below when posting code. Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

So today I tested a theory I had, If i power the peripherals (pressure sensors) seperately with a different nano aside, the code on the first nano runs, which means that the nano misses the setup code when power cycled, because the power on the sensors is not stable yet when the arduino starts the code.

So, old bootloader is replaced with optiboot, not solved.

A 10000 ms delay at the begining of setup code, no success! I debugged with LEDs, I think it is a power problem, i have tested 3 different brand new nanos, all the same issue... I need to hit the damn reset to initialise properly!!

image

Can anyone say something please?

Hi,
Do you have a DMM to measure the 5V on the USB?

Can you please post a schematic, so we can see if there is any hardware problem?

Thanks.. Tom.. :smiley: :+1: :australia:

Many thanks, will do!

I have a multimeter, it measures 4.79 across the poles-

Why do you send two packets for the data? (2 byte data, 30 byte zeros)
Why don't you care whether the packet was delivered?

Don't use delay in a communication sketch.

Thank you very much Whandall for the feedback, I think I owe you some more information about the scope of my project.

I want to send speed and altitude data from a glider aircraft to the winch operator during the launch (Approx. 60 sec.), to optimize the winch launches. I don't care about the lost packages, I will use whatever received packages to show on a display.

The delay on the sketch for the communication part is intentional now to help me debug better, that is all. I will remove it later.

This is my very first program ever that I write. That is why it is inefficient and chaotic at the moment, but it works perfectly. Please explain to me more how I can send the most efficient package with both speed and altitude variables! I need some help on that, that is true.

Thank u again,

best regards,

Do you have an idea why i need to hit the reset every time I cycle power on the board for the code to run correctly? Do I need a watchdog circuit to delay the reset on the board till all peripherals are voltage stable?

I knew that, kind of.
But how would you distinguish the information, if sent in separate packets?
Why create that problem in the first place?

If you use a struct (or an int array), you know where each information is placed.
if you use radio.enableDynamicPayloads() in all sketches, you shrink the number of transmitted
bytes from 32 to 4, which is faster and needs less power.

The NRF configuration is only reset on a power cycle, that could be connected.

But not run correctly allows no diagnostic, only guesswork.

I can receive packages from the NRF, but the sensors are not correctly configured thus the sensor data are 0. When I hit reset on the arduino, things work perfectly.

Amazing! I will learn about it and try it out.

believe me I wanted to make sure that the hardware works first as expected, then I wanted to find the ideal why to send the packages. That is not my problem now, I cannot run the board once plugged in, I should hit the reset, and I cannot guarantee the pilots want to hit the reset every time before launching, i want it to be a hassle free system.

I guess if I could delay running the code even before the setup(), then it will work, but there is no way to do it, only way is a delay at the top of the setup loop, but that didnt cut it, some configurations happen before that!

I have run diagnoses with LED'S, and I can see that the code runs normal, except the sensors are not configured correctly. The reset configures them alright since that they already have stable power.

You could use a big delay before initializing the sensors in setup.

I used a delay(10000) at the beginning of the setup loop. Didnt help. maybe the sensors miss the following:

BlueDot_BME280 bme1; //Object for Sensor 1
BlueDot_BME280 bme2; //Object for Sensor 2

int bme1Detected = 0; //Checks if Sensor 1 is available
int bme2Detected = 0;

can I delay right after the #includes?

No, you would have to provide an own main() to get full control.

You should find out, what the problem really is.
The supply is probably ruled out, a delay before usage should have fixed that.

You are right, but how come if I power the sensors separately with a common ground and then plug the arduino, the code runs like the wind?