undefined reference Error

I've just got started with Arduino and the editor. I'm fairly expericiend in C but new to Ardunio and the IDE. I'm using the online editor.

I keep getting an undefined reference Error for code that should compile/verify.

As an example - I've created a copy of the blink example (whihc works fine) and have started modifying it. I want seperate source files for various functions. My test project has 3 files:

  • My_Blink.ino
  • MyDelay.c
  • MyDelay.h

The Source code of which is fairly simple:
My_Blink.ino

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  digitalWrite(LED_BUILTIN, HIGH);
  do_a_delay(100);
  digitalWrite(LED_BUILTIN, LOW);
  do_a_delay(100);
}

MyDelay.c

#include "MyDelay.h"

void do_a_delay(int length)
{
  delay(length);
}

MyDelay.h

void do_a_delay(int length);

I can't see any reason this wouldn't compile, but it doesn't - instead I get the following error:

./opt/arduino-builder/arduino-builder -compile -core-api-version 10611 -hardware opt/arduino-builder/hardware -hardware ./opt/cores -tools opt/arduino-builder/tools -tools ./opt/tools -built-in-libraries opt/libraries/latest -logger humantags -fqbn arduino:avr:nano:cpu=atmega328 -build-cache /tmp -build-path /tmp/057536142/build -verbose -prefs runtime.tools.avr-gcc.path=./opt/tools/avr-gcc/5.4.0-atmel3.6.1-arduino2 -prefs runtime.tools.avrdude.path=./opt/tools/avrdude/6.3.0-arduino14 -prefs runtime.tools.arduinoOTA.path=./opt/tools/arduinoOTA/1.2.1 -libraries /tmp/057536142/custom -libraries /tmp/057536142/pinned /tmp/057536142/My_Blink

Linking everything together...

/tmp/ccgFCmRK.ltrans0.ltrans.o: In function `loop':

/tmp/057536142/My_Blink/My_Blink.ino:18: undefined reference to `do_a_delay(int)'

/tmp/057536142/My_Blink/My_Blink.ino:20: undefined reference to `do_a_delay(int)'

collect2: error: ld returned 1 exit status

exit status 1

I can't see any reason this wouldn't compile

I can't see any reason why someone would post this question in a section of the forum that is clearly marked "For problems with Arduino itself, NOT your project".

Thread moved.

AWOL:
I can't see any reason why someone would post this question in a section of the forum that is clearly marked "For problems with Arduino itself, NOT your project".

Thread moved.

I put in that section of the forum specifically becuase it seems like a Problem with Ardunio itself - rather than a specific project (hence why I just used a generic project in my example).

However, if it was in the wrong place, I apologise.

Do you notice any significant difference between MyDelay.c and My_Blink.ino?

MyDelay.h contains the declaration of the do_a_delay function. You must add an #include directive to My_Blink.ino for that file.

But this doesn't solve the error. Why not? You need to understand that Arduino sketches are compiled as C++. When you name your file MyDelay.c, that causes it to be compiled as C. If you want to use C functions in C++ code, the declaration must be wrapped in extern "C" {}. You can do that from the sketch like this:

extern "C" {
#include "MyDelay.h"
}

Or you can do it from the .h file like this:

#if defined(__cplusplus)
extern "C" {
#endif  // defined(__cplusplus)
void do_a_delay(int length);
#if defined(__cplusplus)
}
#endif  // defined(__cplusplus)

It will now compile, but notice there is a warning:

MyDelay.c:5:3: warning: implicit declaration of function 'delay'; did you mean 'do_a_delay'? [-Wimplicit-function-declaration]

   delay(length);

   ^~~~~

The declaration of the Arduino delay function is in the Arduino core library. You can bring in that declaration by adding this #include directive:

#include <Arduino.h>

You don't need to do that with .ino files because the Arduino IDE automatically adds the #include directive for Arduino.h to .ino files. However, the Arduino IDE does not mess around with files with other extensions in the sketch (e.g. .h, .c) so you need to do that work yourself when you need to use things from the Arduino core library in those files.

The alternative to extern "C" is to rename MyDelay.c as MyDelay.cpp, which will cause it to be compiled as C++ just like the .ino file.

thanks for the response. I understand it now

You're welcome. I'm glad if I was able to be of assistance. Enjoy!
Per