A new PlatformIO user coding wrong, getting multiple definition & first defined here errors

Duplicate of the general mistake of not properly declaring global variables / duplicating them:

Let’s first go through the multiple definitions of ... errors.

Remember, an #include <Header.h> statement is a fancy way of saying "copy-paste the content of that file at this place.

You write in your Power.h:

float shuntvoltage_A = 0;

and then in main.cpp:

#include "Power.h"

and also in Power.cpp:

#include "Power.h"

When the GCC preprocessor expands the #include .. directives, what do you end up with? Right, a main.cpp and Power.cpp which will both have the content

float shuntvoltage_A = 0;

in them. This is a global variable declaration and there can only be one global variable of a specific name. Since both main.cpp and Power.cpp define that global variable through your include file, the compiler gives you a multiple definition of error.

The solution is that in your header file, you only declare the existence of a global variable of some name and type, but don’t define it. This is done with a statement

extern float shuntvoltage_A;

meaning "compiler, I’m declaring here an external global variable of type float with the name shutvoltage_A. The defininition of the variable has then to be done at only 1 place (e.g. in the Power.cpp), e.g. with the code

float shutvoltage_A = 0;

in one place / compilation unit, e.g. any one cpp file.

For the undefined reference to 'currentoldA' you do the same type of error but in reverse: Your Power.h declares

extern float currentoldA;

but there is no definition statement like

float currentoldA = <some initial value>; 

to be found. Thus you have declared the existence of the variable but haven’t brought in actual existence by defining it, and you get a undefined reference error.

The correct code for Power.h would be:

#ifndef POWER_H
#define POWER_H

#include <Arduino.h>
#include <Adafruit_INA219.h>

/* global objects */
extern Adafruit_INA219 ina219_A;
extern Adafruit_INA219 ina219_B;

/* global functions */
void Power();

/* global float vars */
extern float currentoldA;
extern float currentoldB;
extern float voltageold;
extern float shuntvoltage_A;
extern float busvoltage_A;
extern float current_mA_A;
extern float loadvoltage_A;
extern float power_mW_A;
extern float shuntvoltage_B;
extern float busvoltage_B;
extern float current_mA_B;
extern float loadvoltage_B;
extern float power_mW_B;
extern int Thing_Flag;
#endif

and for Power.cpp:

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

/* define / construct global objects here */
Adafruit_INA219 ina219_A;
Adafruit_INA219 ina219_B(0x41);

/* define global float vars */
float currentoldA = 0;
float currentoldB = 0;
float voltageold = 0;
float shuntvoltage_A = 0;
float busvoltage_A = 0;
float current_mA_A = 0;
float loadvoltage_A = 0;
float power_mW_A = 0;
float shuntvoltage_B = 0;
float busvoltage_B = 0;
float current_mA_B = 0;
float loadvoltage_B = 0;
float power_mW_B = 0;
int Thing_Flag = 0;

/* implement declared function */
void Power()
{
    shuntvoltage_A = 0;
    busvoltage_A = 0;
    current_mA_A = 0;
    loadvoltage_A = 0;
    power_mW_A = 0;
    shuntvoltage_B = 0;
    busvoltage_B = 0;
    current_mA_B = 0;
    loadvoltage_B = 0;
    power_mW_B = 0;
    for (int i = 0; i <= 9; i++) {
        shuntvoltage_A = shuntvoltage_A + ina219_A.getShuntVoltage_mV();
        busvoltage_A = busvoltage_A + ina219_A.getBusVoltage_V();
        current_mA_A = current_mA_A + ina219_A.getCurrent_mA();
        power_mW_A = power_mW_A + ina219_A.getPower_mW();
        loadvoltage_A = busvoltage_A + (shuntvoltage_A / 1000);
    }

    for (int i = 0; i <= 9; i++) {
        shuntvoltage_B = shuntvoltage_B + ina219_B.getShuntVoltage_mV();
        busvoltage_B = busvoltage_B + ina219_B.getBusVoltage_V();
        current_mA_B = current_mA_B + ina219_B.getCurrent_mA();
        power_mW_B = power_mW_B + ina219_B.getPower_mW();
        loadvoltage_B = busvoltage_B + (shuntvoltage_B / 1000);
    }
    shuntvoltage_A = shuntvoltage_A / 10;
    busvoltage_A = busvoltage_A / 10;
    current_mA_A = current_mA_A / 10;
    power_mW_A = power_mW_A / 10;
    loadvoltage_A = loadvoltage_A / 10;
    shuntvoltage_B = shuntvoltage_B / 10;
    busvoltage_B = busvoltage_B / 10;
    current_mA_B = current_mA_B / 10;
    power_mW_B = power_mW_B / 10;
    loadvoltage_B = loadvoltage_B / 10;
    currentoldA = currentoldA + current_mA_A;
    currentoldB = currentoldB + current_mA_B;
    voltageold = voltageold + busvoltage_A;
    if (Thing_Flag >= 60) {
        currentoldA = currentoldA / 60;
        currentoldB = currentoldB / 60;
        voltageold = voltageold / 60;
        //thingspeak1();
        Thing_Flag = 0;
    }
    Thing_Flag++;
    Serial.print("Bus Voltage_A:   ");
    Serial.print(busvoltage_A);
    Serial.println(" V");
    Serial.print("Shunt Voltage_A: ");
    Serial.print(shuntvoltage_A);
    Serial.println(" mV");
    Serial.print("Load Voltage_A:  ");
    Serial.print(loadvoltage_A);
    Serial.println(" V");
    Serial.print("Current_A:       ");
    Serial.print(current_mA_A);
    Serial.println(" mA");
    Serial.print("Power_A:         ");
    Serial.print(power_mW_A);
    Serial.println(" mW");
    Serial.println("");
    Serial.print("Bus Voltage_B:   ");
    Serial.print(busvoltage_B);
    Serial.println(" V");
    Serial.print("Shunt Voltage_B: ");
    Serial.print(shuntvoltage_B);
    Serial.println(" mV");
    Serial.print("Load Voltage_B:  ");
    Serial.print(loadvoltage_B);
    Serial.println(" V");
    Serial.print("Current_B:       ");
    Serial.print(current_mA_B);
    Serial.println(" mA");
    Serial.print("Power_B:         ");
    Serial.print(power_mW_B);
    Serial.println(" mW");
    Serial.println("");
}

main.cpp can stay the same.

1 Like