Lcd and sd card doesn't work at the same time

hello everyone,
i am pretty new to arduino, i'm trying to make a project for keeping 3d printer filaments in good condition. To do that i have to maintain the temperature and humidity of the wardrobe that has filaments in it i have dht 22, mks mini 12864 (basically a displayer &encoder & sd card slot), a custom pcb to work just like a arduino (atmega 2560) and 3d printer heater table. in my projects dht 22 reads the temp and hum in wardrobe i have thresholds and i also have threshold for heater bed (using ntc) to avoid overheating the heater. i adjust hum and temp just fine. and i display the datas on display, i also made a menu for changing the thresholds, i do it with rotary encoder. these works fine. so i understand every pin and wirings are also correct i wanted to log the datas every one hour to check later but the thing is i cant control sd card and displayer at the same time. They both work well at their own but even in easy projects like read from sd card and display it. they dont work. i dont really know what im doing wrong. i ask to my cs friend when im stuck but he said he doesnt know much anymore. thank you even if you read this much

#include <DHT.h>
#include <math.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <ST7565_LCD.h>
#include <Encoder.h>

// ST7565 LCD connection with Arduino board using software SPI
#define LCD_DIN    51
#define LCD_SCLK   52
#define LCD_A0     27
#define LCD_RESET  31
#define LCD_CS     25
ST7565_LCD display = ST7565_LCD(LCD_DIN, LCD_SCLK, LCD_A0, LCD_RESET, LCD_CS);

// DHT sensor and pins
#define DHTPIN 39
#define DHTTYPE DHT22
#define BED_PIN 8
#define THERMISTOR_PIN 84

// Thermistor constants
#define SERIES_RESISTOR 4700
#define NOMINAL_RESISTANCE 100000
#define NOMINAL_TEMPERATURE 25
#define B_COEFFICIENT 3950 

// Thresholds and constants
int tempThreshold = 30;  
int humThreshold = 30;   
#define MAX_BED_TEMP 60
#define HYSTERESIS 1.0 
#define PID_UPDATE_INTERVAL 2000 

// Rotary encoder pins
Encoder myEnc(31, 33);  
const int buttonPin = 35;  
const int sensitivity = 2; 

// Globals
DHT dht(DHTPIN, DHTTYPE);
unsigned long lastUpdateTime = 0;
long oldPosition = -999;
bool inAdjustMode = false;  
int adjustMode = 0;  
unsigned long lastInteractionTime = 0;

double readThermistor() {
    int analogValue = analogRead(THERMISTOR_PIN);

    if (analogValue == 0 || analogValue == 1023) {
        Serial.println("Analog value out of range!");
        displayError("Analog Value Error");
        return -999; 
    }

    double resistance = SERIES_RESISTOR / (1023.0 / analogValue - 1.0);
    double steinhart = resistance / NOMINAL_RESISTANCE;  // (R/Ro)
    steinhart = log(steinhart);  // ln(R/Ro)
    steinhart /= B_COEFFICIENT;  // 1/B * ln(R/Ro)
    steinhart += 1.0 / (NOMINAL_TEMPERATURE + 273.15);  // + (1/To)
    steinhart = 1.0 / steinhart;  // Invert
    steinhart -= 273.15;  // Convert to Celsius
    
    return steinhart;
}

void setup() {
    pinMode(BED_PIN, OUTPUT);
    pinMode(buttonPin, INPUT_PULLUP);
    dht.begin();
    Serial.begin(9600); 

    // Initialize the ST7565 LCD display
    display.begin(22);
    display.display();
    delay(2000); // Pause for 2 seconds

    display.clearDisplay();
    display.setTextSize(1);      
    display.setTextColor(ST7565_ON); 
    display.setCursor(25, 25);
    display.print("System Ready");
    display.display();
    delay(2000);
    showStartScreen();

    oldPosition = myEnc.read() / 4;
}  

void loop() {
    unsigned long currentTime = millis();

    static bool lastButtonState = HIGH;
    bool currentButtonState = digitalRead(buttonPin);

    if (currentButtonState == LOW && lastButtonState == HIGH) {
        delay(50);  // Debounce delay
        if (inAdjustMode) {
            adjustMode = (adjustMode + 1) % 2;  // Toggle between temperature and humidity adjustment
            showAdjustMode();
        } else {
            inAdjustMode = true;
            lastInteractionTime = currentTime;
            showAdjustMode();
        }
    }
    lastButtonState = currentButtonState;

    if (inAdjustMode) {
        long newPosition = myEnc.read() / 4;

        if (newPosition != oldPosition) {
            lastInteractionTime = currentTime;  // Reset interaction timer
            int change = (newPosition - oldPosition) * sensitivity;
            if (adjustMode == 0) {
                tempThreshold += change;
                tempThreshold = constrain(tempThreshold, 0, 100);
            } else {
                humThreshold += change;
                humThreshold = constrain(humThreshold, 0, 100);
            }
            oldPosition = newPosition;
            showAdjustMode();
        }

        if (currentTime - lastInteractionTime > 5000) {  // 5 seconds of inactivity
            inAdjustMode = false;
            showStartScreen();
        }
    } else {
        if (currentTime - lastUpdateTime >= PID_UPDATE_INTERVAL) {
            lastUpdateTime = currentTime;

            double bedTemp = readThermistor(); 
            float wardrobeTemp = dht.readTemperature();
            float humidity = dht.readHumidity();

            if (isnan(wardrobeTemp)) {
                Serial.println("Error: DHT sensor failed to read temperature! Turning off heater.");
                analogWrite(BED_PIN, 0); 
                displayError("Temp Reading Error");
                return;
            }

            if (isnan(humidity)) {
                Serial.println("Error: DHT sensor failed to read humidity! Turning off heater.");
                analogWrite(BED_PIN, 0); 
                displayError("Humidity Reading Error");
                return;
            }
            
            if (bedTemp == -999) {
                Serial.println("Error: Thermistor reading failed! Turning off heater.");
                analogWrite(BED_PIN, 0); 
                displayError("Thermistor Reading Error");
                return;
            } 

            Serial.print("   ntc:"); 
            Serial.print(bedTemp);
            Serial.print(" °C");

            Serial.print("   tempt:");
            Serial.print(wardrobeTemp);
            Serial.print(" °C");

            Serial.print("   Humidity:");
            Serial.print(humidity);
            Serial.print(" %");

            double error = MAX_BED_TEMP - bedTemp;
            double heaterOutput = 0;
            String heaterStatus = "OFF";
            String message = "";

            if (wardrobeTemp >= tempThreshold) {
                heaterOutput = 0; 
                heaterStatus = "OFF";
                message = "WARDROBE TEMP HIGH";
                Serial.println("   !!!WARDROBE TEMPERATURE IS TOO HIGH HEATER OFF!!!");
            } else if (humidity > humThreshold) {
                if (bedTemp < (MAX_BED_TEMP - HYSTERESIS)) {
                    heaterOutput = min(255, 255 * (error / HYSTERESIS)); 
                    heaterStatus = "ON ";
                    message = "HUMIDITY HIGH";
                } else {
                    heaterOutput = 0; 
                    heaterStatus = "OFF";
                    message = "HUMIDITY HIGH ";
                }
                Serial.println("   !!!HIGH HUMIDITY DETECTED ADJUSTING THE HEATER!!!");
            } else if (bedTemp >= MAX_BED_TEMP) {
                heaterOutput = 0; 
                heaterStatus = "OFF";
                message = "MAX BED TEMP";
                Serial.println("   !!!BED TEMPERATURE REACHED TO MAX HEATER!!!");
            } else {
                heaterOutput = 0; 
                heaterStatus = "OFF";
                message = "HUMIDITY OK";
                Serial.println("   !!!HUMIDITY IS WELL FOR ENVIRONMENT!!!");
            }

            analogWrite(BED_PIN, heaterOutput);
            displayData(bedTemp, wardrobeTemp, humidity, heaterStatus, message);
        }
    }
}

void showStartScreen() {
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(ST7565_ON);
    display.setCursor(0, 0);
    display.print("Temp: "); display.print(tempThreshold); display.println(" C");
    display.print("Hum: "); display.print(humThreshold); display.println(" %");
    display.print("Click to Adjust");
    display.display();
}

void showAdjustMode() {
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(ST7565_ON);
    display.setCursor(0, 0);
    display.println("Adjust Mode");
    if (adjustMode == 0) {
        display.print("> Temp: ");
        display.print(tempThreshold);
        display.println(" C");
        display.print("  Hum: ");
        display.print(humThreshold);
        display.println(" %");
        Serial.print("Adjusted Temp Threshold: "); Serial.println(tempThreshold);
        Serial.print("Adjusted Humidity Threshold: "); Serial.println(humThreshold);
    } else {
        display.print("  Temp: ");
        display.print(tempThreshold);
        display.println(" C");
        display.print("> Hum: ");
        display.print(humThreshold);
        display.println(" %");
        Serial.print("Adjusted Temp Threshold: "); Serial.println(tempThreshold);
        Serial.print("Adjusted Humidity Threshold: "); Serial.println(humThreshold);
    }
    display.setCursor(0, 30);
    display.print("Press to Switch");
    display.display();
}


void displayData(double bedTemp, float wardrobeTemp, float humidity, String heaterStatus, String message) {
    display.clearDisplay();
    display.setCursor(0, 0);
    display.setTextSize(1);

    display.print("Bed Temp: "); display.print(bedTemp); display.println(" C");
    display.print("Temp: "); display.print(wardrobeTemp); display.println(" C");
    display.print("Humidity: "); display.print(humidity); display.println(" %");
    display.print("Heater: "); display.println(heaterStatus);

    display.setTextSize(1);
    display.setCursor(0, 40);
    display.print(message);

    display.display();
}

void displayError(const char* errorMsg) {
    display.clearDisplay();
    display.setCursor(0, 0);
    display.setTextSize(2);
    display.setTextColor(ST7565_ON);
    display.println("ERROR:");
    display.setTextSize(1);
    display.println(errorMsg);
    display.display();
    delay(2000);
}

There is a commonly used SD card adapter that does not work with other SPI devices on the same SPI bus.

Screenshot - 02_09_2024 , 14_55_38

thank you for replying but i don't think it's the one that i have because i know even on 3d printers they use this mks mini display, which means it probably read and write to sd -maybe not writing :,(-

You dont think ?

it's not this one MKS MINI 12864 - RepRap please see this

if the SD card is sharing a SPI bus with other devices there can be problems, see Sharing the SPI bus among SD card and other SPI devices
what microcontroller are you using?

a way to overcome the problem is to use a microcontroller with two SPI interfaces, e.g. ESP32

i use atmega 2560

Can you produce a schematic diagram ?

i got the pin numbers from pins_ramps file and try them with libraries example files. but i found the schematic
MKS MINI12864 V3.0_001 SCH.pdf (123.4 KB)

   #define MISO_PIN      50  // system defined - only needed if using onboard SD card
   #define MOSI_PIN      51  // system defined
   #define SCK_PIN       52  // system defined
   #define SDSS          53  // only needed if using onboard SD card

   #define BEEPER_PIN    37

   #define BTN_EN1       31
   #define BTN_EN2       33
   #define BTN_ENC       35

   #define KILL_PIN      41  // optional

   #define SD_DETECT_PIN 49  // only needed if using onboard SD card

   #define DOGLCD_CS     25
   #define DOGLCD_A0     27

Interesting that , I had a situation with an oled display and 2515 CAN controller that would not work together .

i also thought it could be the same issue here but since they are attached together i couldn't be so sure, they use different ss pins

You've supplied a schematic of the MKS mini 12864 RepRap board but not shown the wiring diagram between the headers of that board and the atmega 2560. Also your sketch in your first post does not (or maybe I missed it) show any attempt to include an SD card reader and further, in that sketch, you are using many more pins for your display than in the sample pin allocation.in post #9. There is at least one pin clash, though (see post #8) . Can you also show the basic sketch you use to verify that the SD card reader works without the display.

yes thank you i found actual reset pin is 23 through this pin file
pins_RAMPS.h (28.0 KB)

yes that part is only the working part for now after i make changes for it to log datas it doesn't work properly. here's the basic example of me trying them both work at the same time. when i upload the code while sd is plugged in, sd work but display doesnt .

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <ST7565_LCD.h>
#include <SD.h>

#define LCD_DIN    51
#define LCD_SCLK   52
#define LCD_A0     27
#define LCD_RESET  23
#define LCD_CS     25

#define SDSS       53  
#define SD_DETECT_PIN 49  

ST7565_LCD display = ST7565_LCD(LCD_DIN, LCD_SCLK, LCD_A0, LCD_RESET, LCD_CS);

void setup() {
    Serial.begin(9600);
    
    pinMode(SD_DETECT_PIN, INPUT_PULLUP);
    pinMode(LCD_CS, OUTPUT);
    pinMode(SDSS, OUTPUT); 

    digitalWrite(LCD_CS, HIGH); 
    digitalWrite(SDSS, HIGH); 

    if (digitalRead(SD_DETECT_PIN) == HIGH) {
        Serial.println("SD card not detected!");
        displayText("SD not detected");
        return;
    }

    if (!SD.begin(SDSS)) { 
        Serial.println("SD card initialization failed!");
        displayText("SD init failed");
        return;
    }

    Serial.println("SD card initialized.");
    displayText("SD initialized");
}

void displayText(const char* text) {
    digitalWrite(LCD_CS, LOW); // Enable LCD CS
    delay(10); 

    display.begin(22);
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(ST7565_ON);
    display.setCursor(25, 25);
    display.print(text);
    display.display();

    digitalWrite(LCD_CS, HIGH); // Disable LCD CS
}

void sdsd(const char* text) {
    if (digitalRead(SD_DETECT_PIN) == HIGH) {
        Serial.println("SD card not detected");
        displayText("SD not detected");
        return;
    }
    
    digitalWrite(SDSS, LOW); // Enable SD card CS
    delay(10); 
    
    File myFile = SD.open("testxx.txt", FILE_WRITE);
    if (myFile) {
        Serial.print("Writing to testxx.txt");
        myFile.println(text);
        myFile.close();
        Serial.println("done.");
        displayText("Data written");
    } else {
        Serial.println("Error opening testxx.txt");
        displayText("Write error");
    }
    
    digitalWrite(SDSS, HIGH); // Disable SD card CS
    delay(10); 
}

void loop() {
    const char* text = "example";
    displayText(text);
    delay(1000);
    sdsd(text);
    delay(1000);
}

i couldn't find that schematic on their github. but here's the schematic of the pcb that i'm using
xxx.pdf (1.5 MB)

From your code in #13

From your board schematics:

Looking at the matching header pin pairs, I'd have said that D25 is labelled R/W (Exp1 (6) / J84 (6) and not a CS pin.

The CS (chip select sometimes called SS for slave select) pins are important in SPI to prevent two devices grabbing the bus simultaneously. I can't see from the name whether CS2 belongs to an SD card reader or the display.
Is this pin in the code above #define SDSS 53 the SD card's "CS" pin (SS sounds like slave select). Anyway, PIN 53 appears to be allocated to "SD_CMD"

i got the 25 pin from here

yeah its sd chip select pin. i also got this one from pin_ramps file
i would like to try the pins you think it would work as you said something might be wrong with chip select pins so spi wouldn't work because of that. There's a thing like that in pin_ramps file, i don't know if it's something important:

   *               Board                            Display
   *               ------                           ------
   *    (MISO) 50 | 1  2 | 52 (SCK)             5V |10  9 | GND
   *  (LCD_CS) 33 | 3  4 | 53 (SD_CS)        RESET | 8  7 | (SD_DET)
   *           31   5  6 | 51 (MOSI)        (MOSI)   6  5 | (LCD_CS)
   *  (SD_DET) 49 | 7  8 | RESET           (SD_CS) | 4  3 | (MOD_RESET)
   *          GND | 9 10 | --                (SCK) | 2  1 | (MISO)
   *               ------                           ------
   *                EXP2                             EXP1

I think it is time for a review.

You have a device MKS MINI 12864 - RepRap 7.It has a display, a couple of SD card readers and others. It has two 10 pin header blocks which break out all the necessary pins to use these peripheral devices.

You have made/obtained a pcb board which has an embedded ATmega2560 and sockets corresponding to the two 10 pin headers on the MKS MINI 12864 - RepRap 7. It also has other components like motor drivers.

Now we have to follow through from the display and the SD card readers through the two ten pin headers to the ATmega2560 then to the code to ensure manipulating a pin on the Arduino, for example the pin controlling the CS (Chip select) on the display really gets through to the display.

The two 10 pin headers on what you have said is the schematic of MKS MINI 12864 - RepRap 7 are labelled EXP1 and EXP2.

Q1: Do you make any other connections to the MKS MINI 12864 - RepRap 7 apart from those through the two 10 pin headers ?
Q2: Which SD card reader are you using on that board, the one marked SD1 or SD2 ?

It appears that SD1 can be shared with the display. The mapping between the display and SD1 pins can be seen on the level shifter U5.

Here is one example of a mapping error. I believe that the CS pin for the display should be 17 and not 25.

The logic is this:
LCD_EN in (red 3) maps to LCD_CS in (red 4) [ at the level shifter] so is likely to be the CS pin for the display.
The position of LCD_EN (in red 3) [also EXP1 pin3] maps to Arduino Pin D17 (red 1).
LCD_CS in code snippet (red 5) says pin D25 (not D17) so something is wrong, possibly with the documentation.

I suggest you try with the stand alone sketch which writes to the display and change the CS pin to 17. If it doesn't work the follow the logic back to find out where the error is. If it is documentation, and you are still having problems, then you have to correct the documentation to match the real situation.

The last diagram you supplied is difficult to use because header EXP1 has been rotated 180 degrees and interchanged with the position of EXP2.