Why does this code not run on Arduino Nano ESP32 / Board keeps restarting

Hello community,

The attached code runs smoothly on a Arduino Nano and Arduino Uno R3 but completely fails on an Arduino Nano ESP32.
The code here won't display the final "Setup done ..". If the code is only slightly change, Arduino keeps restarting endlessly.

I've stripped the code down to only a few lines. It is about singleton classes.

Why does it not run on an Arduino Nano ESP32 but on several different boards?
Anybody with an explanation?

Thanks a lot Michael

MeasWaggon.ino


#include "HardwareTimerESP32.h"

void setup() {
    Serial.begin(115200);
    delay(5000);

    Serial.println("Project is starting up ....");

    HardwareTimerESP32::getInstance();
    HardwareTimerESP32::getInstance().Initialize();

    Serial.println("Setup done ...");

}

// the loop function runs over and over again forever
void loop() {
 }

HardwaretimerESP32.h
#ifndef _HARDWARETIMER_h
#define _HARDWARETIMER_h

#include "Arduino.h"

class HardwareTimerESP32 {
private:
    // === Required for Singletons ===
    HardwareTimerESP32();
    HardwareTimerESP32(const HardwareTimerESP32&) = delete;
    HardwareTimerESP32& operator=(const HardwareTimerESP32&) = delete;

public:
    // for singleton
    static HardwareTimerESP32& getInstance();

    int SetTimerInterval(int timeMs);
    void Initialize();
    void Loop();

protected:

};

#endif

HardwareTimerESP32.cpp

#include "HardwareTimerESP32.h"
#include "Arduino.h"

// -----------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------
HardwareTimerESP32::HardwareTimerESP32() {
    // Initialization code, if needed
}


// -----------------------------------------------------------------
// To get/create the singleton
// -----------------------------------------------------------------
HardwareTimerESP32& HardwareTimerESP32::getInstance() {
    static HardwareTimerESP32 instance;
    return instance;
}

int HardwareTimerESP32::SetTimerInterval(int timeMs) {
    Serial.println("HardwareTimerESP32.SetTimerInterval ...");
}


void HardwareTimerESP32::Initialize() {
    Serial.println("HardwareTimerESP32.Initialize ...");
    SetTimerInterval(1000);
}


void HardwareTimerESP32::Loop() {
}

Where does that library come from?

Look the code. There's an attached HardwareTimerESP32.h and .cpp

Now I tried it with the original Arduino IDE.

The result is more or less the same. Arduino Nano ESP32 keeps rebooting again and again

Here is what yoou can see on the serial monitor:

Project is starting up ....
HardwareTimerESP32.Initialize ...
HardwareTimerESP32.SetTimerInterval ...
Project is starting up ....
HardwareTimerESP32.Initialize ...
HardwareTimerESP32.SetTimerInterval ...
Project is starting up ....
HardwareTimerESP32.Initialize ...
HardwareTimerESP32.SetTimerInterval ...
Project is starting up ....
HardwareTimerESP32.Initialize ...
HardwareTimerESP32.SetTimerInterval ...
Project is starting up ....

OMG: Found out what the culprit was: :rage: :rage:
If you leave out or forget to return a value, when a function is declared to return something, then Arduino Nano ESP32 crashes miserably. !!!

int HardwareTimerESP32::SetTimerInterval(int timeMs) {
    Serial.println("HardwareTimerESP32.SetTimerInterval ...");

    return 0;   // <=========== Never omit to return something or youu will fail !!!!!!!!!!!!!!!!
}

It's uncertain what the outcome can be. The could could be simply stuck, Arduino can reboot, thus completely loosing the connection to the PC or just behave irrationally.

In my opinion, a BIG FAT BUG somewhere in a core library.

I am going to write a separate topic.

Why not declare the function as void ?

OMG, what if you just make a mistake?

It is a bug in your code.

I recommend you do this:

  1. Select File > Preferences... (or Arduino IDE > Settings... for macOS users) from the Arduino IDE menus.
    The "Preferences" dialog will open.
  2. Select "All" from the "Compiler warnings" menu in the "Preferences" dialog.
  3. Click the "OK" button.
    The "Preferences" dialog will close.

Due to an innovative configuration of the "Arduino ESP32 Boards" platform, this will cause the compilation to fail when such a bug is present:

C:\Users\per\AppData\Local\Temp\.arduinoIDE-unsaved2024226-17288-1wo2k7f.oucq\sketch_mar26b\HardwareTimerESP32.cpp: In member function 'int HardwareTimerESP32::SetTimerInterval(int)':
C:\Users\per\AppData\Local\Temp\.arduinoIDE-unsaved2024226-17288-1wo2k7f.oucq\sketch_mar26b\HardwareTimerESP32.cpp:22:1: error: no return statement in function returning non-void [-Werror=return-type]
 }
 ^
cc1plus.exe: some warnings being treated as errors

exit status 1

Compilation error: no return statement in function returning non-void [-Werror=return-type]

Note that Arduino IDE caches the compiled object from HardwareTimerESP32.cpp and will reuse that cache so the compilation of sketches that use previously compiled .cpp files won't fail even after that until after the next time the file is modified (which invalidates the cache and causes the file to be recompiled.

Hi there,
Two days ago I nearly got crazy because my simple code, that runs smoothly on several other Arduino boards would crash on an Arduino Nano ESP32.

I never got an answer in this forum, so I tried to investigate and after several hours, I found out what the reason is. In the example below, you can easily try out for yourself.

Never forget to return something in a function (method) when it was declared to return something, at least not in a class:


int Morse::crashExample() {
	Serial.println("Morse.crashExample");

    // if you omit / forget the retrun something
	// Arduino Nano ESP32 crashes (reboots, get stuck whatever)
	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	return 0;
}

When you forget to return a value, then Arduino crashes, restarts or simply stops execution of your code.
In my opinion, this is a BIG FAT BUG somewhere in a core library.

What does the community think?

So, here is the example code:

Morse.ino

#include "Morse.h"

Morse morse(13);

void setup() {
    Serial.begin(115200);
    delay(5000);

    Serial.println("Morse is starting up ....");
    morse.begin();
    Serial.println("Setup done ...");
}


void loop()
{
    morse.dot(); morse.dot(); morse.dot();
    morse.dash(); morse.dash(); morse.dash();
    morse.dot(); morse.dot(); morse.dot();
    morse.crashExample();
    delay(3000);
}

Morse.h


/*
  Morse.h - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
  */

#ifndef Morse_h
#define Morse_h

#include "Arduino.h"

class Morse
{

public:
    Morse(int pin);
    void begin();
    void dot();
    void dash();
    int crashExample();
private:
    int _pin;
};

#endif

Morse.cpp

/*
  Morse.cpp - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Updated by Jason A. Cox, February 18, 2023.
  Released into the public domain.
*/
#include "Arduino.h"
#include "Morse.h"

Morse::Morse(int pin)
{
	_pin = pin;
}

void Morse::begin()
{
	Serial.println("Morse.begin ...");
	pinMode(_pin, OUTPUT);
}

void Morse::dot()
{
	Serial.println("Morse.dot");
	digitalWrite(_pin, HIGH);
	delay(250);
	digitalWrite(_pin, LOW);
	delay(250);
}

void Morse::dash()
{
	Serial.println("Morse.dash");
	digitalWrite(_pin, HIGH);
	delay(1000);
	digitalWrite(_pin, LOW);
	delay(250);
}

int Morse::crashExample() {
	Serial.println("Morse.crashExample");

    // if you omit / forget the retrun something
	// Arduino Nano ESP32 crashes (reboots, get stuck whatever)
	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	return 0;
}

I have merged your cross-posts @snoppy1956.

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting can result in a suspension from the forum.

In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

Yes, I know, it's a bug. And thank you for the idea for the settings of compiler warning.

But still, in my opinion, a behavior like this is just forbidden, out of questions. Never in my programming live, I've encountered such a "thing"

You will, of course, have taken notice of the warning that the compiler gives you if you declare a function as returning a value and fail to do so

I don't think it's a bug in the core :wink: I can not install the core because I use a 32 bit operating system so can't test below.

If you set the warning level to ALL under file/preferences you should at least get a warning and the compiler might even treat the warning as an error.

The compilation caching does mean that, unfortunately, you will only see warnings generated by code in a .cpp file on compilations after the file has been modified:

There is a proposal at the link above to also cache warnings and display them on compilations where they are not currently displayed due to the cached object being used.

This is indeed very useful and I expected the compiler to behave exactly like this.

Unfortunately, the warning were OFF so I didn't see anything.

Besides, I am using MS Visual Studio together with Visual Micro as my Dev-Environment and I don't know is the things behave differently.

Anyway, thank you very much for the idea to switch on all warnings

The last time I used it was a decade ago so I don't know. I think that if Visual Micro has the option to set the compiler warnings level then it should work the same as in Arduino IDE. You can try it out by compiling this minimal demonstration sketch:

void setup() {}
void loop() {}
int foo() {}

I already played with the compiler warnings and it seems to work. But thank you anyway :grinning: :+1:

You are welcome. I'm glad if I was able to be of assistance.

Regards,
Per

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.