I would like to put some personal standard functions into an extra file. But I don't like this add a tab-function.
The tab alsways gets opened with the main *.ino-file.
I made some quick tests with a *.h and/or *.cpp-file. Bu this did not work.
What I would like to have is something like a macro which replaces an identifier with other text
example for a macro
#define TLA "Three Letter Acronym"
whereever in the code 'TLA' is written it gets replaced by
"Three Letter Acronym"
What I would like to have is
inside an extra file named 'myStandardFunctions.txt'
void myFunc1() {
// do 1
}
void myFunc2() {
// do 2
}
and writing in the maincode
insert "myStandardFunctions.txt"
which will do the same as a copy & paste of the code-section
I have looked up the library-tutorial but I don't like all the hassle with defining a class etc.
The only purpose of this construction is: make my *.ino-file smaller so I don't have to move over the standard-functions but without sketch - Add file
If it is possible to use an includefile without the hassle of defining a class etc. etc. I will consider that too.
So if it is possible to use include-files with functions in the includefile that get just added to the rest of the code like copy & paste this would be an option too.
You don't need to define a class to make a library. That's just a common approach. You can just throw your macro definitions in a .h file and install that as a library.
The library approach is great when you want to share code between multiple sketches. If you only need to use the code in a single sketch, another option is to put the file under the src subfolder of your sketch folder: https://arduino.github.io/arduino-cli/latest/sketch-specification/#src-subfolder
Then use a relative include in the sketch, for example, if your sketch folder structure looks like this:
then the #include directive should look like this:
#include "src/myStandardFunctions.h"
But you should be warned that there isn't full support for the src subfolder. There is a bug in the Arduino IDE's "File > Save As..." where it won't save the contents of the src subfolder to the new location. The Arduino Web Editor doesn't have any support at all for the src subfolder.
thank you for answering.
first I was fooling myself through a missing semicolon in my testfile.
Then I had to learn the include-file has to have the extension ".h"
It seems to be enough if there is a *.h-file. my code compiled without a *.cpp-file
And it seems to be a good idea to add
Robin2:
The entire code of the digitalWriteFast library is in a single .h file
Yes, but it's written entirely with macros. Having regular (non-class, non-template) code in a .h file is a really bad idea. Just like having variable definitions (as opposed to declarations) is. If that .h file gets included in more than one compilation units, the linker will error out due to the multiple function and variable definitions.
UKHeliBob:
To me the fact that the .h file always gets opened with the .ino is a positive advantage
What is it that you don't like about it ?
I'm a keyboard-freak. If I can do something with keyboard-shortcuts I'm faster than tossing the mouse.
I have written quite a few keyboard-shortcuts with Autohotkey like
create a copy of the line the cursor is in put linecommet at left like that
Serial.print("My Text");
Shift-Ctrl-D and pop!
//Serial.print("My Text");
Serial.print("My Text");
so I can quickly do things like
//Serial.print("My Text");
Serial.print("My alternative Text");
without modifying the original line of code with just one keypress
shift cursor-down del is much faster than correcting back the original line of code
If I want to look-up something in the added file I prefer to have it opened in an extra editor
and do left-hand Alt-Tab over right hand mouse-move which moves the mouse away from the place I want to have the mouse short after the lookup. And I don't like it if it is additionally opened in an ArduIDE-tab.
best regards Stefan
I think the correct term is "translation unit" (though I seem to be drawn to calling it a "compilation unit"):
The combined .ino files of the sketch are a translation unit. Each .cpp file is a translation unit. The .h file becomes part of each translation unit that #includes it (because the #include is essentially just copy/pasting the contents of the .h file into the file that #includes it).
Where I most often run into the concept of translation units is when the perennial discussion of defining global macros from the sketch comes around again. It's easy to get the idea that you can configure libraries by defining macros in the sketch, but this doesn't work for library source files because they are a separate translation unit from the sketch. This is why you actually can do this with header-only libraries (for example), but not with libraries that have a more conventional structure.
To my simpleton way of thinking, it's each "thing" that is treated as a single unit by the compiler. So, in an Arduino project, you'd have separate translation units for:
The .ino file after the Arduino IDE has done its thing
The hidden main.cpp
Each additional .cpp file that's part of the project
Source code for Arduino core features being used
Source code file for each library that's used
There could be others, I'm not that great of a tool-chain guy.
After each unit is compiled to produce individual object code files, the linker stitches them all together into an executable. That's what will puke when it finds multiple function / variable definitions caused by putting those definitions in .h files.
You might think that because foo.h has include guards, this would prevent multiple definitions of bar(). However, because foo.ino and foo.cpp are separate translation units, the include guards don't protect from this and compilation fails:
C:\Users\per\AppData\Local\Temp\arduino_build_205228\sketch\foo.ino.cpp.o (symbol from plugin): In function `bar()':
(.text+0x0): multiple definition of `bar()'
C:\Users\per\AppData\Local\Temp\arduino_build_205228\sketch\foo.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
gfvalvo:
To my simpleton way of thinking, it's each "thing" that is treated as a single unit by the compiler. So, in an Arduino project, you'd have separate translation units for:
The .ino file after the Arduino IDE has done its thing
In my programs my .ino file has #includes for all my .h files. Does that have the effect of bringing them into the .ino translation unit?
Another question ... which I have never explored. Can you have a .cpp file without a .h file. For example #include "myFile.cpp". And would that get around the translation unit problem?
Robin2:
In my programs my .ino file has #includes for all my .h files. Does that have the effect of bringing them into the .ino translation unit?
Correct. The contents of the #included files becomes part of that translation unit.
Robin2:
Can you have a .cpp file without a .h file. For example #include "myFile.cpp"
Yes. You can #include any arbitrary filename. As far as the compiler is concerned, the header file extensions don't have any special meaning. They are merely conventions we have established to convey the purpose of a file to humans. However, when it comes to Arduino libraries, the .h, .hpp, and .hh file extensions are given special treatment in that these are the supported file extensions for the primary header file name that is used for dependency resolution.
So if you try this:
#include <Servo.cpp>
You get a "No such file or directory" error.
However, if you first provide an #include directive for a supported header filename:
#include <Stepper.h>
#include <Stepper.cpp>
Then you will no longer get the "No such file or directory" error because dependency resolution for Stepper.h was successful and the library's path was added to the include search paths list, meaning you can then #include any file in the library's source folder. Of course, you will still get a compilation error from that code because of the multiple definition errors caused by the same functions being compiled in the sketch translation unit and in the Stepper.cpp translation unit.
You can also just specify the full path to the .cpp file in the #include directive, since that doesn't require any dependency resolution.
There really isn't any valid reason (maybe there is some strange hacky workaround corner case where you would do it) for #including a .cpp file, but it's interesting to study how the Arduino build system works.