Hiding Multiple Tabs

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:

  1. The file with name matching the sketch folder name.
  2. 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.

1 Like

Thank you for the extensive explanation.
I was really impressed by the word 'automagically'. :grinning:

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

1 Like

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.

1 Like

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