I have a hard time grasping the ‘good practice’ rules for header files. Got a main.cpp file and I have put most of the includes and global variables in the main.h file. Also all function declaration go into the main.h file.
And -also good practice I thought- I defined a version string as in:
#define VERSION “Version 1.0 10 february 2025”.
And put that in the main.h header file as well.
Now I have another cpp file -lets call it 2nd.cpp) with some function(s) in which the #define VERSION is used (as in Serial.println(VERSION)).
However the compiler complains that VERSION is not declared. Ok I get that, every cpp file is an Island for the compiler so I have to declare VERSION as external. But it is a #define. mmh problem.
So I made another header file (2nd.h) for this 2nd.cpp file. And put in an #include “main.h”
Problem solved? Well for the #define it is, however, now I have declared some global variables twice. I get that too, I defined an array and set its size to 1500.
char tempspace1500[1500];
I ended up in creating a third header file called ‘defines.h’, put the #define VERSION … in there and included defines.h in both main.cpp as the 2nd.cpp file. But this can not be the correct way can it?
Is there a good tutorial in howto do header files. A tutorial that is complete?
#ifndef _MY_HEADER_FILE_NAME_H_
#define _MY_HEADER_FILE_NAME_H_
/* include all headers whose types you need */
#include <Arduino.h>
/* define macros */
#define VERSION 0x010203
#define MANIPULATE(x) ((x) + 1)
/* declare global variables */
extern int myGlobalInt;
extern String myGlobalString;
extern char myBuf[1500];
/* declare global functions */
String my_global_function(int a, int b);
#endif /* _MY_HEADER_FILE_NAME_H_ */
And the corresponding cpp file should look like
#include "myHeaderName.h"
/* define global variables once */
int myGlobalInt = 123;
String myGlobalString = "ABC";
char myBuf[1500] = {0};
/* define global functions once */
String my_global_function(int a, int b) {
return String(a + b);
}
So a header file contains declarations without settings. You then set (give a value) to these declarations in the cpp file.
That seems clear, although I will probably get back to this forum for the more advanced exceptions and ambiguities.
Now in your example you set
extern char myBuf[1500];
and then (again putting 1500 in the size) in the cpp file:
char myBuf[1500] = {0};
Would it be possible to set the array size=1500 in only one of these files? In this example I must keep track of both. Whenever I want/need to change the one I would have to change the other as well?
With the following I have no idea what to do. I copied a class that essentially streams a print, println and/or printf statement to two different streams, in my case a Telnetstream and the Serial stream:
// Following class to stream a print(f) statement to two streams
// from Juraj (see telnetstream @ github)
class TeePrint: public Print {
Print &out1;
Print &out2;
public:
TeePrint(Print &_out1, Print &_out2) : out1(_out1), out2(_out2) {}
virtual size_t write(uint8_t b) {
out1.write(b);
out2.write(b);
return 1;
}
};
And in my main.cpp:
TeePrint tee(Serial, TelnetStream); // stream print(f) statements to both Serial as Telnet.
I can now use tee.println(“Hello World”); and that will be streamed to both Telnet as Serial.
I have several .cpp files in one project and some of them also will use this tee.print() class. But I get errors in compilation. I read you’d have to put the class in a .h file, e.g. functions.h.
I tried several solutions, but none work. Since I am not skilled (at all) in cpp I am aiming in the dark. Pls explain where I would put this class, how to define it in other cpp files and where do I put the actual declaration:
TeePrint tee(Serial, TelnetStream);
??? Again, pls be very specific as I do not know how to program CPP.