include .h and .cpp in arduino

Status
Not open for further replies.

Manu

Well-known member
[SOLVED] include .h and .cpp in arduino

Hello,

I'd like to clarify something with C/C++/arduino because I don't really understand how it operate. With Arduino, many files (if not all) will have a .ino extension. It seem that arduino ide take care of many things in background.

I explain my tests and problems :

I have an arduino sketch like this :

Code:
#include <RA8875.h>

#define RA8875_CS 15
#define RA8875_RESET 16
RA8875 lcd = RA8875(RA8875_CS, RA8875_RESET);

void setup() {

  Serial.begin(115200);
  delay(100);

  my_function();

}

For clarity of code, I want to write "my_function" in another file, not the main .ino. my_function will use 'lcd'.

If I place the code in my_funtion.ino, all is fine :

Code:
int my_function() {
  lcd.fillQuad(89, 165, 123, 165, 94, 274, 60, 274, RA8875_BLUE);
  return 1;
}

But if I use my_function.h :

Code:
#ifndef my_function_h
#define my_function_h

int my_function();

#endif

and my_function.cpp :

Code:
#include "my_function.h"

int my_function() {
  lcd.fillQuad(89, 165, 123, 165, 94, 274, 60, 274, RA8875_BLUE);
  return 1;
}

I add in main.ino
Code:
#include "my_function.h"

When I compile the sketch I have an error that state :

Code:
my_function.cpp:2: error: 'lcd' was not declared in this scope
my_function.cpp:2: error: 'RA8875_BLUE' was not declared in this scope

How can I make others files (.h and .cpp) to know declarations from others files (like main.ino in this case).

thanks,
Manu
 
Last edited:
You could put them in another header file, which gets included or you can simply define it. Example if your my_function.cpp looked like:
Code:
#include <RA8875.h>
#include <my_function.h"  // probably not needed.
extern RA8875 lcd;  // probably better in a header file included in both .cpp and .ino file... 

int my_function() {
  lcd.fillQuad(89, 165, 123, 165, 94, 274, 60, 274, RA8875_BLUE);
  return 1;
}
 
Thanks KurtE,

This operate well. I only have to include SPI.h too because RA8875.h need it.

Another question :
I suppose that the librairie is only included one time in the .elf ?
#include and #define are still compiler directives ?

Last one :

You could put them in another header file, which gets included

So I can create a single header file with

Lcd.h :
Code:
#include <SPI.h>
#include <RA8875.h>
extern RA8875 lcd;

and include this Lcd.h in each .cpp file that need to access lcd ? That's it ?

Thank, you make my *first day* of the year !
 
Last edited:
So I can create a single header file with

Lcd.h :
Code:
#include <SPI.h>
#include <RA8875.h>
extern RA8875 lcd;

and include this Lcd.h in each .cpp file that need to access lcd ? That's it ?

Tested OK, thank !
 
Arduino doesn't play well with user libraries. It's 100% aimed at those with no/minimal prior coding experience and does lots of things that can really confuse programmers moving to the environment. My advice would be

- If your library is small enough, or you can tolerate it, do everything in .ino files. Arduino compiles all .ino files in a sketch folder alphabetically (i think, or at least in the order the editor shows them), I think it also handles foward delcarations for you
- If your file structure allows it, write your custom libraries in the Arduino library folder. This works, but is impractical if you're using any version control. If you want to use one library for multiple projects this really is easiest.
- If you can download visual studio, then add visual micro, you can do everything in visual studio. As long as you add the new classes using visual studio's wizard it handles all the unpleasantness for you. This is a bit of a pain to get going, and visual micro has a small cost, but I really prefer it.

In this particular instance, the function was working when everything was inside the .ino file becuase the instance of the class RA8875 was a global variable , and myFunction was a global function . Global functions operating on global varibles causes no problems. When you split code up into header and source files (which is a good practice) the compiler needs to be able to compile the .cpp files in isolation, because that's exactly what happens. When my_function.cpp compiles, anything not #included to that file doesn't exist.
The extern keyword tells the copiler that an instance of the object will exist elsewhere in the project, and to compile as though there's a global variable of that name in the hope - but NOT the guarantee - that it will find it later. It really should be avoided, if at all possible, and it's seldom needed.

For this case, you should pass lcd as an argument to the function being sure to pass by reference.

Code:
// in .cpp file
int myFunction(RA8875 &lcd) // this is your [B] function definition [/B]
{  
  lcd.fillQuad(89, 165, 123, 165, 94, 274, 60, 274, RA8875_BLUE);
  return 1;
}
// in .h file
int myFunction(RA8875 &lcd); // this is your [B] function declaration [/B] 

// in .ino file

myFunction(lcd); // this is your [B] function call [/B]

if any of the terms in bold are new to you, treat yourself to a nice google!

Ed
 
Status
Not open for further replies.
Back
Top