Unresolvable "Undefined reference to" error

Hey guys,

I need your help, because I can't find the root cause for this issue.

Following setup is intended:

  • Attiny85 communcation via I2C
  • Arduino Mega2560 is receiving data from the Attiny85
  • An DS3231 is used (ZS-042) also communicating via I2C
  • Working with Arduino IDE 1.8.19
  • Attiny Core from Spence Konde

As soon as the whole circuit is done, an led stripe will be turned on and off based on the pre-defined alarms on the DS3231.

However, that's all future stuff, which should be handled by future Kerby...


Let's focus on the programming issue. I'm using the TinyI2C library from technoblogy (see TinyI2C Library), which can be also found in the code tags for readability reasons.

I created two additional files, called "Tiny_DS3231.cpp" and "Tiny_DS3231.h", which are containing some additional functions in order to separate them from the .ino file for readability reasons. One function reference can not be resolved and I don't know exactly why this is happening. The function concerning is called "send_debug (...)" and is originally defined under "Tiny_DS3231.cpp". Another function "get_currentTime (...)" is located in the same file, which for some reason can be successfully found by the linker. Hence, that doesn't make sense to me.

Following code is currently implemented:

I2C_ATTINY85.ino

#include <stdint.h>
#include <util/delay.h>

#include "Tiny_DS3231.h"
#include "TinyI2CMaster.h"

// ----------------------------------------------
// ATTINY85 PINOUT:
//
//          -------
//   RESET |   V   | VCC
//    PIN3 |       | PIN2 / SCL / INT0
//    PIN4 |       | PIN1
//     GND |       | PIN0 / SDA
//          -------
//
// ----------------------------------------------

//#define DEBUG

#define TRS_PIN 3
#define LED_PIN 4

uint8_t mins, hrs, next_time;

uint8_t blink = 0;
uint8_t time[2];
uint8_t led = 0;

void setup()
{
    // Calibrates the internal register value for the timer accuracy:
    OSCCAL -= 3;

    TinyI2C.init();

    pinMode(LED_PIN, OUTPUT);
    pinMode(TRS_PIN, OUTPUT);

    get_currentTime(time);

    mins = time[0];
    hrs  = time[1];

    // Every 5th multiple of minutes:
    next_time = ((mins + 4) / 5) *5;
}

void loop()
{
    get_currentTime(time);
    
    digitalWrite(LED_PIN, (blink = ~blink));
	
//#ifdef DEBUG
    send_debug(time, 2);
//#endif

	if (!(mins % 5) && (mins == next_time))
	{
		digitalWrite(TRS_PIN, (led = ~led));
		next_time = mins + 5;

		if (next_time >= 60)
		{
			next_time = 0;
		}
	}
    
    _delay_ms(1000);
}

Tiny_DS3231.cpp

// ******************************************************
//
//  Framework for accessing DS3231 registers with the
//  Attiny85 via I2C based on the library "TinyI2C"
//  from technoblogy
//
// ******************************************************

#include "Tiny_DS3231.h"
#include "TinyI2CMaster.h"

void send_debug(void *data_, uint32_t datalen)
{
    uint8_t* data = (uint8_t*) data_;
    
    TinyI2C.start(MEGA2560_ADDRESS, 0);
    
    for (uint32_t i = 0; i < datalen; ++i)
    {
        TinyI2C.write(*(data+i));
    }
    
  TinyI2C.stop();
}

void get_currentTime(uint8_t *time)
{
    // Read the time from the RTC:
    TinyI2C.start(DS3231_ADDRESS, 0);
    {
        // Start reading at register for minutes:
        TinyI2C.write(0x01);
    }
    TinyI2C.restart(DS3231_ADDRESS, 2);
    {
        time[0] = TinyI2C.read(); // Register 0x01: Minutes
        time[1] = TinyI2C.read(); // Register 0x02: Hours
    }
    TinyI2C.stop();
}

Tiny_DS3231.h

// ******************************************************
//
//  Framework for accessing DS3231 registers
//  with the Attiny85 via I2C
//
// ******************************************************

#ifndef _TINY_DS3231_H_
#define _TINY_DS3231_H_

#include <stdint.h>

#define DS3231_ADDRESS (0x68)
#define MEGA2560_ADDRESS (0x01)

  void get_currentTime(uint8_t *time);
  void send_debug(void *data, int datalen);

#endif // _TINY_DS3231_H_

TinyI2CMaster.cpp

/* Tiny I2C
   David Johnson-Davies - www.technoblogy.com - 14th April 2018
   
   CC BY 4.0
   Licensed under a Creative Commons Attribution 4.0 International license: 
   http://creativecommons.org/licenses/by/4.0/
*/

#include "TinyI2CMaster.h"

TinyI2CMaster::TinyI2CMaster() 
{
}

// Minimal Tiny I2C Routines **********************************************

uint8_t TinyI2CMaster::transfer (uint8_t data) {
  USISR = data;                               // Set USISR according to data.
                                              // Prepare clocking.
  data = 0<<USISIE | 0<<USIOIE |              // Interrupts disabled
         1<<USIWM1 | 0<<USIWM0 |              // Set USI in Two-wire mode.
         1<<USICS1 | 0<<USICS0 | 1<<USICLK |  // Software clock strobe as source.
         1<<USITC;                            // Toggle Clock Port.
  do {
    DELAY_T2TWI;
    USICR = data;                             // Generate positive SCL edge.
    while (!(PIN_USI_CL & 1<<PIN_USI_SCL));   // Wait for SCL to go high.
    DELAY_T4TWI;
    USICR = data;                             // Generate negative SCL edge.
  } while (!(USISR & 1<<USIOIF));             // Check for transfer complete.

  DELAY_T2TWI;
  data = USIDR;                               // Read out data.
  USIDR = 0xFF;                               // Release SDA.
  DDR_USI |= (1<<PIN_USI_SDA);                // Enable SDA as output.

  return data;                                // Return the data from the USIDR
}

void TinyI2CMaster::init () {
  PORT_USI |= 1<<PIN_USI_SDA;                 // Enable pullup on SDA.
  PORT_USI_CL |= 1<<PIN_USI_SCL;              // Enable pullup on SCL.

  DDR_USI_CL |= 1<<PIN_USI_SCL;               // Enable SCL as output.
  DDR_USI |= 1<<PIN_USI_SDA;                  // Enable SDA as output.

  USIDR = 0xFF;                               // Preload data register with "released level" data.
  USICR = 0<<USISIE | 0<<USIOIE |             // Disable Interrupts.
          1<<USIWM1 | 0<<USIWM0 |             // Set USI in Two-wire mode.
          1<<USICS1 | 0<<USICS0 | 1<<USICLK | // Software stobe as counter clock source
          0<<USITC;
  USISR = 1<<USISIF | 1<<USIOIF | 1<<USIPF | 1<<USIDC | // Clear flags,
          0x0<<USICNT0;                       // and reset counter.
}

uint8_t TinyI2CMaster::read (void) {
  if ((I2Ccount != 0) && (I2Ccount != -1)) I2Ccount--;
  
  /* Read a byte */
  DDR_USI &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.
  uint8_t data = TinyI2CMaster::transfer(USISR_8bit);

  /* Prepare to generate ACK (or NACK in case of End Of Transmission) */
  if (I2Ccount == 0) USIDR = 0xFF; else USIDR = 0x00;
  TinyI2CMaster::transfer(USISR_1bit);                 // Generate ACK/NACK.

  return data;                                // Read successfully completed
}

uint8_t TinyI2CMaster::readLast (void) {
  I2Ccount = 0;
  return TinyI2CMaster::read();
}

bool TinyI2CMaster::write (uint8_t data) {
  /* Write a byte */
  PORT_USI_CL &= ~(1<<PIN_USI_SCL);           // Pull SCL LOW.
  USIDR = data;                               // Setup data.
  TinyI2CMaster::transfer(USISR_8bit);                 // Send 8 bits on bus.

  /* Clock and verify (N)ACK from slave */
  DDR_USI &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.
  if (TinyI2CMaster::transfer(USISR_1bit) & 1<<TWI_NACK_BIT) return false;

  return true;                                // Write successfully completed
}

// Start transmission by sending address
bool TinyI2CMaster::start (uint8_t address, int readcount) {
  if (readcount != 0) { I2Ccount = readcount; readcount = 1; }
  uint8_t addressRW = address<<1 | readcount;

  /* Release SCL to ensure that (repeated) Start can be performed */
  PORT_USI_CL |= 1<<PIN_USI_SCL;              // Release SCL.
  while (!(PIN_USI_CL & 1<<PIN_USI_SCL));     // Verify that SCL becomes high.
#ifdef TWI_FAST_MODE
  DELAY_T4TWI;
#else
  DELAY_T2TWI;
#endif

  /* Generate Start Condition */
  PORT_USI &= ~(1<<PIN_USI_SDA);              // Force SDA LOW.
  DELAY_T4TWI;
  PORT_USI_CL &= ~(1<<PIN_USI_SCL);           // Pull SCL LOW.
  PORT_USI |= 1<<PIN_USI_SDA;                 // Release SDA.

  if (!(USISR & 1<<USISIF)) return false;

  /*Write address */
  PORT_USI_CL &= ~(1<<PIN_USI_SCL);           // Pull SCL LOW.
  USIDR = addressRW;                          // Setup data.
  TinyI2CMaster::transfer(USISR_8bit);                 // Send 8 bits on bus.

  /* Clock and verify (N)ACK from slave */
  DDR_USI &= ~(1<<PIN_USI_SDA);               // Enable SDA as input.
  if (TinyI2CMaster::transfer(USISR_1bit) & 1<<TWI_NACK_BIT) return false; // No ACK

  return true;                                // Start successfully completed
}

bool TinyI2CMaster::restart(uint8_t address, int readcount) {
  return TinyI2CMaster::start(address, readcount);
}

void TinyI2CMaster::stop (void) {
  PORT_USI &= ~(1<<PIN_USI_SDA);              // Pull SDA low.
  PORT_USI_CL |= 1<<PIN_USI_SCL;              // Release SCL.
  while (!(PIN_USI_CL & 1<<PIN_USI_SCL));     // Wait for SCL to go high.
  DELAY_T4TWI;
  PORT_USI |= 1<<PIN_USI_SDA;                 // Release SDA.
  DELAY_T2TWI;
}

TinyI2CMaster TinyI2C = TinyI2CMaster();      // Instantiate a TinyI2C object

TinyI2CMaster.h

/* Tiny I2C
   David Johnson-Davies - www.technoblogy.com - 28th May 2019
   
   CC BY 4.0
   Licensed under a Creative Commons Attribution 4.0 International license: 
   http://creativecommons.org/licenses/by/4.0/
*/

#ifndef TinyI2CMaster_h
#define TinyI2CMaster_h

#include <stdint.h>
#include <Arduino.h>
#include <avr/io.h>
#include <util/delay.h>

// Defines
#define TWI_FAST_MODE

#ifdef TWI_FAST_MODE                 // TWI FAST mode timing limits. SCL = 100-400kHz
#define DELAY_T2TWI (_delay_us(2))   // >1.3us
#define DELAY_T4TWI (_delay_us(1))   // >0.6us
#else                                // TWI STANDARD mode timing limits. SCL <= 100kHz
#define DELAY_T2TWI (_delay_us(5))   // >4.7us
#define DELAY_T4TWI (_delay_us(4))   // >4.0us
#endif

#define TWI_NACK_BIT 0 // Bit position for (N)ACK bit.

// Constants
// Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.
const unsigned char USISR_8bit = 1<<USISIF | 1<<USIOIF | 1<<USIPF | 1<<USIDC | 0x0<<USICNT0;
// Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.
const unsigned char USISR_1bit = 1<<USISIF | 1<<USIOIF | 1<<USIPF | 1<<USIDC | 0xE<<USICNT0;

class TinyI2CMaster {

    public:
  TinyI2CMaster();
  void init(void);
  uint8_t read(void);
  uint8_t readLast(void);
  bool write(uint8_t data);
  bool start(uint8_t address, int readcount);
  bool restart(uint8_t address, int readcount);
  void stop(void);

    private:
  int I2Ccount;
  uint8_t transfer(uint8_t data);
};

extern TinyI2CMaster TinyI2C;

#endif

The error from the Arduino IDE is the following, when trying to compile the .ino:

Arduino: 1.8.19 (Windows Store 1.8.57.0) (Windows 10), Board: "ATtiny25/45/85 (No bootloader), Enabled, CPU (CPU frequency), ATtiny85, 8 MHz (internal), EEPROM retained, B.O.D. Disabled (saves power), Enabled"

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware -hardware C:\Users\<User>\Documents\ArduinoData\packages -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\tools-builder -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware\tools\avr -tools C:\Users\<User>\Documents\ArduinoData\packages -built-in-libraries C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\libraries -libraries C:\Users\<User>\Documents\Arduino\libraries -fqbn=ATTinyCore:avr:attinyx5:LTO=enable,TimerClockSource=default,chip=85,clock=8internal,eesave=aenable,bod=disable,millis=enabled -vid-pid=2341_0043 -ide-version=10819 -build-path C:\Users\<User>\AppData\Local\Temp\arduino_build_67524 -warnings=all -build-cache C:\Users\<User>\AppData\Local\Temp\arduino_cache_712885 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.micronucleus.path=C:\Users\<User>\Documents\ArduinoData\packages\ATTinyCore\tools\micronucleus\2.5-azd1b -prefs=runtime.tools.micronucleus-2.5-azd1b.path=C:\Users\<User>\Documents\ArduinoData\packages\ATTinyCore\tools\micronucleus\2.5-azd1b -prefs=runtime.tools.avrdude.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avrdude-6.3.0-arduino18.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -verbose C:\Users\<User>\Documents\Arduino\I2C_ATTINY85\I2C_ATTINY85.ino

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\arduino-builder -compile -logger=machine -hardware C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware -hardware C:\Users\<User>\Documents\ArduinoData\packages -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\tools-builder -tools C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware\tools\avr -tools C:\Users\<User>\Documents\ArduinoData\packages -built-in-libraries C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\libraries -libraries C:\Users\<User>\Documents\Arduino\libraries -fqbn=ATTinyCore:avr:attinyx5:LTO=enable,TimerClockSource=default,chip=85,clock=8internal,eesave=aenable,bod=disable,millis=enabled -vid-pid=2341_0043 -ide-version=10819 -build-path C:\Users\<User>\AppData\Local\Temp\arduino_build_67524 -warnings=all -build-cache C:\Users\<User>\AppData\Local\Temp\arduino_cache_712885 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.micronucleus.path=C:\Users\<User>\Documents\ArduinoData\packages\ATTinyCore\tools\micronucleus\2.5-azd1b -prefs=runtime.tools.micronucleus-2.5-azd1b.path=C:\Users\<User>\Documents\ArduinoData\packages\ATTinyCore\tools\micronucleus\2.5-azd1b -prefs=runtime.tools.avrdude.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avrdude-6.3.0-arduino18.path=C:\Users\<User>\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino18 -verbose C:\Users\<User>\Documents\Arduino\I2C_ATTINY85\I2C_ATTINY85.ino

Using board 'attinyx5' from platform in folder: C:\Users\<User>\Documents\ArduinoData\packages\ATTinyCore\hardware\avr\1.5.2

Using core 'tiny' from platform in folder: C:\Users\<User>\Documents\ArduinoData\packages\ATTinyCore\hardware\avr\1.5.2

Detecting libraries used...

"C:\\Users\\<User>\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=attiny85 -DF_CPU=8000000L -DCLOCK_SOURCE=0 -DARDUINO=10819 -DARDUINO_AVR_ATTINYX5 -DARDUINO_ARCH_AVR -DNEOPIXELPORT=PORTB "-IC:\\Users\\<User>\\Documents\\ArduinoData\\packages\\ATTinyCore\\hardware\\avr\\1.5.2\\cores\\tiny" "-IC:\\Users\\<User>\\Documents\\ArduinoData\\packages\\ATTinyCore\\hardware\\avr\\1.5.2\\variants\\tinyX5" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\I2C_ATTINY85.ino.cpp" -o nul

Using cached library dependencies for file: C:\Users\<User>\AppData\Local\Temp\arduino_build_67524\sketch\TinyI2CMaster.cpp

Using cached library dependencies for file: C:\Users\<User>\AppData\Local\Temp\arduino_build_67524\sketch\Tiny_DS3231.cpp

Generating function prototypes...

"C:\\Users\\<User>\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=attiny85 -DF_CPU=8000000L -DCLOCK_SOURCE=0 -DARDUINO=10819 -DARDUINO_AVR_ATTINYX5 -DARDUINO_ARCH_AVR -DNEOPIXELPORT=PORTB "-IC:\\Users\\<User>\\Documents\\ArduinoData\\packages\\ATTinyCore\\hardware\\avr\\1.5.2\\cores\\tiny" "-IC:\\Users\\<User>\\Documents\\ArduinoData\\packages\\ATTinyCore\\hardware\\avr\\1.5.2\\variants\\tinyX5" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\I2C_ATTINY85.ino.cpp" -o "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\preproc\\ctags_target_for_gcc_minus_e.cpp"

"C:\\Program Files\\WindowsApps\\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\preproc\\ctags_target_for_gcc_minus_e.cpp"

Compiling sketch...

"C:\\Users\\<User>\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=attiny85 -DF_CPU=8000000L -DCLOCK_SOURCE=0 -DARDUINO=10819 -DARDUINO_AVR_ATTINYX5 -DARDUINO_ARCH_AVR -DNEOPIXELPORT=PORTB "-IC:\\Users\\<User>\\Documents\\ArduinoData\\packages\\ATTinyCore\\hardware\\avr\\1.5.2\\cores\\tiny" "-IC:\\Users\\<User>\\Documents\\ArduinoData\\packages\\ATTinyCore\\hardware\\avr\\1.5.2\\variants\\tinyX5" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\I2C_ATTINY85.ino.cpp" -o "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\I2C_ATTINY85.ino.cpp.o"

Using previously compiled file: C:\Users\<User>\AppData\Local\Temp\arduino_build_67524\sketch\Tiny_DS3231.cpp.o

Using previously compiled file: C:\Users\<User>\AppData\Local\Temp\arduino_build_67524\sketch\TinyI2CMaster.cpp.o

Compiling libraries...

Compiling core...

Using precompiled core: C:\Users\<User>\AppData\Local\Temp\arduino_cache_712885\core\core_9558a1c025a50e12ab415d105f7eef9f.a

Linking everything together...

"C:\\Users\\<User>\\Documents\\ArduinoData\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -Wall -Wextra -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=attiny85 -o "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524/I2C_ATTINY85.ino.elf" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\I2C_ATTINY85.ino.cpp.o" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\TinyI2CMaster.cpp.o" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524\\sketch\\Tiny_DS3231.cpp.o" "C:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524/..\\arduino_cache_712885\\core\\core_9558a1c025a50e12ab415d105f7eef9f.a" "-LC:\\Users\\<User>\\AppData\\Local\\Temp\\arduino_build_67524" -lm

C:\Users\<User>\AppData\Local\Temp\ccqfSMek.ltrans0.ltrans.o: In function `loop':

C:\Users\<User>\Documents\Arduino\I2C_ATTINY85/I2C_ATTINY85.ino:56: undefined reference to `send_debug(void*, int)'

collect2.exe: error: ld returned 1 exit status

exit status 1

Error compiling for board ATtiny25/45/85 (No bootloader).

Do you guys have any idea how to solve it? I probably tried everything.
Tried to move it to the libraries folder and accessing it via

#include <Tiny_DS3231.h>

hasn't solved the issue.

I also changed the name of the function from "send_debug" to something like "check_var", which hasn't solved the issue, too.

All files are located in one folder. No other folders are existing in that one. The Arduino IDE detects all files fine, which is visible by the top tabs (exactly 5 tabs for 5 files).

Remark: If you are checking the paths, I manually replaced my user name with "<User>".

Thanks for any helpful advice!

Kerby

Please capture the complete error message and post here in tags.

I don't understand... I tried my best and set up everything in code tags. Am I missing something?

In the past, I have seen the IDE fail to create a function prototype when putting libraries into tabs.

C:\Users\<User>\Documents\Arduino\I2C_ATTINY85/I2C_ATTINY85.ino:56: undefined reference to `send_debug(void*, int)'

Guessing...
In your .INO, just build the prototype like a good C/C++ coder.

Ray

Not the problem. The prototype is already present in the .h file OP #include(d) in the .ino.

Look at the signature of 'send_debug()' in Tiny_DS3231.h:

void send_debug(void *data, int datalen);

Compare that to the implementation in Tiny_DS3231.cpp:

void send_debug(void *data_, uint32_t datalen)
{

See the difference?

Holy s***, you are right. I was so blind...

Damn, sometimes it's just better to restart debugging the next day instead of trying to fix it the whole evening without pauses.

Honestly, I'm usually used to that the compiler would tell me, that there is a difference. Interestingly, this time it doesn't.

However, I will check this tomorrow and let you know. Big "Thank you" to @gfvalvo for taking your time to find the issue!

It wasn't a problem that the compiler could catch.. Your .ino had a function signature (from the .h file) that matched your call to the function. That made the compiler perfectly happy to process your .ino.

The error was caught by the linker when it went looking for the implementation of a function with that name and signature. It couldn't find it because the .cpp file (which was also perfectly fine as far as the compiler was concerned) didn't implement that function name with that signature.

1 Like

Hey @gfvalvo ,

so to let you know: You nailed it.
It's compiling fine now. Shame on me...

Thanks, this topic is solved.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.