Problème de déclaration de fonctions

Bonjour,
je ne comprend pas bien comment déclarer mes fonctions avec plusieurs fichiers.
J'ai toujours des problèmes de compilation.
Que dois je faire pour que cela fonctionne ?

test.ino :

#include "test.h"
//#include "functions.cpp"

void setup()
{
  
}

void loop()
{
  function_A();
}

functions.cpp :

//#include "test.h"

void function_A()
{
  int x = 0;

  function_B(x);
}


void function_B(int y)
{
  
}

test.h :

#include "functions.cpp"

void function_A();
void function_B(int y);

ne pas mettre #include "functions.cpp" dans test.h

l'idéal serait d'ailleurs de l'appeler functions.h
vous pouvez inclure functions.h dans functions.cpp et dans test.ino

donc

test.ino importe functions.h
functions.cpp importe functions.h et implémente le code des fonctions. L'import du header functions.h est important pour que si vous appelez dans la première fonction du fichier des fonctions qui sont plus loin alors il connait leur existence et signature et peut vérifier les paramètres

et comme vous l'avez bien noté, tout est au niveau de votre projet et ce ne sont pas des imports système, on utilise bien

#include [color=green]"[/color]functions.h[color=green]"[/color] et pas #include [color=red]<[/color]functions.h[color=red]>[/color]

J'ai supprimé #include "functions.cpp" dans test.h
J'ai inclus functions.h dans functions.cpp
Et, renomé test.h en functions.h ainsi que le nom de fichier de l'include.
Mais rien ni fait j'ai toujours 2 erreurs à la compilation:

" In function 'void function_A()': "

" 'function_B' was not declared in this scope "

Je vous joins un exemple similaire à ce que vous décrivez et qui compile sans pb sur mon ordinateur.


[color=blue][b]test.ino[/b][/color]
#include "functions.h"

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  function_A();
  Serial.println("");
}

[color=blue][b]functions.cpp[/b][/color]
#include "functions.h"
#include "Arduino.h" // uniquement parce que j'utilise Serial.print


void function_A()
{
  for (int x = 0; x < 10; x++) function_B(x);
}


void function_B(int y)
{
  Serial.print(y);
  Serial.print("|");

}

[color=blue][b]functions.h[/b][/color]
/*
  functions.h - this is a demo.
*/

#ifndef functions_h  // evite les inclusions récursives
#define functions_h

void function_A();
void function_B(int y);

#endif

Il faut bien sûr vous assurer que les 3 fichiers soient bien dans le même répertoire qui doit s'appeler test

Et bien déclarés/ajoutés à votre projet pour que les instructions de compilation prennent en compte ces fichiers ==> dans l'IDE les 3 tabs doivent être visibles

ça fonctionne.
Cela va me permettre de terminer plusieurs projets.
Merci. Bonne journée à vous.

super!

vous avez trouvé ce que vous faisiez de bizarre?

Non, pas vraiment, cela fonctionne parfaitement dans l'example, mais pas vraiment dans mon projet.
J'ai une série d'erreurs pointant sur mon fichier .cpp

In file included from C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:1:0:
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.h:4:8: error: 'uint8_t' does not name a type
extern uint8_t SmallFont[];
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.h:20:1: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
};
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.h:20:1: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.h:20:1: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.h:20:1: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp: In function 'void Settings()':
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:7:3: error: 'boolean' was not declared in this scope
boolean quitMode = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:7:11: error: expected ';' before 'quitMode'
boolean quitMode = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:8:13: error: 'selectedMenu' was not declared in this scope
PrintMenu(selectedMenu);
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:10:12: error: 'quitMode' was not declared in this scope
while (quitMode==false)
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:12:27: error: 'Buttons' was not declared in this scope
int buttons = Buttons();
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:36:26: error: 'SetTotalTime' was not declared in this scope
SetTotalTime();
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:44:13: error: 'delay' was not declared in this scope
delay(50);
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp: In function 'void PrintMenu(int)':
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:52:3: error: 'myOLED' was not declared in this scope
myOLED.clrScr();
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:53:18: error: 'SmallFont' was not declared in this scope
myOLED.setFont(SmallFont);
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:61:26: error: 'CENTER' was not declared in this scope
myOLED.print (ptr, CENTER, (x * vertSpace)+2);
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:66:25: error: 'CENTER' was not declared in this scope
myOLED.print(ptr, CENTER, (x * vertSpace)+2);
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp: In function 'void SetDateTime()':
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:74:3: error: 'boolean' was not declared in this scope
boolean exitMenu = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:74:11: error: expected ';' before 'exitMenu'
boolean exitMenu = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:76:10: error: 'exitMenu' was not declared in this scope
while (exitMenu==false)
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp: In function 'void SetTimeON()':
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:84:3: error: 'boolean' was not declared in this scope
boolean exitMenu = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:84:11: error: expected ';' before 'exitMenu'
boolean exitMenu = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:86:10: error: 'exitMenu' was not declared in this scope
while (exitMenu==false)
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp: In function 'void InfoScreen()':
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:94:3: error: 'boolean' was not declared in this scope
boolean exitMenu = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:94:11: error: expected ';' before 'exitMenu'
boolean exitMenu = false;
^
C:\Users\theda\AppData\Local\Temp\buildc7147de8a2ebc35985cb35ed435f8800.tmp\sketch\menu.cpp:96:10: error: 'exitMenu' was not declared in this scope
while (exitMenu==false)
^
Utilisation de la bibliothèque OLED_I2C prise dans le dossier : C:\Users\theda\OneDrive\Documents\Arduino\libraries\OLED_I2C (legacy)
Utilisation de la bibliothèque DS3231 prise dans le dossier : C:\Users\theda\OneDrive\Documents\Arduino\libraries\DS3231 (legacy)
exit status 1
'exitMenu' was not declared in this scope

J'ai réussi à résumé mon projet tout en gardant les mêmes erreurs de compilation.

test2.ino

#include <OLED_I2C.h>
#include <DS3231.h>
#include "menu.h"


const int button1Pin = 16;
const int button2Pin = 17;
const int button3Pin = 18;
    
// Declare which fonts we will be using
//extern uint8_t Sinclair_M[];
//extern uint8_t TinyFont[];
//extern uint8_t SmallFont[];

// Init the OLED and DS3231 using the hardware I2C pins
OLED myOLED(SDA, SCL);
DS3231 rtc(SDA, SCL);

// Init a Time
Time  t;

// Init variable
int oldsec=0;
int selectedMenu = 7;


//***START OF SETUP***
void setup()
{
  pinMode(button1Pin, INPUT);
  pinMode(button2Pin, INPUT);
  pinMode(button3Pin, INPUT);
  
  //*RTC*
  rtc.begin();

  //*OLED setup*
  myOLED.begin();
  myOLED.setFont(Sinclair_M);
  myOLED.setBrightness(0);  
  //myOLED.invert(true);

  //*Serial setup*
//  Serial.begin(115200);

  t = rtc.getTime();
}
//***END OF SETUP***

//***START OF LOOP***
void loop()
{
  int prevSec;

  PrintMenu(selectedMenu);
  myOLED.update();

  prevSec = t.sec;
  while (t.sec == prevSec)
  {
    int butStat=Buttons();
    if (butStat == 2) Settings();
    else if (butStat != 0) InfoScreen();
    delay(50);
    t = rtc.getTime();
  }
}
//***END OF LOOP***

int Buttons()
{
  int butStatus=0;
  if (digitalRead(button1Pin) == HIGH) butStatus = 1;
  else if (digitalRead(button2Pin) == HIGH) butStatus = 2;
  else if (digitalRead(button3Pin) == HIGH) butStatus = 3;
  return butStatus;
}

menu.cpp

#include "menu.h"
//#include "Arduino.h" 
//#include "OLED_I2C.h"

void Settings()
{
  boolean quitMode = false;
  PrintMenu(selectedMenu);

    while (quitMode==false)
  {
    int buttons = Buttons();
    if (buttons != 0)
    {
      if (buttons == 1)
      {
        if (selectedMenu == 1) selectedMenu = settingTextNumber;
        else selectedMenu--; 
      }
      else if (buttons == 3)
      {
        if (selectedMenu == settingTextNumber) selectedMenu=1;
        else selectedMenu++;
      }
      else
      {
        switch (selectedMenu)
        {
          case 1:
            SetDateTime();
            break;
          case 2:
            SetTimeON();
            break;
          case 3:
            SetTotalTime();
            break;         
          case 4:
            quitMode = true;
            break; 
        }
      }
    }
    delay(50);
    quitMode = true;
  }
}

void PrintMenu(int menuState)
{
  int vertSpace = 9;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);

  for (int x = 0; x <= settingTextNumber; x++)
  {
    char * ptr = (char *) settingText[x];
    if (menuState == x+1)
    {
      myOLED.invertText(true);
      myOLED.print (ptr, CENTER, (x * vertSpace)+2);
      myOLED.invertText(false);
    }
    else
    {
      myOLED.print(ptr, CENTER, (x * vertSpace)+2);
    }
  }
  myOLED.update();
}

void SetDateTime()
{
  boolean exitMenu = false;

  while (exitMenu==false)
  {
    exitMenu = true;
  }
}

void SetTimeON()
{
  boolean exitMenu = false;

  while (exitMenu==false)
  {
    exitMenu = true;
  }
}

void InfoScreen()
{
  boolean exitMenu = false;

  while (exitMenu==false)
  {
    exitMenu = true;
  }  
}

menu.h

#ifndef menu_h
#define menu_h

extern uint8_t SmallFont[];

void Settings();
void PrintMenu(int menuState);
void SetDateTime();
void SetTimeON();
void InfoScreen();


const int settingTextNumber = 4;
char * const settingText [settingTextNumber] = 
{
         "Set date & time", 
         "Set time to turn ON", 
         "Set light time",  
         " Exit settings "
};

#endif

Liens library:
OLED_I2C Rinky-Dink Electronics
DS3231 Rinky-Dink Electronics

Erreur:
exit status 1
'exitMenu' was not declared in this scope

Vous avez des fichiers interdépendants. par exemple vous déclarez dans test.ino

int selectedMenu = 7;

mais vous l'utilisez dans menu.cpp

il faut vraiment que vous ayez des unités autonomes. par exemple en mettant toutes les variables globales afférentes au menu dans menu.h