Problem with #ifndef test for Serial port #define

Hi all

Am working on a project that uses two serial ports on a Mega. 1) Serial for communication with a PC using pySerialTransfer and 2) Serial3 for printing debug statements (back to PC via a nano gateway).

I had used a #define statement to give "Serial3" a defined name so I could change it to another Serial port easily in that one line while I was developing things.

works fine in the principal .ino file but I can't get the #define to show up correctly in any included files (am using an #ifndef test at the top of the included header to give it a default which should not be used).

The code will probably describe this better, attached below. I am expecting DEBUGSERIAL.println() to be resolved to Serial3.println() in both the ino and the cpp file, however it is being defaulted to Serial.println() in the included file - i.e. the #ifndef is returning true when I am expecting it to be false. I can't figure out why this is.

I'm using Arduino plugin for VSCode and intellisense is picking up my intention correctly (i.e. is detecting the #ifndef should be returning false as it is #defined in the principal .ino file).

Principal sketch:

#define DEBUGSERIAL Serial3

#include "otherFuncs.h"

void setup() {
    Serial.begin(19200);
    DEBUGSERIAL.begin(57600);
}

void loop() {

    loopPrint();   
    otherPrint();

    delay(500);
}

void loopPrint() {
    Serial.println("Serial0 print from loop");
    Serial3.println("Serial3 print from loop");
    DEBUGSERIAL.println("DEBUGSERIAL print from loop");
}

otherFuncs.h:

// default DEBUGSERIAL if not defined, otherwise use it

#ifndef DEBUGSERIAL

#define DEBUGSERIAL Serial

#endif

#include <Arduino.h>

void otherPrint();

otherFuncs.cpp:

#include "otherFuncs.h"

void otherPrint(){

    Serial.println("Serial0 print from other");

    Serial3.println("Serial3 print from other");

    DEBUGSERIAL.println("DEBUGSERIAL print from other");

}

Tx'd on Serial: (comments added)

Serial0 print from loop // correct
                                                       
Serial0 print from other // correct
                                                      
DEBUGSERIAL print from other // error! wrong serial port!
  

Tx'd on Serial3:

Serial3 print from loop // correct
                                                       
DEBUGSERIAL print from loop // correct
                                                   
Serial3 print from other // correct
 

Many thanks in advance for any pointers as to what might be wrong here

otherFuncs.cpp includes otherFuncs.h where DEBUGSERIAL Serial3 is not defind
it is defined in in main sketch file

you could have another header file which defines DEBUGSERIAL Serial3 which is then included at the start of the main sketch and the other header files

1 Like

Ah, I think I have misunderstood how these #includes work. Is this the same across Arduino and general C++? Or does some Arduino preprocessor go through all the cpp files in the directory first and pull in all their #includes before looking in the .ino?

I was certain that the principal file first calls its own h file (or in this case the start of the .ino) before working through the #includes. Indeed that's why I put the #define DEBUGSERIAL first in the file.

I've very probably misunderstood the few C++ tutorials I've done...

thanks again

In the arduino IDE, all the .ino files are combined into one .cpp file. The build chain also generates function prototypes and includes them in the .cpp file as well. It is then compiled as a separate "compilation unit." Any other .cpp files (like libraries, etc.) as also compiled separately. The linker then links all those compilation units together to make the final product to download to your board.

1 Like

source .ino, .c and .cpp files only include the .h files which they are explicitly told to include (plus .h files which the header files themselves include)
it is not recommended to include .c or .cpp source files as you can then end up with multiply defined references at link time

1 Like

Thanks @blh64 - is this combined cpp file available to look at somewhere post-build? Just curious, but what you say makes sense

Thanks @horace actually fair point I completely neglected an include guard on the example .h file. When I'm working with on a bigger project with multiple cpp and h files I have found that the include guards work fine to stop what you describe - but let me know if I've misunderstood

If you look at the output of compilation, it will show you where:

Archiving built core (caching) in: C:\Users\Brian\AppData\Local\Temp\arduino_cache_469159...

If you build your project, the path changes to arduino_build_xxxx versus arduino_cache_xxxx

Inside the sketch directory, you will see your sketch.ino.cpp file which is what actually gets compiled

For your .ino, the IDE throws in the #include <Arduino.h> implictly

I mainly use MPLABX and STM32cube IDEs - tend to forget about the Arduino IDE implicit include

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