-
For my project I require two I2C interfaces (one for the TMP102 Temperature Sensor and one for a DS1307 Real Time Clock module). The PCB I have designed for the project has the RTC physically connected to the second, user defined I2C interface. I am using the Sparkfun ESP32 Thing microprocessor.
-
I have a test sketch (modified from elsewhere) which scans for I2C devices. To do this I have defined the pins for the second I2C connection and then created two ‘TwoWire’ instances (I2Cone – the default I2C instance, and I2Ctwo, the user defined two wire instance).
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
Code adapted from: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/
*********/
// Library
#include <Wire.h>
#include <RTClib.h>
// I2C
#define I2C_SCL_RTC 26
#define I2C_SDA_RTC 27
TwoWire I2Cone = TwoWire(0);
TwoWire I2Ctwo = TwoWire(1);
// RTC
RTC_DS1307 rtc; // set up an RTC instance
void setup() {
Serial.begin(9600);
Serial.println("\nI2C Scanner");
I2Cone.begin(21, 22);
I2Ctwo.begin(I2C_SDA_RTC,I2C_SCL_RTC,100000); // don't use address in the freq position - creates an error
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
// while (1) delay(10);
}
if (! rtc.isrunning()) { //// **Where I think my code errors.**
Serial.println("RTC is NOT running!");
} else if (rtc.isrunning()) {
Serial.println("RTC IS running!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
} // end setup
void loop() {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
I2Ctwo.beginTransmission(address);
error = I2Ctwo.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknown error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
//Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
//Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
delay(5000);
}
-
The sketch confirms that the DS1307 RTC I2C device is present at returning addresses of 0x50 and 0x68 using the user defined I2C interface (I2Ctwo).
-
In the sketch I have created an RTC_DS1307 instance named ‘rtc.’ This is using the ‘RTClib’ library – Version 2.0.2 (latest).
-
When I call rtc.begin() an error message returned (‘Couldn’t find RTC’). This is because rtc.begin() defaults to the default ‘Wire’ I2C interface.
-
Others have had this problem. Two fixes are detailed here: arduino due - Second I2C on Due RTClib, can't start - Arduino Stack Exchange'
a. The first fix is to change the pointer in RTClib.h for the DS1307 class definition from the default ‘&Wire’ to the new wire instance (e.g. &I2Ctwo). When I make this change I get the following error:
“call to 'boolean RTC_DS1307::begin(TwoWire)' uses the default argument for parameter 1, which is not yet defined*”
b. The second fix is to add a #define for the second I2C interface. I have tried using two definitions (#define Wire I2Ctwo and #define TwoWire I2Ctwo). Errors are returned as follows:
When using #define Wire I2Ctwo the error message is: ‘call to 'boolean RTC_DS1307::begin(TwoWire)' uses the default argument for parameter 1, which is not yet defined*’ – same as previous error.
When using #define TwoWire I2Ctwo: ‘error: 'I2Ctwo' has not been declared #define TwoWire I2Ctwo’
-
I have checked the other files in RTClib of relevance (RTClib.cpp and DS1307.h). Nothing in either of these files appears relevant to this problem.
-
RTClib.h includes the file ‘Adafruit_I2CDevice.h’ from the Adafruit_BusIO library. In the class ‘Adafruit_I2CDevice’ it has the pointer to ‘&Wire.’ I added the #define Wire I2Ctwo and changed the point from &Wire to &I2Ctwo. The result is the same error. This line of fixing the problem appears to have got me nowhere so I looked for other approaches.
-
I tried the RTClib example sketch: ‘customWire_DS3231onSAMD21.’ When I run it the following error occurs: ‘sercom0' was not declared in this scope.’
-
Basically at this point I am stuck. The task seems easy, redirect the RTC to look at the second I2C interface but after several days I have not been able to solve this. Any assistance would be greatly appreciated.
Thank you
Cameron