error: Wire.h: No such file or directory

Hi all, I'm going mad.

Really, I just wrote my first custom library to read from/write to my RTC Module (DS1307 + AT24C32).

I'm now trying to use it in my sketch, but I get an error saying:

error: Wire.h: No such file or directory

The Wire.h is imported in my header file using #include "Wire.h"

Googling I found that this is a known issue reported here, but I couldn't believe there's not any workaround to face this lack.
So I googled again but couldnt find anything, and now I'm here asking for your help.

Can you help me please?
Thank you guys!

#include <Wire.h>

Changed to

#include <Wire.h>

and things got worse

C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:19: error: ISO C++ forbids declaration of 'start' with no type
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:19: error: prototype for 'int RTCReader::start()' does not match any in class 'RTCReader'
C:\Users\Username\Documents\Arduino\libraries\RTCReader/RTCReader.h:11: error: candidate is: void RTCReader::start()
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:24: error: ISO C++ forbids declaration of 'end' with no type
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:24: error: prototype for 'int RTCReader::end()' does not match any in class 'RTCReader'
C:\Users\Username\Documents\Arduino\libraries\RTCReader/RTCReader.h:12: error: candidate is: void RTCReader::end()
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:33: error: ISO C++ forbids declaration of 'setDateTime' with no type
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:33: error: prototype for 'int RTCReader::setDateTime(short int, short int, short int, short int, short int, short int, short int)' does not match any in class 'RTCReader'
C:\Users\Username\Documents\Arduino\libraries\RTCReader/RTCReader.h:13: error: candidate is: void RTCReader::setDateTime(short int, short int, short int, short int, short int, short int, short int)
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:49: error: ISO C++ forbids declaration of 'getDateTime' with no type
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:49: error: prototype for 'int RTCReader::getDateTime(short int*, short int*, short int*, short int*, short int*, short int*, short int*)' does not match any in class 'RTCReader'
C:\Users\Username\Documents\Arduino\libraries\RTCReader/RTCReader.h:14: error: candidate is: void RTCReader::getDateTime(short int*, short int*, short int*, short int*, short int*, short int*, short int*)
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:68: error: ISO C++ forbids declaration of 'decToBcd' with no type
C:\Users\Username\Documents\Arduino\libraries\RTCReader\RTCReader.cpp:68: error: prototype for 'int RTCReader::decToBcd(byte)' does not match any in class 'RTCReader'
C:\Users\Username\Documents\Arduino\libraries\RTCReader/RTCReader.h:17: error: candidate is: byte RTCReader::decToBcd(byte)

so I think it would be useful to provide my code, just please help me get out of this

Header file

#ifndef RTCReader_h
#define RTCReader_h

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

class RTCReader
{
  public:
  	RTCReader(int rtc_i2c_address);
  	void start();
  	void end();
  	void setDateTime(short weekDay, short monthDay, short month, short year, short hours, short mins, short secs);
  	void getDateTime(short* weekDay, short* monthDay, short* month, short* year, short* hours, short* mins, short* secs);
  
  private:
  	byte decToBcd(byte val);
  	byte bcdToDec(byte val);
  	int RTC_I2C_ADDRESS;
  	int regPtrReset;
};

#endif

cpp file

#include "Arduino.h"
#include "RTCReader.h"

// Arduino version compatibility Pre-Compiler Directives
#if defined(ARDUINO) && ARDUINO >= 100   // Arduino v1.0 and newer
#define I2C_WRITE Wire.write
#define I2C_READ Wire.read
#else                                   // Arduino Prior to v1.0 
#define I2C_WRITE Wire.send
#define I2C_READ Wire.receive
#endif

RTCReader::RTCReader(int rtc_i2c_address)
{
  RTC_I2C_ADDRESS = rtc_i2c_address;
  regPtrReset = 0x00;
}

RTCReader::start()
{
  Wire.begin();
}

RTCReader::end()
{
  Wire.end();
}

// 1) Sets the date and time on the RTC
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers, Probably need to put in checks for valid numbers.
RTCReader::setDateTime(short weekDay, short monthDay, short month, short year, short hours, short mins, short secs)
{
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  I2C_WRITE(regPointReset);
  I2C_WRITE(decToBcd(secs) & 0x7f);    // 0 to bit 7 starts the clock
  I2C_WRITE(decToBcd(mins));
  I2C_WRITE(decToBcd(hours));      // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateRTC)
  I2C_WRITE(decToBcd(weekDay));
  I2C_WRITE(decToBcd(monthDay));
  I2C_WRITE(decToBcd(month));
  I2C_WRITE(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time from the RTC and prints result
RTCReader::getDateTime(short* weekDay, short* monthDay, short* month, short* year, short* hours, short* mins, short* secs)
{
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  I2C_WRITE(regPointReset);
  Wire.endTransmission();
  
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *secs     = bcdToDec(I2C_READ() & 0x7f);
  *mins     = bcdToDec(I2C_READ());
  *hours    = bcdToDec(I2C_READ() & 0x3f);  // Need to change this if 12 hour am/pm
  *weekDay  = bcdToDec(I2C_READ());
  *monthDay = bcdToDec(I2C_READ());
  *month    = bcdToDec(I2C_READ());
  *year     = bcdToDec(I2C_READ());
}

// Convert normal decimal numbers to binary coded decimal
RTCReader::decToBcd(byte val)
{
  return ((val / 10 * 16) + (val % 10));
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ((val / 16 * 10) + (val % 16));
}

the sketch

#include <RTCReader.h>

#define RTC_I2C_ADDRESS 0x68  // This is the I2C address

RTCReader rtcReader(RTC_I2C_ADDRESS);

short weekDay, monthDay, month, year, hours, mins, secs;
char  *Day[] = {"","Lun","Mar","Mer","Gio","Ven","Sab","Dom"};
char  *Mon[] = {"","Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"};

void setup()
{
  rtcReader.start();
  rtcReader.getDateTime(&weekDay, &monthDay, &month, &year, &hours, &mins, &secs);
  if (year == 0)
  {
    rtcReader.setDateTime(3, 14, 8, 2013, 13, 15, 0);
  }
}

void loop()
{
  rtcReader.getDateTime(&weekDay, &monthDay, &month, &year, &hours, &mins, &secs);
  
  if (hours < 10)
    Serial.print("0");
  Serial.print(hours, DEC);
  Serial.print(":");
  if (mins < 10)
    Serial.print("0");
  Serial.print(mins, DEC);
  Serial.print(":");
  if (secs < 10)
    Serial.print("0");
  Serial.print(secs, DEC);
  Serial.print("  ");
  Serial.print(Day[weekDay]);
  Serial.print(", ");
  Serial.print(monthDay, DEC);
  Serial.print(" ");
  Serial.print(Mon[month]);
  Serial.print(" 20");
  if (year < 10)
    Serial.print("0");
  Serial.println(year, DEC);
}

That isn't worse. It is better. There are some errors in your RTCReader.cpp file.
All those functions require a return type. Like start().

void RTCReader::start()
{
  Wire.begin();
}

Do the rest like that.

edit: Except the byte and int types.
byte should use uint8_t
int should use uint16_t

Ok that was stupid, I saw many lines and got scared :blush: (and didn't read)

anyway

  • void is not required by the ctor right?
  • now it says that Wire doesnt exist in .cpp at every point I try to use it, example

RTCReader.cpp:27: error: 'Wire' was not declared in this scope

do I have to #include <Wire.h> in .cpp too? (like in .h)

Yes, or include it in the script.

If I #include <Wire.h> in .cpp the error dosen't change
if I #include <Wire.h> in the sketch it shows one single error:

RTCReader.cpp:66: undefined reference to `RTCReader::bcdToDec(unsigned char)'

if I get it right I'm trying to access the bcdToDec function but it doesnt know where to find it, so I tried both RTCReader::bcdToDec and RTCReader.bcdToDec but other errors rise, so the only cause that gets in my mind atm is that it's something about the KEYWORDS file that i dont have yet (cause I'm following step-by-step the official guide to create custom libraries)

Am I right or totally wrong?

If you try outside that RTCReader.cpp file, you can't access these functions and variables. They are listed as private.

  private:
  	byte decToBcd(byte val);
  	byte bcdToDec(byte val);
  	int RTC_I2C_ADDRESS;
  	int regPtrReset;

Though I dont understand why i cant access a private member from the class itself, i moved the funcs to the public section

#ifndef RTCReader_h
#define RTCReader_h

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

class RTCReader
{
  public:
  	RTCReader(int rtc_i2c_address);
  	void start();
  	void end();
  	void setDateTime(short weekDay, short monthDay, short month, short year, short hours, short mins, short secs);
  	void getDateTime(short* weekDay, short* monthDay, short* month, short* year, short* hours, short* mins, short* secs);
  	[b]uint8_t decToBcd(byte val);
  	uint8_t bcdToDec(byte val);[/b]
  
  private:
  	int RTC_I2C_ADDRESS;
  	int regPtrReset;
};

#endif

but nothing changed (tried to restart the IDE too): the error remains

/RTCReader.cpp:68: undefined reference to `RTCReader::bcdToDec(unsigned char)'

P.S. keywords.txt created

thanks for the help you're giving me, i would be lost <3

I modified a few Arduino libraries to add features, and had bad luck using byte, char, and int in the .cpp files. I had to change all to uint8_t and uint16_t types, both in the return value and the parameters.

  	uint8_t decToBcd(uint8_t val);
  	uint8_t bcdToDec(uint8_t val);

Replaced all but still the same error =(

UPDATE: this is the code I'm actually working on

.h file

#ifndef RTCReader_h
#define RTCReader_h

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

class RTCReader
{
  public:
  	RTCReader(int rtc_i2c_address);
  	void start();
  	void end();
  	void setDateTime(short weekDay, short monthDay, short month, short year, short hours, short mins, short secs);
  	void getDateTime(short* weekDay, short* monthDay, short* month, short* year, short* hours, short* mins, short* secs);
  	uint8_t decToBcd(uint8_t val);
  	uint8_t bcdToDec(uint8_t val);
  
  private:
  	int RTC_I2C_ADDRESS;
  	int regPtrReset;
};

#endif

.cpp file

#include "Arduino.h"
#include "RTCReader.h"

// Arduino version compatibility Pre-Compiler Directives
#if defined(ARDUINO) && ARDUINO >= 100   // Arduino v1.0 and newer
#define I2C_WRITE Wire.write
#define I2C_READ Wire.read
#else                                   // Arduino Prior to v1.0 
#define I2C_WRITE Wire.send
#define I2C_READ Wire.receive
#endif

int regPointReset;

RTCReader::RTCReader(int rtc_i2c_address)
{
  RTC_I2C_ADDRESS = rtc_i2c_address;
  regPtrReset = 0x00;
}

void RTCReader::start()
{
  Wire.begin();
}

void RTCReader::end()
{
  //Wire.end();
}

// 1) Sets the date and time on the RTC
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers, Probably need to put in checks for valid numbers.
void RTCReader::setDateTime(short weekDay, short monthDay, short month, short year, short hours, short mins, short secs)
{
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  I2C_WRITE(regPointReset);
  I2C_WRITE(decToBcd(secs) & 0x7f);    // 0 to bit 7 starts the clock
  I2C_WRITE(decToBcd(mins));
  I2C_WRITE(decToBcd(hours));      // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateRTC)
  I2C_WRITE(decToBcd(weekDay));
  I2C_WRITE(decToBcd(monthDay));
  I2C_WRITE(decToBcd(month));
  I2C_WRITE(decToBcd(year));
  Wire.endTransmission();
}

// Convert normal decimal numbers to binary coded decimal
uint8_t RTCReader::decToBcd(uint8_t val)
{
  return ((val / 10 * 16) + (val % 10));
}

// Gets the date and time from the RTC and prints result
void RTCReader::getDateTime(short* weekDay, short* monthDay, short* month, short* year, short* hours, short* mins, short* secs)
{
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  I2C_WRITE(regPointReset);
  Wire.endTransmission();
  
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *secs     = bcdToDec(I2C_READ() & 0x7f);
  *mins     = bcdToDec(I2C_READ());
  *hours    = bcdToDec(I2C_READ() & 0x3f);  // Need to change this if 12 hour am/pm
  *weekDay  = bcdToDec(I2C_READ());
  *monthDay = bcdToDec(I2C_READ());
  *month    = bcdToDec(I2C_READ());
  *year     = bcdToDec(I2C_READ());
}

// Convert binary coded decimal to normal decimal numbers
uint8_t bcdToDec(uint8_t val)
{
  return ((val / 16 * 10) + (val % 16));
}

keywords file

RTCReader	KEYWORD1
start		KEYWORD2
end		KEYWORD2
setDateTime	KEYWORD2
getDateTime	KEYWORD2

sketch file

#include <Wire.h>

#include <RTCReader.h>

#define RTC_I2C_ADDRESS 0x68  // This is the I2C address

RTCReader rtcReader(RTC_I2C_ADDRESS);

short weekDay, monthDay, month, year, hours, mins, secs;
char  *Day[] = {"","Lun","Mar","Mer","Gio","Ven","Sab","Dom"};
char  *Mon[] = {"","Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"};

void setup()
{
  rtcReader.start();
  rtcReader.getDateTime(&weekDay, &monthDay, &month, &year, &hours, &mins, &secs);
  if (year == 0)
  {
    rtcReader.setDateTime(3, 14, 8, 2013, 13, 15, 0);
  }
}

void loop()
{
  rtcReader.getDateTime(&weekDay, &monthDay, &month, &year, &hours, &mins, &secs);
  
  if (hours < 10)
    Serial.print("0");
  Serial.print(hours, DEC);
  Serial.print(":");
  if (mins < 10)
    Serial.print("0");
  Serial.print(mins, DEC);
  Serial.print(":");
  if (secs < 10)
    Serial.print("0");
  Serial.print(secs, DEC);
  Serial.print("  ");
  Serial.print(Day[weekDay]);
  Serial.print(", ");
  Serial.print(monthDay, DEC);
  Serial.print(" ");
  Serial.print(Mon[month]);
  Serial.print(" 20");
  if (year < 10)
    Serial.print("0");
  Serial.println(year, DEC);
}

Wire::read() returns an integer, not a byte. Maybe that confuses the compiler?

I dont think so because everything worked as sketch, now that I'm turning it into a library it raises errors, but funcs and their use is just copy-pasted from the sketch

I tried to replay both parameter and return type (byte-short, both individually and together) but it just changes the error to a type conversion issue so I think this is not the solution T_T

EDIT: for completeness the whole errors report is

RTCReader\RTCReader.cpp.o: In function RTCReader::getDateTime(short*, short*, short*, short*, short*, short*, short*)': C:\Users\Daedalus\Documents\Arduino\libraries\RTCReader/RTCReader.cpp:72: undefined reference to RTCReader::bcdToDec(short)'
C:\Users\Daedalus\Documents\Arduino\libraries\RTCReader/RTCReader.cpp:73: undefined reference to RTCReader::bcdToDec(short)' C:\Users\Daedalus\Documents\Arduino\libraries\RTCReader/RTCReader.cpp:74: undefined reference to RTCReader::bcdToDec(short)'
C:\Users\Daedalus\Documents\Arduino\libraries\RTCReader/RTCReader.cpp:75: undefined reference to RTCReader::bcdToDec(short)' C:\Users\Daedalus\Documents\Arduino\libraries\RTCReader/RTCReader.cpp:76: undefined reference to RTCReader::bcdToDec(short)'
RTCReader\RTCReader.cpp.o:C:\Users\Daedalus\Documents\Arduino\libraries\RTCReader/RTCReader.cpp:77: more undefined references to `RTCReader::bcdToDec(short)' follow

facepalm

just accidentally removed RTCReader prefix from bcdToDec: I'm kinda retarded today, sorry :grin:

Daedalus1632:
facepalm

just accidentally removed RTCReader prefix from bcdToDec: I'm kinda retarded today, sorry :grin:

That means it is working now?

No lol, it just doesnt give any error XD , now I will look for logical errors

thanks for your precious time man! karma up and tons of gratitude! =)

Thanks and no problem. Remember when troubleshooting logic, Serial.println() is your friend! :slight_smile:

All working now, just forgot Serial.begin(); XD