0

I want to write a library for the RGBDigit shield (http://rgbdigit.com/), which essentially is an Adafruit Neopixel strip, packed as a 7 segment display. The shield also has a DS3231 clock and an IR receiver.

So my plan was to make a class RGBDigit, which inherits from the Adafruit_NeoPixel class and add private objects DS3231 and IRrecv.

This is my RGBDigit.h:

#ifndef RGBDigit_h
#define RGBDigit_h

#include <Arduino.h>
#include "Wire.h"
#include "../Adafruit_NeoPixel/Adafruit_NeoPixel.h"
#include "../IRremote/IRremote.h"
#include "../DS3231/DS3231.h"

class RGBDigit : public Adafruit_NeoPixel {
    public:
        RGBDigit(int nDigits);
        ~RGBDigit();
    private:
        int _nDigits;
        DS3231 _clock;
        IRrecv* _ir;
};

#endif

This is RGBDigit.cpp:

#include "RGBDigit.h"


RGBDigit::RGBDigit(int nDigits)
    : Adafruit_NeoPixel(8 * nDigits, 12, NEO_GRB + NEO_KHZ800),
    _nDigits(nDigits)
{
    _ir = new IRrecv(10);
    _ir->enableIRIn(); // Start the receiver
    Adafruit_NeoPixel::begin();
}

RGBDigit::~RGBDigit()
{
    delete _ir;
}

And this is my Arduino sketch:

#include <Wire.h>
#include <RGBDigit.h>

RGBDigit display = RGBDigit(4);

void setup() {
    // put your setup code here, to run once:

}

void loop() {
    // put your main code here, to run repeatedly:

}

I get al lot of "undefined reference" errors:

RGBDigit/RGBDigit.cpp.o: In function `RGBDigit::RGBDigit(int)':
/home/ralph/Arduino/libraries/RGBDigit/RGBDigit.cpp:23: undefined reference to `Adafruit_NeoPixel::Adafruit_NeoPixel(unsigned int, unsigned char, unsigned char)'
/home/ralph/Arduino/libraries/RGBDigit/RGBDigit.cpp:23: undefined reference to `DS3231::DS3231()'
/home/ralph/Arduino/libraries/RGBDigit/RGBDigit.cpp:25: undefined reference to `IRrecv::IRrecv(int)'
/home/ralph/Arduino/libraries/RGBDigit/RGBDigit.cpp:26: undefined reference to `IRrecv::enableIRIn()'
/home/ralph/Arduino/libraries/RGBDigit/RGBDigit.cpp:27: undefined reference to `Adafruit_NeoPixel::begin()'
RGBDigit/RGBDigit.cpp.o: In function `RGBDigit::~RGBDigit()':
/home/ralph/Arduino/libraries/RGBDigit/RGBDigit.cpp:30: undefined reference to `Adafruit_NeoPixel::~Adafruit_NeoPixel()'
collect2: error: ld returned 1 exit status

But I don' t understand why. What am I doing wrong?

1
  • 1
    You're assuming that the IDE is smart enough to know that it needs to copy over and link the other libraries. Sep 5 '15 at 7:56
0
#include "../Adafruit_NeoPixel/Adafruit_NeoPixel.h"
#include "../IRremote/IRremote.h"
#include "../DS3231/DS3231.h"

What you're doing there is telling the compiler where, relative to where it's performing the compiling (or one of its include directories), the header files you list are.

What you're not doing is telling the IDE where the CPP files are to compile and link with your sketch.

When including anything external to the sketch folder that is more than just a header file you must treat it as an Arduino library - that is, place it in one of the standard library folders and name it properly (libraries should be named LibraryName/LibraryName.h).

Then you include the libraries properly:

#include <Adafruit_NeoPixel.h>
#include <IRremote.h>
#include <DS3231.h>

You must do that in both your sketch and your custom library. That way the IDE knows where to look for the files to compile - the compiler doesn't understand the concept of an Arduino library (and thus the CPP files associated with a header file) - that is purely down to the IDE gathering the data by examining your sketch and locating the right files to then pass to the compiler.

4
  • Thank you very much; I understand it now! But isn't it a bad thing that someone who wants to use my RGBDigit library, also needs to know which other classes and libraries are used by RGBDigit?
    – Ralph
    Sep 5 '15 at 10:19
  • @Ralph: With all due credit to the Arduino IDE's developers for a basic download-and-go beginners IDE, it has its limitations. You have met some of them.
    – JRobert
    Sep 5 '15 at 11:09
  • @Ralph Yep, that's a shortcoming all right. One that I addressed in my replacement IDE - UECIDE. Upgrade to that and you won't see that problem since it can recursively scan libraries for other libraries that they rely on.
    – Majenko
    Sep 5 '15 at 11:11
  • 1
    See How the IDE organizes things for more details about this. But isn't it a bad thing that someone who wants to use my RGBDigit library, also needs to know which other classes and libraries are used by RGBDigit? - most IDEs need you to tell them, one way or another, which libraries to use. If UECIDE does that automatically, that sounds good. However if you rely upon a different IDE, now you need to tell your users that it only works with that IDE. Maybe you could just explain in the documentation you post with it?
    – Nick Gammon
    Sep 5 '15 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.