DS3234 + Arduino TFT screen using SPI

Hey folks! I have an Arduino Mega 2560, a DS3234 RTC, and an arduino TFT screen (this one: https://www.arduino.cc/en/Guide/TFT). They both work fine independently, but I’m having problems with the RTC when I connect the lcd screen as well. I’m not too familiar with SPI so I was wondering if someone here could help me with this issue.

The pin connections for RTC are:
CLK - 52
MISO - 50
MOSI - 51
SS - 44

for the lcd screen:
MISO - 50
SCK - 52
MOSI - 51
CS-LD - 28
DC-LD - 26
RESET - 24

If I understand correctly, the MISO, MOSI and CLK pins should be the same for both devices, only the chip select pin needs to be different. The devices that I want to communicate with needs to have its CS pin LOW, and the other device needs to have its HIGH.

I wrote a simple program that sets the RTC time, and displays the second. I have set the CS, DC and RESET pins for the display HIGH, but whenever I connect the display to the breadboard, both the minute and second value become 0. It starts working as soon as I remove the display.

Code:

#include <SPI.h>

int chipSelect = 44;
int intFreq = 3;

/*display pins*/
int cs = 28;
int dc = 26;
int rst = 24;

#define WRITE_CONTROL_REG 0x8E
#define READ_CONTROL_REG 0x0E
#define WRITE_TIME_REG 0x80
#define READ_TIME_REG 0x00

typedef struct 
{
 uint8_t ss;
 uint8_t mm;
 uint8_t hh;
 uint8_t dy;
 uint8_t d;
 uint8_t m;
 uint8_t y;
}timeParams;

void rtc_init(int chipSelect, int intFreq)
{
 /*
  * output frequencies:
  * 0: 1hz
  * 1: 1.024 kHz
  * 2: 4.096 kHz
  * 3: 8.192 kHz
  * 4: off
  */

 /*set up chip select pin*/
 pinMode(chipSelect, OUTPUT);
 //initialize comm
 digitalWrite(chipSelect, LOW);
 
 //Only change bit 2,3,4,6
 SPI.transfer(READ_CONTROL_REG);
 byte originalConfig = SPI.transfer(0x00);
 //end comm
 digitalWrite(chipSelect, HIGH);
 delay(10);

 byte configModifier;
 byte newConfig;

 //if intFreq is 4, turn square wave off
 if(intFreq == 4)
 {
   configModifier = 0b10111111;
   newConfig = configModifier & originalConfig;
 }
 else if (intFreq < 4)
 {
   configModifier = (intFreq << 3) | 0b01000000; // bit 6 has to be on
   newConfig = configModifier | (originalConfig & 0b11100011); //only change bits 2,3,4,6
 }

 digitalWrite(chipSelect, LOW);
 SPI.transfer(WRITE_CONTROL_REG);
 SPI.transfer(newConfig);
 digitalWrite(chipSelect, HIGH);
}

static uint8_t convertValGet(uint8_t value)
{
 uint8_t convertedValue = value - 6 * (value >> 4);
 return convertedValue; 
}

static uint8_t convertValSet(uint8_t value)
{
 uint8_t convertedValue = value + 6 * (value / 10);
 return convertedValue;
}

void setTime(int chipSelect, timeParams *timeVals)
{
 pinMode(chipSelect, OUTPUT);
 
 digitalWrite(chipSelect, LOW);
 SPI.transfer(WRITE_TIME_REG);
 SPI.transfer(convertValSet(timeVals->ss));
 SPI.transfer(convertValSet(timeVals->mm));
 SPI.transfer(convertValSet(timeVals->hh));
 SPI.transfer(convertValSet(timeVals->dy));
 SPI.transfer(convertValSet(timeVals->d));
 SPI.transfer(convertValSet(timeVals->m));
 SPI.transfer(convertValSet(timeVals->y));
 digitalWrite(chipSelect, HIGH);
 
 delay(10);
}

void getTime(int chipSelect, timeParams *timeVals)
{
 pinMode(chipSelect, OUTPUT);

 digitalWrite(chipSelect, LOW);
 SPI.transfer(READ_TIME_REG);
 timeVals->ss = convertValGet(SPI.transfer(READ_TIME_REG));
 timeVals->mm = convertValGet(SPI.transfer(READ_TIME_REG));
 timeVals->hh = convertValGet(SPI.transfer(READ_TIME_REG));
 timeVals->dy = convertValGet(SPI.transfer(READ_TIME_REG));
 timeVals->d = convertValGet(SPI.transfer(READ_TIME_REG));
 timeVals->m = convertValGet(SPI.transfer(READ_TIME_REG));
 timeVals->y = convertValGet(SPI.transfer(READ_TIME_REG));
 digitalWrite(chipSelect, HIGH);
 delay(10);
}

timeParams currentTime = {
 39,
 29,
 11,
 4,
 5,
 7,
 17
};

void setup() {
 // put your setup code here, to run once:
 pinMode(cs, OUTPUT);
 pinMode(dc, OUTPUT);
 pinMode(rst, OUTPUT);
 pinMode(chipSelect, OUTPUT);

 digitalWrite(cs, HIGH);
 digitalWrite(dc, HIGH);
 digitalWrite(rst, HIGH);
 
 SPI.begin();
 SPI.setBitOrder(MSBFIRST);
 SPI.setDataMode(SPI_MODE1);
 Serial.begin(9600);

 rtc_init(chipSelect, intFreq);
 setTime(chipSelect, &currentTime);



}

void loop() {
 // put your main code here, to run repeatedly:
 delay(1000);
 getTime(chipSelect, &currentTime);
 Serial.println(currentTime.ss);

}

What is it that I’m doing wrong here?

I found out that the RTC keeps count even though the LCD is connected, but displays 0. If I plug in the LCD at second 2, for 3 seconds, and unplug, the count resumes are 5.

Also found out that the problem is with the MISO pin. I tried plugging in each pin of the LCD individually, and found out that the MISO pin causes the time to be 0.

Since you're not even referencing the TFT code yet, I'd guess there's a wiring issue. Can you hook the TFT pins up one at a time until you find the offender?

Yeah, found out that the MISO pin was the culprit. Since the LCD will not be sending any data to the master, I disconnected that pin, and now the LCD and RTC work together fine :slight_smile: . However, I'm still curious as to why that happened, and if there is a software way to solve the issue.

Perhaps the idle states on each device’s MISO are at odds, one pulling high and the other low. Could that be mucking up the start condition, perhaps?