Access function in new file .h .cpp .ino

How to make function from new file accessible from main *.ino file?

Say I have sketch.ino like this:

#include "tempsensor.h"

void setup() {
}

void loop() {

/** would like to move to a new file **/
long a = analogRead(tempPin);
float tempC = beta / (log((1025.0 * 10 / a - 10) + beta / 298.0) - 273.0);
float tempF = 1.8 * tempC + 32.0;
/**************************************/

float tempCAv;
float tempFAv;
tempCAv = averager(tempC, 20);
tempFAv = averager(tempF, 100);

}

float averager (float inputValue, int averageAmt) {
  float averageValue = 0;
    for ( int i=0, i < averageAmt; i++) {
    averageValue = averageValue + inputValue;
    }
  averageValue = averageValue / averageAmt;
  return averageValue;
}

Here is tempsensor.h

#include <Wire.h>
#include <Arduino.h>

const byte tempPin = A0;
#define beta 4090
#define resistance 10

Once I move the temperature sensor code to a function (say void tempRead() {//code here}) and leave it in sketch.ino everything runs ok, however when I move tempRead function to a new file with extension *.h or *.cpp or *.ino I immediately get error that tempC and tempF are not defined.

How to properly link function to the main sketch?

What file is that? Did you #include it?

That was meant to represent any file with .h extension.
Yes, I did.

for instance main file is sketch.ino and tempsensor.h with all values and function. I also tried creating separate file temps.cpp or temps.h or temps.ino for a function only - included corresponding name in sketch.ino and no luck.

Do I have to include sketch.ino in tempsensor.h fine in addition to <Arduino.h>?

No the last case would be a circular reference.

Where are all your files located? Specify the location of each. Do they show up as separate tabs in the IDE?

yes.
so it should be the same folder then?

See My Post #5 Here for a brief guide to breaking up a project into multiple .h / .cpp files.

When you have this in temp.cpp:
`void tempRead() {/*code here */}'

Put this in temp.h:
`extern void tempRead();'

I have tried multiple attempts after reading @gfvalvo post #6. Added extern and still no luck. :man_shrugging:

What am I missing?

sketch.ino :arrow_down:

#include "startLCD.h"
#include "humanTime.h"


void setup() {

  lcd.init();
  lcd.backlight();

}

void loop() {

humanTime();

}

startLCD.h :arrow_down:

#ifndef STARTLCD_H
#define STARTLCD_H

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#endif

humanTime.h :arrow_down:

#ifndef HUMANTIME_H
#define HUMANTIME_H

#include "startLCD.h"
#include <Arduino.h>

extern void humanTime();

#endif

humanTime.cpp :arrow_down:

#include "humanTime.h"

void humanTime() {

  unsigned long times = millis();
  unsigned long millisec = times % 100;
  unsigned long tseconds = times / 1000;
  unsigned long seconds = tseconds % 60;
  unsigned long tminutes = tseconds / 60;
  unsigned long minutes = tminutes % 60;
  unsigned long thours = tminutes / 60;
  unsigned long hours = thours % 24;
  lcd.setCursor(0, 1);
  lcd.print("Time ON: ");
  if (thours < 10) {
    lcd.print("0");
  }
  lcd.print(thours);
  lcd.print(":");
  if (minutes < 10) {
    lcd.print("0");
  }
  lcd.print(minutes);
  lcd.print(":");
  if (seconds < 10) {
    lcd.print("0");
  }
  lcd.print(seconds);
  lcd.print(".");
  lcd.print(millisec);
}

I get these errors:

/private/var/folders/z3/q3k2ybd52j9f6157nzp8jnww0000gn/T/arduino-sketch-D4ACB24F437CE32DEFD15ED8D5CA1065/sketch/humanTime.cpp.o (symbol from plugin): In function `lcd':
(.text+0x0): multiple definition of `lcd'
/private/var/folders/z3/q3k2ybd52j9f6157nzp8jnww0000gn/T/arduino-sketch-D4ACB24F437CE32DEFD15ED8D5CA1065/sketch/dustFairy_2.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
Compilation error: exit status 1

That often happens when you define a global variable in a .h file and include the .h file in multiple places. You have:
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
in both sketch.ino and humanTime.cpp. That declaration should only be in one place.

Change 'startLCD.h' to:

#ifndef STARTLCD_H
#define STARTLCD_H

#include <LiquidCrystal_I2C.h>

extern LiquidCrystal_I2C lcd;  // set the LCD address to 0x27 for a 16 chars and 2 line display

#endif

and add this line to your main sketch:
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

1 Like

Thank you! It worked!

It also works if I create startLCD.cpp :arrow_down: and move it there:

#include "startLCD.h"

LiquidCrystal_I2C lcd(0x27, 20, 4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

are there any down sides to this method?

To putting the definition of 'lcd' in a separate .cpp file? I don't think there is a downside. You can put it in any one .ino or .cpp file.

Thank you for the reply! I am experimenting with other functions. For the reasons unknown to me yet only certain variables has to be placed in .cpp file or .ino file to work properly.

For example:
if I keep float pressureValue = 0.0; in pressureSensor.h then I get the error, however if I place it in sketch.ino or in pressureSensor.cpp directly it works ok.

And also if place void pressureSensor(){/*code here*/} only in .h file without creating .cpp - it also works ok. Is it normal practice?

Working version

sketch.ino :arrow_down:

#include "pressureSensor.h"

void setup() 
{
}

void loop() 
{
  pressureSensorRead();
}

pressureSensor.h :arrow_down:

#ifndef PRESSURESENSOR_H
#define PRESSURESENSOR_H

#include "Arduino.h"

const int pressureInput = A1;  //analog input pin for the pressure transducer
const int pressureZero = 98.6; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 300; //psi value of transducer being used

extern void pressureSensorRead();

#endif

pressureSensor.cpp :arrow_down:

#include "pressureSensor.h"
// why this guy has to live here? 
float pressureValue = 0.0; //variable to store the value coming from the pressure transducer

void pressureSensorRead(){
//pressure sensor begin
  pressureValue = analogRead(pressureInput);                                                                   //reads value from input pin and assigns to variable
  pressureValue = ((pressureValue - pressureZero) * pressuretransducermaxPSI) / (pressureMax - pressureZero);  //conversion equation to convert analog reading to psi
}

Non-Working Version

sketch.ino :arrow_down:

#include "pressureSensor.h"

void setup() 
{
}

void loop() 
{
  pressureSensorRead();
}

pressureSensor.h :arrow_down:

#ifndef PRESSURESENSOR_H
#define PRESSURESENSOR_H

#include "Arduino.h"

const int pressureInput = A1;  //analog input pin for the pressure transducer
const int pressureZero = 98.6; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 300; //psi value of transducer being used

//this line in .h file causes error. As I originally had it.
float pressureValue = 0.0; //variable to store the value coming from the pressure transducer

extern void pressureSensorRead();

#endif

pressureSensor.cpp :arrow_down:

#include "pressureSensor.h"

void pressureSensorRead(){
//pressure sensor begin
  pressureValue = analogRead(pressureInput);                                                                   //reads value from input pin and assigns to variable
  pressureValue = ((pressureValue - pressureZero) * pressuretransducermaxPSI) / (pressureMax - pressureZero);  //conversion equation to convert analog reading to psi
}

ERROR TEXT START
/private/var/folders/z3/q3k2ybd52j9f6157nzp8jnww0000gn/T/arduino-sketch-ABC400A390B2AEF0CC63234EE757BE66/sketch/sketch.ino.cpp.o (symbol from plugin): In function `setup':
(.text+0x0): multiple definition of `pressureValue'
/private/var/folders/z3/q3k2ybd52j9f6157nzp8jnww0000gn/T/arduino-sketch-ABC400A390B2AEF0CC63234EE757BE66/sketch/pressureSensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Compilation error: exit status 1
END

How to determine which one goes in .cpp?
Aren't they all defined as global variables?
Is it better to place them in .cpp file?

Yes. Like I said:

If you put the definition of a global variable or function in a .h file AND INCLUDE THE .h FILE IN MORE THAN ONE .ino/.cpp FILE then you will have the same global variable or function defined twice and get an error.

ONLY if the .h file is not included, directly or indirectly, in more than one .ino/.cpp file of your sketch.

No, because it limits the utility of the .h file.

1 Like

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