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);
}