#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define Info 4 //Info-Taster auf digital Pin 8 (extern Pullup!)
#define PWM_FAN 3 // Pin to control the PWM signal for the fan
const int pwmMin = 0; // Minimum PWM value (0% duty cycle)
const int pwmMax = 255; // Maximum PWM value (100% duty cycle)
const float tempMin = 35.00; // Lower temperature threshold in Celsius
const float tempMax = 70.00; // Upper temperature threshold in Celsius
const float TempOff = 120.00; // value for TempOff
const float Amps1 = 0.00; // value for Amps1
const float Amps2 = 0.00; // value for Amps2
const float AmpsOff = 4.50; // value for AmpsOff
const float Volt1 = 0.00; // value for Volt1
const float Volt2 = 0.00; // value for Volt2
const int DS18B20 = 2; // GPIO where the DS18B20 is connected to (extern Pullup!)
OneWire oneWire(DS18B20); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature sensor
const int momentarySwitchPin = 8; // Arduino pin connected to button's pin (extern Pullup!)
const int latchingSwitchInputPin = 8;
const int latchingSwitchOutputPin = 7; // Arduino pin connected to relay's pin
int switchState = HIGH; // Variables to store switch states
int lastSwitchState = HIGH; // Variables to store switch states
int latchingSwitchState = LOW; // Variables to store switch states
const int lcdAddress1 = 0x27; // Replace with the actual I2C address of LCD 1
const int lcdAddress2 = 0x28; // Replace with the actual I2C address of LCD 2
LiquidCrystal_I2C lcd1(lcdAddress1, 20, 4); // I2C LCD display address 0x27, 20 column and 4 rows (extern Pullup!)
LiquidCrystal_I2C lcd2(lcdAddress2, 20, 4); // I2C LCD display address 0x28, 20 column and 4 rows (extern Pullup!)
const int state_red = 11; // RGB Status LED Pin red
const int state_green = 10; // RGB Status LED Pin green
const int state_blue = 9; // RGB Status LED Pin blue
const int IO_red = 6; // RG I/O LED Pin red
const int IO_green = 5; // RG I/O LED Pin green
byte fan[8] = { // Symbol Fan for LCD
0b00000,
0b11001,
0b01011,
0b00100,
0b11010,
0b10011,
0b00000,
0b00000
};
byte temp[8] = { // Symbol Temp for LCD
0b10100,
0b00101,
0b10100,
0b00101,
0b10100,
0b01110,
0b01010,
0b01110
};
byte pm[8] = { // Symbol +/- for LCD
0b00000,
0b00100,
0b01110,
0b00100,
0b00000,
0b01110,
0b00000,
0b00000
};
void setup(void)
{
Serial.begin(9600); // initialize serial monitor
pinMode(state_red, OUTPUT);
pinMode(state_green, OUTPUT);
pinMode(state_blue, OUTPUT);
pinMode(IO_red, OUTPUT);
pinMode(IO_green, OUTPUT);
pinMode(Info, INPUT); // Set info switch pin as INPUT (extern Pullup!)
pinMode(momentarySwitchPin, INPUT); // Set the momentary switch pin as INPUT
pinMode(latchingSwitchInputPin, INPUT); // Set the latching switch input pin as INPUT
pinMode(latchingSwitchOutputPin, OUTPUT); // Set the latching switch output pin as OUTPUT
pinMode(PWM_FAN, OUTPUT); // Set PWM_FAN pin as OUTPUT
sensors.begin(); // Start the DS18B20 sensor
lcd1.init(); // initialize the LCD1
lcd2.init(); // initialize the LCD2
lcd1.backlight(); // turn on backlight LCD1
lcd2.backlight(); // turn on backlight LCD2
lcd1.clear(); // clear display LCD1
lcd2.clear(); // clear display LCD2
lcd1.setCursor(0,0); // move cursor to (0, 0) LCD1
lcd2.setCursor(0,0); // move cursor to (0, 0) LCD2
lcd1.createChar(0, fan); // create symbol fan on LCD1
lcd1.createChar(1, temp); // create symbol temp on LCD1
lcd1.createChar(2, pm); // create symbol +/- on LCD1
lcd2.createChar(0, fan); // create symbol fan on LCD2
lcd2.createChar(1, temp); // create symbol temp on LCD2
lcd2.createChar(2, pm); // create symbol temp on LCD2
lcd1.setCursor(0,0); // tell the LCD1 to write on the top row
lcd1.print("-----<STARTING>-----");
lcd1.setCursor(0,1);
lcd1.print(" This may take a ");
lcd1.setCursor(0,2);
lcd1.print(" few Moment ");
lcd1.setCursor(0,3);
lcd1.print(" Please wait... ");
lcd2.setCursor(0,0); // tell the LCD2 to write on the top row
lcd2.print("-----<STARTING>-----");
lcd2.setCursor(0,1);
lcd2.print(" This may take a ");
lcd2.setCursor(0,2);
lcd2.print(" few Moment ");
lcd2.setCursor(0,3);
lcd2.print(" Please wait... ");
delay(2000); // display the above for 0,5 second
lcd1.clear(); // clear display LCD1
lcd2.clear(); // clear display LCD2
}
void loop(void)
{
int pwmValue = 0; // set pwmValue as integer = 0
analogWrite(PWM_FAN, pwmValue); // set fan speed
int rmpFan = 0; // set rmpFan as integer = 0
sensors.requestTemperatures(); // to issue a global temperature and Requests to all devices on the bus
float Temp = sensors.getTempCByIndex(0); // set read temperature in float Temp
if (Temp >= tempMin && Temp <= tempMax) { // check if temperature is within the desired range
state_color(1,1,0);
int pwmValue = map(Temp, tempMin, tempMax, pwmMin, pwmMax); // map temperature to PWM range
analogWrite(PWM_FAN, pwmValue); // control fan speed using PWM
rmpFan = map(pwmValue, pwmMin, pwmMax, 0, 100); // fan speed in %
Serial.print("Temperature: "); // output in serial console
Serial.print(Temp); // output Temp in serial console
Serial.print(" °C, Fan Speed: "); // output in serial console
Serial.println(rmpFan); // output fan speed in % in serial console
}
if (Temp <= tempMin) { // check if temperature is lower the desired range
state_color(0,1,0);
int pwmValue = 0; // set pwmValue = 0
rmpFan = 0; // set rmpFan = 0
analogWrite(PWM_FAN, pwmValue); // control fan speed using PWM
Serial.print("Temperature: "); // output in serial console
Serial.print(Temp); // output Temp in serial console
Serial.print(" °C, Fan Speed: "); // output in serial console
Serial.println(rmpFan); // output fan speed in % in serial console
}
if (Temp >= tempMax) { // check if temperature is higher the desired range
state_color(1,0,0);
int pwmValue = 255; // set pwmValue = 255
rmpFan = 100; // set rmpFan = 100
analogWrite(PWM_FAN, pwmValue); // control fan speed using PWM
Serial.print("Temperature: "); // output in serial console
Serial.print(Temp); // output Temp in serial console
Serial.print(" °C, Fan Speed: "); // output in serial console
Serial.println(rmpFan); // output fan speed in % in serial console
}
if (Temp >= TempOff) {
state_color(1,0,0);
latchingSwitchState = LOW; // toggle the state of the latching switch
digitalWrite(latchingSwitchOutputPin, latchingSwitchState); // set states
lcd1.clear(); // clear display LCD1
lcd2.clear(); // clear display LCD2
delay(100); // wait for 0,5 seconds
lcd1.setCursor(0,0); // tell the LCD1 to write on the top row
lcd1.print("OVERHEAT PROTECTION");
lcd1.setCursor(0,1);
lcd1.print(" Temp. above 120 ""\xDF""C ");
lcd1.setCursor(0,2);
lcd1.print(" Power supply was ");
lcd1.setCursor(0,3);
lcd1.print(" switched off !!!");
lcd2.setCursor(0,0); // tell the LCD2 to write on the top row
lcd2.print(" OVERHEAT PROTECTION");
lcd2.setCursor(0,1);
lcd2.print("Don't press the main");
lcd2.setCursor(0,2);
lcd2.print("switch while the fan");
lcd2.setCursor(0,3);
lcd2.print(" is running !!!");
delay(2000); // wait for 2 seconds
}
switchState = digitalRead(momentarySwitchPin); // read the state of the momentary switch
if (switchState == HIGH && lastSwitchState == LOW) { // check for a rising edge (transition from LOW to HIGH) on the momentary switch
latchingSwitchState = !latchingSwitchState; // toggle the state of the latching switch
digitalWrite(latchingSwitchOutputPin, latchingSwitchState); // set states
}
lastSwitchState = switchState; // update the last switch state
if (latchingSwitchState == HIGH){
IO_color(0,1);
}
else{
IO_color(1,0);
}
int zustandInfo = digitalRead(Info); // read state taster
if (zustandInfo == HIGH && Temp <= TempOff // if not pushed (HIGH) und Temp, Amps1, Amps2 kleine als [....]Off
&& Amps1 <= AmpsOff && Amps2 <= AmpsOff) {
lcd1.setCursor(0,0); // tell the LCD1 to write on the top row
lcd1.print("-----<OUTPUT 1>-----");
lcd1.setCursor(0,1);
lcd1.print(" VOLTAGE: 05.00 V");
lcd1.setCursor(0,2);
lcd1.print(" CURRENT: 04.00 A");
lcd1.setCursor(0,3);
lcd1.print(" POWER: 20.00 W ");
lcd2.setCursor(0,0); // tell the LCD2 to write on the top row
lcd2.print("-----<OUTPUT 2>-----");
lcd2.setCursor(0,1);
lcd2.print(" VOLTAGE: -05.00 V");
lcd2.setCursor(0,2);
lcd2.print(" CURRENT: 04.00 A");
lcd2.setCursor(0,3);
lcd2.print(" POWER: 20.00 W ");
}
if (zustandInfo == LOW && Temp <= TempOff // if pushed (LOW) und Temp, Amps1, Amps2 kleine als [....]Off
&& Amps1 <= AmpsOff && Amps2 <= AmpsOff) {
state_color(0,0,1);
lcd1.clear(); // clear display LCD1
lcd1.setCursor(0,0); // tell the LCD1 what to write on the rows an cells
lcd1.print("------<INPUT>-------");
lcd1.setCursor(0,1);
lcd1.print(" VOLTAGE: 225.00 V");
lcd1.setCursor(0,2);
lcd1.print(" CURRENT: 12.00 A");
lcd1.setCursor(0,3);
lcd1.print(" POWER: 2700.00 W ");
lcd2.clear(); // clear display LCD2
lcd2.setCursor(0,0); // tell the LCD2 what to write on the rows an cells
lcd2.print("---<INFORMATIONS>---");
lcd2.setCursor(0,1);
lcd2.print("HW: ");
lcd2.write(byte(2));
lcd2.print("5V4AF-V1.0");
lcd2.setCursor(0,2);
lcd2.print("SW: V1.0-11.09.2024");
lcd2.setCursor(0,3);
lcd2.write(byte(0));
char displayFan[3]; // create Char with 3 signs
uint8_t temFan = rmpFan; // convert int rmpFan in unsigned int 58 bit
sprintf(displayFan, "%3u", temFan); // placeholder for 3 signs, empty signs filled with space character
lcd2.setCursor(2,3);
lcd2.print(displayFan);
lcd2.setCursor(6,3);
lcd2.print("%");
lcd2.setCursor(9,3);
lcd2.write(byte(1));
char displayTemp[6]; // create Char with 6 signs
int Temp_int = (int) Temp; // convert
float Temp_float = (abs(Temp) - abs(Temp_int)) * 100; // convert
int Temp_fra = (int)Temp_float; // convert
sprintf (displayTemp, "%3d.%2d", Temp_int, Temp_fra); //placeholder for 3 signs bevor "." and 2 signs after ".", empty signs filled with space character
lcd2.setCursor(11,3);
lcd2.print(displayTemp);
lcd2.setCursor(18,3);
lcd2.print("\xDF""C");
delay(3000); // wait for 3 seconds
lcd2.setCursor(0,1); // tell the LCD2 what tooverwrite on the rows an cells
lcd2.print("BUILD: 11.09.2024-MS");
lcd2.setCursor(0,2);
lcd2.print("SN: 102024-MS-x001");
delay(3000); // wait for 3 seconds
}
}
void IO_color(int red_value, int green_value)
{
digitalWrite(IO_red,red_value);
digitalWrite(IO_green,green_value);
}
void state_color(int red_value, int green_value, int blue_value)
{
digitalWrite(state_red,red_value);
digitalWrite(state_green,green_value);
digitalWrite(state_blue,blue_value);
}