Hi all.
I am using Arduino IDE and ESP32.
My project has grown into a large number of tabs .
Some of the tabs are no longer necessary to be reviewed, and I would like them to be hidden.
(Obviously there is still a need to compile them.)
Is this possible? Is there a way to do this ?
Regards.
Hi @Francesco2017. If the tabs are .h
(header), .cpp
(C++), .c
(C), or .S
(assembly) files, you can move them to the src
subfolder of the sketchbook.
The files at that location are compiled recursively, which means you can organize them into any subfolder structures under src
you like.
If the files in the root folder have #include
directives for the moved header files, you will need to adjust the paths accordingly.
For example, if you have a sketch that looks like this:
FooSketch/
├── Bar.h
└── FooSketch.ino
and an #include
directive in FooSketch.ino
that looks like this:
#include "Bar.h"
then if you moved Bar.h
to src/BarLib/
:
FooSketch/
├── FooSketch.ino
└── src/
└── BarLib/
└── Bar.h
Then you would need to change the #include
directive to this:
#include "src/BarLib/Bar.h"
You can not use .ino
files in the src
subfolder, but you could convert them to C++ files if you want to move them.
Hi ptillisch. Thank you for your reply.
My tab are all save as .ino file.
How can I chenge them to C++, as you described
Regard.
After some investigation I found that for the OP (like me) would be very hard to to convert
'.ino' file to '.cpp' file. I wish I had known this before starting my project.
An IDE function that would hide tabs from the user could be done very easy.
Come on, Arduino include this in the next version of the IDE.
Regards
Perhaps. But it might not be as hard as you think.
Sketch preprocessing
The important thing to understand is that the language of the .ino
files of your sketch is already very close to C++ (so close in fact that many would say it is C++ already).
When you compile an Arduino sketch, a few small changes are made to the .ino
files. This is known as "sketch preprocessing". After that preprocessing the code is compiled as C++ using a standard C++ compiler, just the same as the .cpp
files are.
So the first thing is to understand what these changes are:
Concatenation
All the .ino
files are concatenated into a single file.
The order of concatenation is:
- The file with name matching the sketch folder name.
- All other files in alphabetical order.
Arduino core API declarations
An #include
directive is added to the top of the file:
#include <Arduino.h>
This #include
directive provides all the declarations of the standardized Arduino core API such as pinMode
, digitalWrite
, etc.
Function prototypes
In C++, we must declare a function before referencing it. For example, this is not valid C++:
void setup() {
foo();
}
void loop() {}
void foo() {}
The compiler doesn't know about the existence of a function named foo
when it reaches the call at line 2, so it will error. The obvious solution would be to move the function definition to the top of the code:
void foo() {}
void setup() {
foo();
}
void loop() {}
Now you have valid C++, but you might prefer to have freedom to organize your code as you like instead of having the order of the function definitions dictated by the needs of the compiler. This is where "function prototypes" become useful. The compiler doesn't need to know the full definition when it reaches the call. It only needs to know that a function with this signature will be defined eventually. We can tell it this by adding a function prototype, which is only the signature of the function:
void foo();
void setup() {
foo();
}
void loop() {}
void foo() {}
So why is it we don't need to worry about this in the .ino
files? The answer is that the Arduino sketch preprocessor automagically adds function prototypes for you.
Manual C++ conversion
From the information above, you can see that a basic conversion from .ino
to .cpp
would look something like this:
.ino
file
void foo() {
digitalWrite(2, HIGH);
bar();
}
void bar() {}
.cpp
file
#include <Arduino.h>
void bar();
void foo() {
digitalWrite(2, HIGH);
bar();
}
void bar() {}
Interfaces
If you want to call the functions defined in this file from your .ino
files or from another .cpp
file, a declaration of that function will need to be visible to the compiler before the call. This is usually done by adding a companion header (.h
) file that contains the function prototypes. Any time you want to use the functions from this .cpp
file, you simply add an #include
directive for the appropriate header file. You will already be familiar with this from using Arduino libraries in your sketches.
This header file defines the interface for the .cpp
file. Some of the functions may only be intended for use within the .cpp
file, in which case you would omit their prototypes from the header file.
Translation units
As I mentioned, the sketch preprocessor concatenates all the .ino
files into a single file. This causes all the code is in a single translation unit, which means we don't need to know about the concept.
However, each of the .cpp
files of the sketch are a separate translation unit. Each translation unit is isolated from the others within its own scope. This is actually a very useful thing when it comes to large programs, but is also something you must keep in mind when converting files that were previously part of the primary sketch translation unit to .cpp
files.
More information
I have found this to be a good introduction to C++:
https://cplusplus.com/doc/tutorial/
The information there is also useful for writing .ino
files.
Unfortunately, this tutorial is not written specifically for use in writing firmware for microcontrollers. Some of the information is not relevant for our application. I think if you keep that in mind while reading it, you will be able to identify the parts that are not applicable. I think the same problem applies to most of the general C++ programming information. I am not aware of a good tutorial for the C++ language that is targeted specifically to the application.
I would not recommend reading the tutorial end to end. Browse over it and do some study and experimentation with the parts that look interesting or useful. If you later find you need more understanding of C++, circle back to the tutorial and look for the section that contains that information.
Thank you for the extensive explanation.
I was really impressed by the word 'automagically'.
Your explanation is excellent, and will be used by many other Arduino fans.
Thank you for spending time to write this.
Now I have no choice but to attempt to convert my project to .ccp (19 tabs, currently).
Regards
You are welcome. I'm glad if I was able to be of assistance.
Please let us know if you have any questions or problems. This forum is fortunate to have many helpers who are very knowledgeable about C++ and programming in general.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.