Errors when importing IRremote.hpp in a external file

Hey, i am working on a project using RFID and IR transmitter/ receiver i have some problems when trying to include IRremote.hpp in a external file, my project was in just one file and it worked good but now i am trying to separate the functionality of of the project in different files so it be more clean and easy to modify but i get a lot of errors when trying to include IRremote library in the external file, any help is appreciated.Sry if there any mistakes regarding this post, first time when i ask a question here. This is my code :

//remote.ino
#include "IRHandler.h"
#include "RFIDHandler.h"
#include "Config.h"
#include <stdint.h>

const unsigned long IR_CODE = 0xFFA25D31; 
const int IR_BITS = 32; // Lungimea în biți
unsigned long lastRFIDCheck = 0;
const unsigned long RFIDCheckInterval = 200; 

byte data1[14] = {"Televizor N21"};  //The first data that needs to be written to the tag.
byte readbackblock[18]; //Array for reading out a block.

void setup() {
  pinMode(BUTTON_PIN, INPUT);
  Serial.begin(115200);
  initializeRFID();
  initializeIR();
}

void loop() {
  unsigned long currentMillis = millis();
 if (currentMillis - lastRFIDCheck >= RFIDCheckInterval) {
    lastRFIDCheck = currentMillis;
    checkRFID();
  }
}
//IRHandler.h
#ifndef IRHANDLER_H
#define IRHANDLER_H
#include <IRremote.hpp>

extern IRrecv irrecv;
extern IRsend irsend;
void initializeIR();
void receiver();
void transmitter(const unsigned long IR_CODE, const int IR_BITS);
uint32_t mirror_u32(uint32_t input);

#endif
//IRHandler.cpp
#include "IRHandler.h"
#include "Config.h"

IRrecv irrecv(IR_RECEIVE_PIN);
IRsend irsend(IR_TRANSMITER_PIN);


void initializeIR() {
    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
    Serial.println("IR initialized!");
}

void transmitter(const unsigned long IR_CODE, const int IR_BITS)
{
    if (digitalRead(BUTTON_PIN) == HIGH) {
    // Trimite semnalul IR
    Serial.println("Sending IR signal...");
    irsend.sendNEC(IR_CODE, IR_BITS);
    delay(1000);
    }
}

void receiver()
{
    if (IrReceiver.decode())
    {
        digitalWrite(LED, HIGH);

        Serial.print("Value received: ");
        Serial.println(mirror_u32(IrReceiver.decodedIRData.decodedRawData), HEX); 
        Serial.print("Protocol: ");
        Serial.println(IrReceiver.decodedIRData.protocol);
        irrecv.resume();                                 
    }
    else
    {
        delay(100);
        digitalWrite(LED, LOW);
    }
}

// funtion to mirror data
uint32_t mirror_u32(uint32_t input)
{
    uint32_t returnval = 0;
    for (int i = 0; i < 32; i++)
    {
        int bit = input & 0x01;
        returnval <<= 1;
        returnval += bit;
        input >>= 1;
    }
    return returnval;
}
RFIDHandler.h
#ifndef RFIDHANDLER_H
#define RFIDHANDLER_H
#include <MFRC522.h>

extern MFRC522 mfrc522;
extern MFRC522::MIFARE_Key key;
void initializeRFID();
void checkRFID();
int writeBlock(int blockNumber, byte arrayAddress[]);
int readBlock(int blockNumber, byte arrayAddress[]);
void get_uid();

#endif
RFIDHandler.cpp
#include "RFIDHandler.h"
#include "Config.h"
#include <SPI.h>

MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

void initializeRFID() {
    SPI.begin();
    mfrc522.PCD_Init();
    Serial.println("RFID initialized!");
    for (byte i = 0; i < 6; i++) {
        key.keyByte[i] = 0xFF;
    }
}

void checkRFID()
{
    if (!mfrc522.PICC_IsNewCardPresent())
    {
        return;
    }

    if (!mfrc522.PICC_ReadCardSerial())
    {
        return;
    }

    Serial.println("Card detected!");
    get_uid();
    mfrc522.PICC_HaltA(); 
}

int writeBlock(int blockNumber, byte arrayAddress[])
{
    // check if the block number corresponds to data block or triler block, rtuen with error if it's trailer block.
    int largestModulo4Number = blockNumber / 4 * 4;
    int trailerBlock = largestModulo4Number + 3; // determine trailer block for the sector
    if (blockNumber > 2 && (blockNumber + 1) % 4 == 0)
    {
        Serial.print(blockNumber);
        Serial.println(" is a trailer block: Error");
        return 2;
    }
    // authentication
    byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK)
    {
        Serial.print("Authentication failed: ");
        Serial.println(mfrc522.GetStatusCodeName(status));
        return 3; // return "3" as error message
    }
    // writing data to the block
    status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);
    // status = mfrc522.MIFARE_Write(9, value1Block, 16);
    if (status != MFRC522::STATUS_OK)
    {
        Serial.print("Data write failed: ");
        Serial.println(mfrc522.GetStatusCodeName(status));
        return 4; // return "4" as error message
    }
    Serial.print("Data written to block ");
    Serial.println(blockNumber);
}

int readBlock(int blockNumber, byte arrayAddress[])
{
    int largestModulo4Number = blockNumber / 4 * 4;
    int trailerBlock = largestModulo4Number + 3; // determine trailer block for the sector
    // authentication of the desired block for access
    byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK)
    {
        Serial.print("Authentication failed : ");
        Serial.println(mfrc522.GetStatusCodeName(status));
        return 3; // return "3" as error message
    }
    // reading data from the block
    byte buffersize = 18;
    status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize); //&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number
    if (status != MFRC522::STATUS_OK)
    {
        Serial.print("Data read failed: ");
        Serial.println(mfrc522.GetStatusCodeName(status));
        return 4; // return "4" as error message
    }
    Serial.println("Data read successfully");
}

void get_uid()
{

    Serial.print("Card UID:");
    for (byte i = 0; i < mfrc522.uid.size; i++)
    {
        Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(mfrc522.uid.uidByte[i], HEX);
    }
    Serial.println();
    mfrc522.PICC_HaltA();
}
//Config.h
#ifndef CONFIG_H
#define CONFIG_H
#define LED 2
#define BUTTON_PIN 7
#define IR_TRANSMITER_PIN 4
#define IR_RECEIVE_PIN 8
#define RST_PIN 9
#define SS_PIN 10
#endif

And this are the some of the errors there a many more like this ones, cant understand what is the problem because i dont have any FeedbackLEDControl:

\sketch\IRHandler.cpp.o (symbol from plugin):(.text+0x0): first defined here
\sketch\remote.ino.cpp.o (symbol from plugin): In function `FeedbackLEDControl':
(.text+0x0): multiple definition of `aggregateArrayCounts(unsigned char*, unsigned char, unsigned char*, unsigned char*)'
\sketch\IRHandler.cpp.o (symbol from plugin):(.text+0x0): first defined here
\sketch\remote.ino.cpp.o (symbol from plugin): In function `FeedbackLEDControl':
(.text+0x0): multiple definition of `IRrecv::decodeDistanceWidth()'
\sketch\IRHandler.cpp.o (symbol from plugin):(.text+0x0): first defined here
\sketch\remote.ino.cpp.o (symbol from plugin): In function `FeedbackLEDControl':
(.text+0x0): multiple definition of `IRrecv::decode()'
\sketch\IRHandler.cpp.o (symbol from plugin):(.text+0x0): first defined here
\sketch\remote.ino.cpp.o (symbol from plugin): In function `FeedbackLEDControl':
(.text+0x0): multiple definition of `IRrecv::read()'
\sketch\IRHandler.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status```

This error message is indicating that there are multiple definitions of certain functions and variables in your code. This is likely due to the fact that you are including the IRHandler.cpp file in your remote.ino file, which is causing the functions and variables to be defined twice.

The error message specifically mentions the following functions and variables:

  • aggregateArrayCounts
  • IRrecv::decodeDistanceWidth
  • IRrecv::decode
  • IRrecv::read

These functions and variables are likely defined in the IRHandler.cpp file, and are being included in the remote.ino file through the #include "IRHandler.h" directive.

To fix this error, you can try the following:

  1. Remove the #include "IRHandler.cpp" directive from your remote.ino file. This will prevent the functions and variables from being defined twice.
  2. Make sure that the IRHandler.cpp file is not being included in any other files in your project.
  3. If you need to use the functions and variables from the IRHandler.cpp file in your remote.ino file, consider using a header file (IRHandler.h) to declare the functions and variables, and then include the IRHandler.cpp file in your project's build process.

Alternatively, you can also try to use the extern keyword to declare the functions and variables in the IRHandler.cpp file, and then define them in the IRHandler.cpp file. This will allow you to use the functions and variables in your remote.ino file without causing multiple definition errors.

For example:

// IRHandler.h
extern void IRrecv::decode();
extern void IRrecv::read();

// IRHandler.cpp
void IRrecv::decode() {
  // implementation
}

void IRrecv::read() {
  // implementation
}

By using the extern keyword, you are declaring the functions and variables in the IRHandler.h file, and then defining them in the IRHandler.cpp file. This will allow you to use the functions and variables in your remote.ino file without causing multiple definition errors.

I dont include IRHandler.cpp in remote.ino and i am already using a header IRHandler.h also this are not the only errors there are like 100 of them all related with FeedbackLEDControl

In that case, the issue is likely due to the fact that the FeedbackLEDControl function is being defined in multiple places.

Since you're already using a header file (IRHandler.h) and not including the IRHandler.cpp file in remote.ino, the issue is likely due to the fact that the FeedbackLEDControl function is being defined in both IRHandler.cpp and remote.ino.

To fix this, you can try the following:

  1. Move the definition of the FeedbackLEDControl function to the IRHandler.cpp file. This will ensure that the function is only defined once.
  2. Remove any references to the FeedbackLEDControl function from remote.ino. Instead, call the function from IRHandler.cpp using the header file (IRHandler.h).

If you're still getting errors, it's possible that there are other functions or variables that are being defined in multiple places. You can try to identify these functions and variables by looking at the error messages.

Here are some steps you can follow to identify the issues:

  1. Look at the error messages and identify the functions or variables that are being defined in multiple places.
  2. Check the IRHandler.cpp and remote.ino files to see where these functions or variables are being defined.
  3. Move the definitions of these functions or variables to a single file (e.g. IRHandler.cpp) and remove any references to them from the other file (e.g. remote.ino).
  4. Use the header file (IRHandler.h) to declare the functions or variables that need to be accessed from multiple files.

By following these steps, you should be able to identify and fix the issues that are causing the multiple definition errors.

I didnt define any FeedbackLEDControl. Pls answer only if you can help if i wanted AI generated answer i would used ChatGPT, well i did use it and it didnt help me.

just trying to help I don't have all the answers maybe if you include more details and all the error codes

@Always_be_kind if you are going to use AI generated content when providing help here, it must be done responsibly.

Just as with any other information you find on the Internet, you must carefully evaluate AI-generated content for accuracy, relevance, and appropriateness within the context. Copy/pasting without giving any thought to the information is irresponsible, regardless of the source of that information. If you are not able to make such an evaluation, then please don't share the content here on the forum.

Thanks in advance for your cooperation.

3 Likes

the error codes do suggest that there are multiple definitions

Yes, but you wrote this:

If you look at the code from remote.ino that was posted by @bot_25, you will see that it doesn't contain any such directive.

So if you got that response from an AI, it is clear that you didn't do any verification of its accuracy. It is fine to use AI-generated content to help people here on the forum, but only if you make the effort to carefully verify that it is accurate before posting.

i guess not then?

"IRHandler.h" != "IRHandler.cpp"

i will be sure to properly read the code rather than just skim too fast

i only read the errors

Thanks. Although we should strive to approach perfection, all humans make mistakes. However, it is easy to get lazy when using AI-generated content and simply copy and paste what the machine wrote. Unfortunately, although the AI has a lot of information, it also frequently makes mistakes. So we want to make sure that a knowledgeable human checks over what the AI wrote before using it here on the forum to provide support.

1 Like

proper information is good to have on both sides it seems to me now that none of the errors relates to the code provided

unless its in this one which was not included seems to be the only one i cant see on here

unless

is in

then id say that the errors don't make any sense

This is not how it works. .cpp files aren't "included". They are all compiled separately and then linked. Variables and functions defined inside them are not visible from the other files.

Only what is in the .h or .hpp can be seen from the .ino file or any other place.

Remove these lines from IRHandler.h:

#include <IRremote.hpp>
extern IRrecv irrecv;
extern IRsend irsend;

Add this line to IRHandler.h:

#include <Arduino.h>

Add this line to IRHandler.cpp:

#include <IRremote.hpp>

It also looks like your code is mixing techniques from older and newer versions of IRremote because there are deprecated warnings when I compile it. So, while the above changes should allow it to compile, it's not clear that it will work.

Finally, I left out all your RFIDHandler stuff when I test compiled it because it's not relevant to IRremote.

Thx everyone for the help, i found in a older post the answer. All i had to do is add

#define USE_IRREMOTE_HPP_AS_PLAIN_INCLUDE
#include <IRremote.hpp>

in remote.ino

1 Like