I'm making an aquarium chiller using a Peltier device, and a water pump, which both run on 12VDC, I have an Arduino Nano and a DS18B20 temp sensor, simple push buttons, and a 1.9 i2C OLED. I have a 12V 15A 180W wall power supply. The peltier device and its fans are connected to an optoisolator relay, that is controlled by the nano on pin d4. The pump is just connected to the 12v directly. The OLED and Push buttons are on a separate shield brd. To power the Nano I have a 7805 circuit that connects to the +5v pin.
here's the code for the project:
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
const int relayPin = 4; // Output pin for D4 relay
const int hysteresis = 1; // Hysteresis value in degrees Fahrenheit
bool relayState = false; // Variable to keep track of D4 relay state
int set_temp = 60;
int temp;
// Set up I2C OLED screen
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
OneWire oneWire(A1); // Pin A1
DallasTemperature sensors(&oneWire);
void printText(const char* text, uint8_t size, uint8_t x, uint8_t y) {
display.setTextSize(size);
display.setTextColor(WHITE);
display.setCursor(x, y);
display.println(text);
display.display();
}
void getUP() {
if (set_temp < 70) {
set_temp++;
}
else {}
display.fillRect(10, 40, 48, 24, BLACK);
printText(String(set_temp).c_str(), 2, 10, 40);
display.display(); // Display the text on the screen
}
void getDWN() {
if (set_temp > 45) {
set_temp--;
}
else {}
display.fillRect(10, 40, 48, 24, BLACK);
printText(String(set_temp).c_str(), 2, 10, 40);
display.display(); // Display the text on the screen
}
void getTemp() {
sensors.requestTemperatures(); // Request temperature from sensor
temp = sensors.getTempFByIndex(0); // Get temperature value in Fahrenheit
display.fillRect(80, 40, 48, 24, BLACK);
printText(String(temp).c_str(), 2, 80, 40);
display.display(); // Display the text on the screen
}
void setup() {
pinMode(3, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
sensors.begin(); // Start temperature sensor
// Start I2C OLED screen
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
getTemp();
display.clearDisplay();
printText("WATER COOLING", 1, 20, 0);
printText("TEMP", 2, 64, 20);
printText("SET", 2, 0, 20);
printText(String(set_temp).c_str(), 2, 10, 40);
printText(String(temp).c_str(), 2, 80, 40);
display.display(); // Display the text on the screen
}
void loop() {
getTemp();
if (digitalRead(2) == LOW) {
getUP();
}
if (digitalRead(3) == LOW) {
getDWN();
}
if (relayState == false && temp > set_temp + hysteresis) {
digitalWrite(relayPin, HIGH); // Turn on D4 relay
relayState = true; // Update relay state
}
if (relayState == true && temp <= set_temp) {
digitalWrite(relayPin, LOW); // Turn off D4 relay
relayState = false; // Update relay state
}
}
The problem I have is when I power the system, the OLED displays the first temperature reading, and the set temperature, but pressing the push buttons does nothing, and the temperature reading does not change. However, if I keep the power on but plug a USB into the nano and restart it, it will work as expected for about 10-15 mins before going back to the condition described. I don't know if it's the power supply that is the issue, on the 5v pin I read 5.028vDC with a DMM, or if the code and an error that I'm overlooking. The problem is not just the OLED displaying the correct data, the system will not operate correctly, i.e. if the screen freezes with a set temp of 60 and a temp reading of 70 the relay will keep the Peltier device on regardless of the temp. It seems like it's somehow getting stuck in a loop. I am by no means a coder so it could be a very simple mistake. The part that baffles me is why it works for longer with the USB connection.
here is the wiring schematic
as you can see the OLED and push buttons are connected to a shield brd which can be seen here.
thanks for your help!