I2C and SPI interfaces do not work in one sketch

:frowning: I don't succeed in making the I2C and SPI interfaces work in one sketch on a generic Arduino MEGA2560.
I2C: RTC-DS3231 (0x68) and LCD_4x20 (0x27) together on SDA & SCL without SD card = OK
SPI: Arduino - Examples - SD (CS=53, SCK=52, MOSI=51, MISO=50): card-info alone = OK
To prepare for another data logging sketch, only the date and time should be written line by line to the SD card.
As soon as the SPI.h library is included, SD.begin() reports 'SD initialization failed'.
I felt like I looked at 500 posts about "I2C and SPI", but found no hint.
Is there anyone who can help and knows how to do this interfaces?
Thanks in advance. Regards

DS3231-RTC-auf-LCDdt_SD-v00a-20190807.ino (2.46 KB)

DS3231-I2C-SPI-Prbl-03.jpg

SPI: Arduino - Examples - SD (CS=53, SCK=52, MOSI=51, MISO=50): card-info alone = OK

is inconsistent with:

As soon as the SPI.h library is included, SD.begin() reports 'SD initialization failed'.

You need the SPI.h library to read the SD card!

 void loop() { 
  SD.begin(chipSelect);

SD.begin() should be in setup() not in loop().

 #include <DS3231.h>
 DS3231 rtc(SDA, SCL);

You seem to use the library from Rinky Dink Electronics. I have no clue why this library is so often used as it's old and not well designed. I doubt that your RTC worked together with the LCD using that library as it uses the same pins as the I2C interface uses (which the LCD code needs) as digital I/Os (bit bang I2C). Use the library manager of the IDE, search for DS3231 and use one of the libraries there as they use I2C.

String wochenTagDT = "";
String wochenTagEN = "";

Eliminate the use of the String class. It fragments the memory and in no time you run out of it. Remember the SD library uses more than a quarter of the available RAM without having done anything. Also learn to use the F() macro to not waste memory for constant strings.

Sketch19:
To prepare for another data logging sketch, only the date and time should be written line by line to the SD card. As soon as the SPI.h library is included, SD.begin() reports 'SD initialization failed'.

This RTC3231-LCD-SD data logger shows current time on LCD at 1-sec interval; acquires RTC Temperature at 2-sec interval, and shows it on Serial Monitor with time stamp; the temperature is recorded on SD Card at 2-sec interval along with time stamp. This tutorial may help you trouble shooting your own data logger. (Codes could be added to show on Serial Monitor the recorded contents of SD Card when button K1 is pressed.)
rtc-lcd-sd.png

rtc-lcd-sdPIC.jpg

#include<SPI.h>     //sd cARD USES spi bUS
#include<SD.h>      //contains library functions
#define CSPIN 53    //if using DPin-4, it does not require to set direction
File myFile;        //file pointer variable declaration

#include <Wire.h>     //needed because DS3231 uses I2C Bus
#include <RTClib.h>   //needed becuase we have ready-made functions of this librray
RTC_DS3231 rtc;     //the object rtc is created from the class RTC_DS3231
char daysOfTheWeek[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
#define deviceAddress 0x68

#include<LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
byte x, x5, x6;
float rtcTemp;

void setup()
{
  Serial.begin(9600);
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//auto update from computer time
  //rtc.adjust(DateTime(2018, 12, 23, 9, 15, 17));//set date-time manualy:yr,mo,dy,hr,mn,sec
  lcd.init();
  lcd.backlight();
  //---------------------
  Serial.begin(9600);
  pinMode(CSPIN, OUTPUT);
  SD.begin(CSPIN);              //SD Card is initialized
  delay(2000);
  //  SD.remove("Imp21.txt");       //remove any existing file
}

void  loop()
{
  DateTime nowTime = rtc.now();
  x5 = nowTime.second();    //present second 23
  // Serial.println(x5, DEC);
  do
  {
    DateTime nowTime = rtc.now();
    x6 = nowTime.second();
    if (x6 == 0)
    {
      x5 = x6;
    }
    showTimeOnLCD();
  }
  while ((x6 - x5) != 2);
  rtcTemp = rtcTemperature();
  //nowTime = rtc.now();
  Serial.print(nowTime.hour());
  Serial.print(':');
  Serial.print(nowTime.minute());
  Serial.print(':');
  Serial.print(nowTime.second());
  Serial.print("  ");
  Serial.print("RTC Temp: ");
  Serial.print(rtcTemp, 2);
  Serial.println(" degC");
  rtcTempOnSD();              //store RTC temp on SD Card
}

void showTimeOnLCD()
{
  DateTime nowTime = rtc.now();
  lcd.setCursor(0, 0);
  lcd.print(daysOfTheWeek[nowTime.dayOfTheWeek()]);
  lcd.print(':');
  lcd.print("  ");
  lcd.print(nowTime.day(), DEC);
  lcd.print('/');
  lcd.print(nowTime.month(), DEC);
  lcd.print('/');
  lcd.print(nowTime.year(), DEC);
  //-------------------------
  lcd.setCursor(0, 1);
  lcd.print("Time: ");
  byte x2 = nowTime.hour();
  if (x2 < 10)
  {
    lcd.print('0');
  }
  lcd.print(nowTime.hour(), DEC);
  lcd.print(':');
  //---------------------
  byte x1 = nowTime.minute();
  if (x1 < 10)
  {
    lcd.print('0');
  }
  lcd.print(nowTime.minute(), DEC);
  lcd.print(':');
  //------------------------
  byte x = nowTime.second();
  if (x < 10)
  {
    lcd.print('0');
  }
  lcd.print(nowTime.second(), DEC);
  //---------------------------
}

float rtcTemperature()
{
  Wire.beginTransmission(0x68); //START, deviceAdr, data direction (write) are queued
  Wire.write(0x0E);//(0x0E);                     //Control Register Address is queued
  Wire.write(0x20);//(0x20);                     //Start Temperature Conversion command byte is queued
  Wire.endTransmission();               //queued information are transferred on ACK
  do
  {
    Wire.requestFrom(0x68, 1);   //command to the slave to send 1-byte data
    x = Wire.read();                      //data is read from FIFO buffer
  }
  while (bitRead(x, 5) != LOW);           //bit-5 of Control Register is LOW indicates end-of-conversion

  //--- read Temperature Signal----------------
  Wire.beginTransmission(0x68);  //
  Wire.write(0x11);                       //point higher byte of Temperature Register; queued
  Wire.endTransmission();                 //transfer the above queued information

  Wire.requestFrom(0x68, 2);       //request to send 2-byte data of Temperature Register
  float tempUpper = (float)Wire.read();    //integer part is saved as: XX.00000…….
  byte tempLower = Wire.read();            //fractional part as: XX000000

  float tempLowerx = (float) ((tempLower >> 7) * 0.5 + ((tempLower >> 6) & 0x01) * 0.250);
  float temp = tempLowerx + tempUpper;
  return temp;
}

void rtcTempOnSD()
{
  myFile = SD.open("Imp21.txt", FILE_WRITE);  //file created/opened for writing
  if (myFile)                                   //file has really been opened
  {
    DateTime nowTime = rtc.now();
    myFile.print(nowTime.hour());
    myFile.print(':');
    myFile.print(nowTime.minute());
    myFile.print(':');
    myFile.print(nowTime.second());
    myFile.print("  ");

    myFile.print("RTC Temp: ");
    myFile.println(rtcTemp);
  }
  else
  {
    Serial.println("File can't be opened");
    while (1);
  }
  myFile.close();
  //  myFile = SD.open("Imp21.txt", FILE_READ);  //file opened for reading

  // if (myFile)                                   //file has really been opened
  // {
  //   while (myFile.available())
  //  {
  //    Serial.print((char)myFile.read());
  //  }
  //  myFile.close();
  //}
}

rtc-lcd-sdPIC.jpg

rtc-lcd-sd.png

pylon, GolamMostafa, thanks a lot for your hints. We have weekend!, I will work on them !

Phew, it's working now!
And wow, it went fast.
As suggested I have other I2C libraries installed -> 'Rtc by Makuna' and 'DS3231'.
Then I went through the example and took all the instructions before the void setup() except for byte .. and float ...
For me the problem seems to be due to the DS3231 library from Rinky Dink Electrnoics indeed. Now date and time are written to the SD card.
The thing with the F() macro to save memory, I still have to practice.
But my core problem is solved.
Many Thanks Again!

Did Post#2 help you?