# Hierachical header structure

**URL:** <https://forum.arduino.cc/t/hierachical-header-structure/892606>\
**Category:** Programming\
**Created:** [August 5, 2021, 8:21am UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606 "2021-08-05T08:21:33Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![sut3](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@sut3](https://forum.arduino.cc/u/sut3)\
**Post date:** [August 5, 2021, 8:21am UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/1 "2021-08-05T08:21:33Z")

</div>

Hi,

I have an bigger project with my arduino with an e-Paper display and and a keyboard an something like that and would like to get more structure and cleanness into the project. Therefore I would like to outsource some methods into header and cpp-files like:

**main.ino**

```cpp
#include <master.h>

void setup()
{
// ...
}

void loop()
{
loop_actions();
}

```

**master.h**

```cpp
#ifndef MASTER_H
#define MASTER_H

#include "keyboard.h"
#include "display.h"

#define MAX_MESSAGE_LENGTH 200

void loop_actions(void);

#endif

```

**master.cpp**

```cpp
#include "master.h"

void loop_actions(void) { 
  // Commands done periodically in main-loop
  }

```

**keyboard.h**

```cpp
#ifndef KEYBOARD_H
#define KEYBOARD_H

#include <BBQ10Keyboard.h>

#define KB_INTERRUPT_PIN 13 // Interrupt pin
// SDA = 21
// SCL = 22

char* read_keys (void);

#endif

```

**keyboard.cpp**

```cpp
#include "keyboard.h"

char* read_keys (void) { 
  // read from keyboard
}

```

**display.h**  
**display.cpp**  
_Similar to keyboard_

Is that possible? I tried it with the code-pieces I posted, but IDE says there are multiple calls for every externel/library include.

Could you please help me

Thanks in advance  
sut3

---

<div class="post-metadata">

**Author:** ![J-M-L](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/j-m-l/32/766245_2.png) [@J-M-L](https://forum.arduino.cc/u/J-M-L)\
**Post date:** [August 5, 2021, 12:20pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/2 "2021-08-05T12:20:32Z")

</div>

post a minimal zip with all the files necessary to demonstrate the behavior you see

---

<div class="post-metadata">

**Author:** ![hammy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/hammy/32/238813_2.png) [@hammy](https://forum.arduino.cc/u/hammy)\
**Post date:** [August 5, 2021, 9:25pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/3 "2021-08-05T21:25:33Z")

</div>

How about just using tabs ?

---

<div class="post-metadata">

**Author:** ![J-M-L](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/j-m-l/32/766245_2.png) [@J-M-L](https://forum.arduino.cc/u/J-M-L)\
**Post date:** [August 6, 2021, 4:51am UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/4 "2021-08-06T04:51:36Z")

</div>

You can have tabs with .ino or .h or .cpp or .hpp etc.

If you use .ino the IDE will (likely) merge everything into a large file before attempting to compile, so it might work - but is far from standard C++

---

<div class="post-metadata">

**Author:** ![chrisknightley](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/chrisknightley/32/637257_2.png) [@chrisknightley](https://forum.arduino.cc/u/chrisknightley)\
**Post date:** [August 6, 2021, 5:05am UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/5 "2021-08-06T05:05:38Z")

</div>

Just change `#include <master.h>` to `#include "master.h"` and at least I've successfully compiled with the file structure you posted.

**EDIT:**  
If you want to use Arduino standard functions etc., you need to add `#include <Arduino.h>` to each header file.

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [August 6, 2021, 2:33pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/6 "2021-08-06T14:33:39Z")

</div>

In main.ino I had to change `#include <master.h>` to `#include "master.h"` so the tab would be used.

I had to comment out `#include <BBQ10Keyboard.h>` and `#include "display.h"` because you didn't include those files.

There was a warning in `keyboard.cpp` because `char * read_keys (void)` didn't return a value.

After those changes it compiled without error.

---

<div class="post-metadata">

**Author:** ![sut3](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@sut3](https://forum.arduino.cc/u/sut3)\
**Post date:** [August 8, 2021, 2:56pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/7 "2021-08-08T14:56:58Z")

</div>

Thank you very much (also @johnwasser ) - I will try it tomorrow and will report my sucess or not 😉

sut3

---

<div class="post-metadata">

**Author:** ![sut3](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@sut3](https://forum.arduino.cc/u/sut3)\
**Post date:** [August 9, 2021, 4:39pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/8 "2021-08-09T16:39:50Z")

</div>

So I tried it today an get

This is the new/real code:

```cpp
sketch\src.ino.cpp.o:(.bss.display+0x0): multiple definition of `display'
sketch\master.cpp.o:(.bss.display+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board WiFi LoRa 32(V2).

```

_I changed display.h to displayown.h, because I thought meybe there is a multiple use of the name..._

**src.ino**

```cpp
#include "master.h"

BBQ10Keyboard keyboard;
volatile bool dataReady = false;
char EPD_preview_buffer[MAX_MESSAGE_LENGTH];
int EPD_preview_buffer_pos = 0;
int EPD_preview_cursor_pos = 0;

char fifo[FIFO_SIZE];
int fifo_in_pos = 0;
int fifo_out_pos = 0;
int fifo_elements = 0;

int rowUpperEdge[] = {10, 26, 42, 58, 74, 90, 106, 122}; // Cursorposition for text with 1px
int rowLowerEdge[] = {11, 27, 43, 59, 75, 91, 107, 123}; // Cursorposition for text with 1px
int maxColChars = 21;
int mailboxGUILine = 0;
int initialized = 0;

String messagesLines[MAX_MESSAGES];
int messagesLinesCount = 7;

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("setup");
  delay(100);

  display.init(115200);

  display.firstPage();
  do
  { 
    display.fillScreen(GxEPD_WHITE); // set the background to white (fill the buffer with value for white)
    display.fillRect(0, 79, maxColChars*11 + 7, 1, GxEPD_BLACK); // Trennstrich horizontal
    display.fillRect(maxColChars*11 + 7, 0, 1, display.height(), GxEPD_BLACK); // Trennstrich vertikal
  }
  while (display.nextPage());
  

  delay(50);
  Serial.println("setup display end");
}

void loop()
{
// ...
}

```

**master.h**

```cpp
#ifndef MASTER_H
#define MASTER_H

#define MAX_MESSAGE_LENGTH 200
#define FIFO_SIZE 20

#include <Arduino.h>
#include "keyboard.h"
#include "displayown.h"

void printFIFO (char fifo[]);
void printArray (char a[], int s);

#endif

```

**master.cpp**

```cpp
#include "master.h"

void printFIFO (char fifo[]) {
  for (int i = 0; i < FIFO_SIZE; i++) {
    Serial.printf("%c, ", fifo[i]);  
  }  
  Serial.println("");
}

void printArray (char a[], int s) {
  for (int i = 0; i < s; i++) {
    Serial.printf("%c, ", a[i]);  
  }  
  Serial.println("");
}

```

**displayown.h**

```cpp
// Code from ZinggJM/GxEPD2^1.3.6
#ifndef DISPLAYOWN_H
#define DISPLAYOWN_H

#include <Arduino.h>
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include "GxEPD2_display_selection_new_style.h"

#include "bitmaps/Bitmaps128x296.h" // 2.9" b/w

#define ENABLE_GxEPD2_GFX 0
#define ENABLE_GxEPD2_GFX 0
#define MAX_MESSAGES 10
#define MAILBOXGUI_LINES 5

#define MAX_EPD_PREVIEW_LINES 3
#define MAX_EPD_PREVIEW_ROWS 21

#define FIFO_SIZE 20
#define MAX_MESSAGE_LENGTH 200

#endif

```

**keyboard.h**

```cpp
#ifndef KEYBOARD_H
#define KEYBOARD_H

#include <Arduino.h>
#include <BBQ10Keyboard.h>

#define KB_INTERRUPT_PIN 13 // Interrupt pin
// SDA = 21
// SCL = 22

#endif

```

I have no idea why this is not working...

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 9, 2021, 6:07pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/9 "2021-08-09T18:07:22Z")

</div>

> [@J-M-L](#):
>
> post a minimal zip with all the files necessary to demonstrate the behavior you see

It would be helpful if you actually complied with this request from Reply #2. Nobody can test-compile your code with all those #include statements when they don't have the actual files you're trying to #include. In other words, post an [MRE](https://stackoverflow.com/help/minimal-reproducible-example)!!!

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [August 9, 2021, 9:11pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/10 "2021-08-09T21:11:02Z")

</div>

> [@sut3](#):
>
> ```arduino
> sketch\src.ino.cpp.o:(.bss.display+0x0): multiple definition of `display'
> sketch\master.cpp.o:(.bss.display+0x0): first defined here
> 
> ```

It looks like one of the files included by 'displayown.h' defines the global variable 'display'. My guess is "GxEPD2\_display\_selection\_new\_style.h" (which you did not provide). Since 'displayown.h' is included by 'master.h' and 'master.h' is included in both 'src.ino' and 'master.cpp' the global variable 'display' is defined twice.

Maybe you can change the global definition in the .h file into an extern reference and move the definition into master.cpp. That way you only have one definition of the variable but can use it anywhere 'master.h' is included.

---

<div class="post-metadata">

**Author:** ![sut3](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@sut3](https://forum.arduino.cc/u/sut3)\
**Post date:** [August 10, 2021, 1:11pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/11 "2021-08-10T13:11:40Z")

</div>

[src.zip](https://forum.arduino.cc/uploads/short-url/k3QjAEr6keuH0Sdk6cl9gFtvl0Z.zip) (2,4 MB)

Here is my structure 🙂

```cpp
[platformio]
default_envs = heltec_wifi_lora_32_V2

[env]
lib_deps = 
	adafruit/Adafruit GFX Library @ ^1.10.10
	adafruit/Adafruit BusIO @ ^1.8.2
	heltecautomation/ESP32_LoRaWAN @ ^2.1.1
	arturo182/BBQ10Keyboard @ ^1.1.0
	zinggjm/GxEPD2 @ ^1.3.6
upload_speed = 115200
monitor_speed = 115200

[env:heltec_wifi_lora_32_V2]
platform = espressif32
board = heltec_wifi_lora_3

```

---

<div class="post-metadata">

**Author:** ![sut3](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@sut3](https://forum.arduino.cc/u/sut3)\
**Post date:** [August 10, 2021, 1:14pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/12 "2021-08-10T13:14:28Z")

</div>

Yes. That is the problem. If I include every own library in main.ino everything works fine.

> [@johnwasser](#):
>
> Maybe you can change the global definition in the .h file into an extern reference and move the definition into master.cpp.

WHat do you mean? I don'T exectly understand how to change the global definition in the .h file into an extern reference.

Thank you  
sut3

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [August 10, 2021, 1:18pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/13 "2021-08-10T13:18:30Z")

</div>

> [@gfvalvo](#):
>
> It would be helpful if you actually complied with this request from Reply #2. Nobody can test-compile your code with all those #include statements when they don't have the actual files you're trying to #include. In other words, post an [MRE](https://stackoverflow.com/help/minimal-reproducible-example)!!!

Is there any reason you're unwilling to post an [MRE](https://stackoverflow.com/help/minimal-reproducible-example) as requested?

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [August 10, 2021, 1:38pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/14 "2021-08-10T13:38:34Z")

</div>

> [@sut3](#):
>
> I don'T exectly understand how to change the global definition in the .h file into an extern reference.

Change the definition:  
`GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ 2, /*DC=*/ 12, /*RST=*/ 17, /*BUSY=*/ 39)); // Heltec LORA`  
to something like this declaration:  
`extern GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display; // Heltec LORA`  
and put the declaration:  
`GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ 2, /*DC=*/ 12, /*RST=*/ 17, /*BUSY=*/ 39)); // Heltec LORA`  
into master.cpp.

Maybe you could use '#ifdef' to put both in the .h file:

```arduino
#ifdef DEFINE_display_HERE
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ 2, /*DC=*/ 12, /*RST=*/ 17, /*BUSY=*/ 39)); // Heltec LORA
#else
extern GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display; // Heltec LORA
#endif

```

Then, in master.cpp put:  
`#define DEFINE_display_HERE`  
just above:  
`#include "GxEPD2_display_selection_new_style.h`

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [December 8, 2021, 1:38pm UTC](https://forum.arduino.cc/t/hierachical-header-structure/892606/15 "2021-12-08T13:38:51Z")

</div>

Closed on December 8, 2021, 1:38pm UTC

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