Writing a library file

Hello. I am struggling with some concepts on how to write a header file.
I have a project involving cameras, steppers, high power LEDs and a multitude of inputs and outputs.
After 2.5 years of learning, playing, testing etc I now need to knock dozens of working sketches into a single program.
I have at least 80 named constants that are used globally. A couple of examples are probably enough:

B4C3 = 17 (Block 4 Contact 3 connected to GPIO 17)
USB3B2 = 21 (USB3 #2(B) wire 2 connected to GPIO 21)

I would like to put these all into a header file but seem to have 2 options (or more?)

From the tutorial: Arduino - LibraryTutorial
It puts constants into the .h file as :
private:
int _pin;
int _B4C3

  • so I would have my list there (but under public in my case)
    then in the cpp file I would have
    { pinMode(B4C3, OUTPUT);
    _B4C3 = B4C3;
    }

but in the .h files supplied with the arduino IDE I see lists of
#define B4C3 17
with the cpp file containing
pinMode(B4C3, INPUT);

Are these methods equal? Is one better?
Will I be able to use either in this type of context?
REG_WRITE(GPIO_OUT_W1TC_REG,(1<<21));
REG_WRITE(GPIO_OUT_W1TC_REG,(1<<B4C3));

Thank you.
Baldi

One method has the constants defined in the class (and therefore the scope always needs to have the :: and the other is just preceding the constant identifier. The other just has C style definitions that are handled by the preprocessor as a textual substitution. You could also just define the constant using the ‘const’ keyword with global scope.

The first method is the more ‘modern’ method. As the compiler is provided with the intended type for the constant it can do more checking to see that you are using it correctly. As the second method does not do this, an error in the constant can producer some weird compiler error messages that could be hard to interpret.

The second is very common due to the amount of legacy code out there and older C programmers using what they know.

I use any of these three methods both depending on what I am trying to do.

If I want to make absolutely sure that my constants won’t clash with other global constants or #defines in header files I can’t control, then the class encapsulation method is preferable. Mostly I just define global typed constants, but there are other times you may actually want to use the macro preprocessor to your advantage so the #define method is an advantage.

Are the constants are for the use of the caller and passed as arguments to your methods/member functions then I would put them in the library header file as:

const byte B4C3 =       17; // (Block 4 Contact 3 connected to GPIO 17)
const byte USB3B2 =   21; // (USB3 #2(B) wire 2 connected to GPIO 21)

If they are constants, why have the user of the library pass them into the library if the library knows what the value are going to be? If the user of the library gets to choose the values, why not let the user decide how to name them?

Thank you both Marco & John. I think that half of my problems are caused by my not having grown up with C - the last serious programming that I did was back in the early 90's with Modula-2. My compiler (Topspeed) would also work with C so I looked at it but preferred the structure of Modula. Libraries in Modula-2 were essentially functions just lifted from working code and dropped into a separate file then used by reference just like in C. I am confused by the need for _underscoreVariables, double colons :: and some of the other syntax. At nearly 70 with failing eyesight too much punctuation is not good for me!

John: I am the only user of this software (although there is a minute possibility of the project becoming commercial) so my main aim of setting up a library is to declutter the working sketch. My experience was that an ever-growing program took longer to compile but by shifting tried-and-tested parts to a library they would be compiled once and only linked repeatedly when the current sketch was run, thereby reducing the compile time. Is this the case in Arduino C?

Thanks again.
Baldi

I am confused by the need for _underscoreVariables, double colons :: and some of the other syntax.

_ variables are only a common convention to show that a variable is a private member of the class. It is not part of the language.

Is this the case in Arduino C?

Unfortunately no. Arduino C++ user 'libraries' are really just a definition of a class to do a certain task. Using the IDE and derived tools, they are pulled in and recompiled EVERY time. The IDE also does a bunch of other work mangling the source code to create function prototypes and other stuff that would normally be done by the programmer. The system libraries are precompiled, I believe. Some of the stuff here may be interesting for you.

For robust commercial programming, there are third party tools that are more optimised to the 'normal' flow in a code shop, but they usually cost money.

Aah. Thanks Marco.