Undefined Reference to Variable error (global variable) [Timers && ISR’s]

I need to use a few global variables in order to update ADC read values whenever a triggered interrupt service routine occurs. The interrupt routine is using the standard pre-processor ISR(vector) function in the default Arduino.h library.


#include "Interrupts.h"

        // Update Global Variable (#include of Globals.h is performed in Interrupts.h)
        PIN_A0_READ = analogRead(5);
        TIFR0 |= (0 << OCF0A);

        PIN_A1_READ = analogRead(6);
        TIFR0 |= (0 << OCF0B);

        TIFR1 |= (0 << OCF1A);

    //    std::cout << "Interrupt Service Routine 1B tripped!!!" << std::endl;
        TIFR1 |= (0 << OCF1B);

        TIFR2 |= (0 << OCF2A);

        TIFR2 |= (0 << OCF2B);

In a separate header file, I have a class which instantiates a Thermistor object. The constructor accepts a few arguments. One of which, is the analog input pin to specify which physical port a Thermistor probe is attached to. The constructor checks this argument to direct the private class member adcValue to the space in memory from which it should be updated from (i.e address reference). The idea of this approach was to allow the Thermistor object to continuously update in the background after instantiation by utilizing the interrupt service routines in order to monitor/update temperatures without blocking the main program through various and frequent class-method calls.


    #define THERMISTOR_H
    #include <Arduino.h>
    #include <ArduinoSTL.h>
    #include <Globals.h>

    class Thermistor
        unsigned int * adcValue = nullptr;
        int * logicalPinAddress = nullptr;
        long * nominalResistance = nullptr;
        int * beta = nullptr;
        float * supplyVoltage = nullptr;
        float * vo = nullptr;
        float * r1 = nullptr;
        float * r2 = nullptr;
        float * temperatureCelsius = nullptr;
        float * temperatureFahrenheit = nullptr;


        Thermistor(int pinAddress, long int nominalResistance, int beta, float supplyVoltage, float R1) :
                logicalPinAddress(&pinAddress), nominalResistance(&nominalResistance), beta(&beta), supplyVoltage(&supplyVoltage), r1(&R1) {

            if (*logicalPinAddress == PIN_A0)
                this->adcValue = &PIN_A0_READ;

            if (*logicalPinAddress == PIN_A1)
                this->adcValue = &PIN_A1_READ;

            if (*logicalPinAddress == PIN_A2)
                this->adcValue = &PIN_A2_READ;;

            if (*logicalPinAddress == PIN_A3)
                this->adcValue = &PIN_A3_READ;

            if (*logicalPinAddress == PIN_A4)
                this->adcValue = &PIN_A4_READ;

            if (*logicalPinAddress == PIN_A5)
                this->adcValue = &PIN_A5_READ;


I obviously cannot declare the global variables in the Main.cpp file, because if I needed to access it from my Interrupts.h header, then the #include main.cpp would cause a circular dependency. I read up online a better approach would be to use a dedicated .h file (“Globals.h”) to hold global variables and then include them into other headers as needed.


extern unsigned int PIN_A0_READ;
   extern unsigned int PIN_A1_READ;
   extern unsigned int PIN_A2_READ;
   extern unsigned int PIN_A3_READ;
   extern unsigned int PIN_A4_READ;
   extern unsigned int PIN_A5_READ;

Upon compiling my code I get a Undefined Reference to Variable error as seen below in the console output. I am not sure what could be causing this, as my Linter/Intellisense all checks out. Are there any specific instances I would not be able to reference a Global variable by address?

Compiler Output:

   Dependency Graph
   |-- <ArduinoSTL> 1.1.0
   |-- <Arduino-MemoryFree> 0.0.0+20201021195712.sha.aed5cc5
   |-- <Interrupts>
   |   |-- <Probes>
   |   |   |-- <ArduinoSTL> 1.1.0
   |   |   |-- <Thermistor>
   |   |   |   |-- <ArduinoSTL> 1.1.0
   |   |   |   |-- <Globals>
   |   |   |-- <Arduino-MemoryFree> 0.0.0+20201021195712.sha.aed5cc5
   |-- <Probes>
   |   |-- <ArduinoSTL> 1.1.0
   |   |-- <Thermistor>
   |   |   |-- <ArduinoSTL> 1.1.0
   |   |   |-- <Globals>
   |   |-- <Arduino-MemoryFree> 0.0.0+20201021195712.sha.aed5cc5
   |-- <Thermistor>
   |   |-- <ArduinoSTL> 1.1.0
   |   |-- <Globals>
   Building in release mode
   Compiling .pio\build\uno\src\main.cpp.o
   Compiling .pio\build\uno\libcfd\Interrupts\Interrupts.cpp.o
   In file included from src\main.cpp:13:0:
   .pio\libdeps\uno\Arduino-MemoryFree/pgmStrToRAM.h:5:39: warning: '__progmem__' attribute ignored [-Wattributes]
    char *pgmStrToRAM(PROGMEM const char *theString);
   src\main.cpp: In function 'void coutLong(std::string)':
   src\main.cpp:185:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
        for (int i = 0; i < s.length(); ++i)
   In file included from C:\Users\Aspen\.platformio\packages\framework-arduino-avr\cores\arduino/Arduino.h:30:0,
                    from lib\Interrupts\Interrupts.h:8,
                    from lib\Interrupts\Interrupts.cpp:5:
   lib\Interrupts\Interrupts.cpp: In function 'void TIMER2_COMPAB_vect()':
   lib\Interrupts\Interrupts.cpp:41:5: warning: 'TIMER2_COMPAB_vect' appears to be a misspelled signal handler, missing __vector prefix [-Wmisspelled-isr]
   Archiving .pio\build\uno\libcfd\libInterrupts.a
   Indexing .pio\build\uno\libcfd\libInterrupts.a
   Linking .pio\build\uno\firmware.elf
   C:\Users\Aspen\AppData\Local\Temp\ccEIKXAw.ltrans0.ltrans.o: In function `main':
   <artificial>:(.text.startup+0x354): undefined reference to `PIN_A0_READ'
   <artificial>:(.text.startup+0x356): undefined reference to `PIN_A0_READ'
   <artificial>:(.text.startup+0x3f0): undefined reference to `PIN_A1_READ'
   <artificial>:(.text.startup+0x3f2): undefined reference to `PIN_A1_READ'
   <artificial>:(.text.startup+0x48c): undefined reference to `PIN_A2_READ'
   <artificial>:(.text.startup+0x48e): undefined reference to `PIN_A2_READ'
   <artificial>:(.text.startup+0x500): undefined reference to `PIN_A3_READ'
   <artificial>:(.text.startup+0x502): undefined reference to `PIN_A3_READ'
   <artificial>:(.text.startup+0x582): undefined reference to `PIN_A4_READ'
   <artificial>:(.text.startup+0x584): undefined reference to `PIN_A4_READ'
   <artificial>:(.text.startup+0x5fc): undefined reference to `PIN_A5_READ'
   <artificial>:(.text.startup+0x5fe): undefined reference to `PIN_A5_READ'
   collect2.exe: error: ld returned 1 exit status
   *** [.pio\build\uno\firmware.elf] Error 1

You globals.h file is not declaring any variables. Using 'extern' just tells the compiler that the named variable will be declared somewhere else (in a different compilation unit) and that the linker will resolve it. You still have to actually declare those variables some place or they do not exist.