// Includes:
#include <DMXSerial.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
// Variables:
int PumpState = LOW; // State of the pump output pin
int PumpPWM = 0; // Output value of the pump, ranging from 0 to 25
int FanPWM = 0; // Output value of the fan, ranging from 0 to 255
int startChannel = 1; // DMX Address
int FanDefaultLevel = 26; // Default fan level when no DMX signal is received
int PumpDefaultLevel = 0; // Default pump level when no DMX signal is received
unsigned long previousMillis = 0; // Stores the last time pin was updated
unsigned long previousMillisDmx = 0;
int DMXflash = 0;
int StateUp = 0; // State of the up button
int StateDown = 0; // State of the down button
int StateMenu = 0; // State of the menu button
int StateOK = 0; // State of the OK button
int MenuActive = 0; // Handler for configuration function (99 for debug, 0 for normal)
int MenuChange = 0; // Handler for display clearing
int Debug = 0; // Debug value handler
int FirstSave = 0; // Handler for first configuration of EEPROM
int SaveSettings = 0; // Handler for EEPROM update
byte AddByte0 = 0; // First address byte
byte AddByte1 = 0; // Second address byte
int DMXNotactive = 0; // Handler for active DMX signal
int ThermostatActive = 0; // Handler for thermostat input
int HeaterActive = 1; // Handler for heater control
int HeaterTimeout = 1; // Block pump
unsigned long ThermostatTime = 0;
// Constants:
const int FanPin = 3; // PWM output pin for the fan.
const int PumpPin = 13; // The number of the pump pin
const int UpPin = 6; // Pin for the up-button
const int DownPin = 5; // Pin for the down-button
const int MenuPin = 4; // Pin for the Menu button
const int OKPin = 2; // Pin for the OK button
const int maxoutput = 25; // Maximum value for the pump output variable
const long increment = 20; // Increment in on-time (Duty Cycle)
const int rs = 12, en = 11, d4 = 10, d5 = 9, d6 = 8, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int Buttondelay = 100;
const int AddDMX = 0; // Takes up two bytes
const int AddFan = 2;
const int AddPump = 3;
const int AddFirst = 4;
const unsigned long HeaterTimeouttime = 120000; // 3 minutes timeout
void setup() {
// Initialize LCD
lcd.begin(16, 2); // Set up the LCD's number of columns and rows
lcd.print("Initializing");
lcd.setCursor(0, 1);
lcd.print("SnoerFZ V1.0");
// Initialize DMX
DMXSerial.init(DMXReceiver);
// Set pins
pinMode(FanPin, OUTPUT); // Sets the fan pin as output
pinMode(PumpPin, OUTPUT); // Sets the pump pin as output
pinMode(A0, OUTPUT);
pinMode(UpPin, INPUT_PULLUP);
pinMode(DownPin, INPUT_PULLUP);
pinMode(MenuPin, INPUT_PULLUP);
pinMode(OKPin, INPUT_PULLUP);
pinMode(A0, OUTPUT);
pinMode(A1, INPUT_PULLUP);
// Set defined state
digitalWrite(PumpPin, 0);
digitalWrite(A0, 1);
analogWrite(FanPin, 0);
// Read settings
FirstSave = EEPROM.read(AddFirst);
if (FirstSave < 255) {
AddByte0 = EEPROM.read(AddDMX);
AddByte1 = EEPROM.read(AddDMX + 1);
FanDefaultLevel = EEPROM.read(AddFan);
PumpDefaultLevel = EEPROM.read(AddPump);
startChannel = AddByte0 * 256 + AddByte1;
}
// Finish setup
delay(2000);
lcd.clear();
}
void loop() {
// Handle DMX
unsigned long lastPacket = DMXSerial.noDataSince();
if (lastPacket < 5000) {
FanPWM = DMXSerial.read(startChannel);
PumpPWM = (DMXSerial.read(startChannel + 1) / 10);
DMXNotactive = 0;
} else {
FanPWM = FanDefaultLevel;
PumpPWM = (PumpDefaultLevel / 10);
DMXNotactive = 1;
}
// Handle PWM
unsigned long Ontime = PumpPWM * increment;
unsigned long Offtime = (maxoutput - PumpPWM) * increment;
unsigned long currentMillis = millis();
if (PumpPWM < 1) {
PumpState = LOW;
} else if (PumpPWM > 24) {
PumpState = HIGH;
} else {
if (currentMillis - previousMillis <= Ontime) {
PumpState = HIGH;
} else if ((currentMillis - previousMillis >= Ontime) && (currentMillis - previousMillis <= ( Offtime + Ontime ))) {
PumpState = LOW;
} else if (currentMillis - previousMillis >= (Ontime + Offtime)) {
previousMillis = currentMillis;
}
}
// Handle Heater
ThermostatActive = !digitalRead(A1);
if (ThermostatActive == 0){
ThermostatTime = millis();
}
if ((millis() - ThermostatTime) > HeaterTimeouttime){
HeaterTimeout = 1;
} else {
if (HeaterTimeout == 1) {
MenuChange = 1;
}
HeaterTimeout = 0;
}
HeaterActive = !ThermostatActive;
// Write outputs:
if (HeaterTimeout == 0){
digitalWrite(PumpPin, PumpState);
}
analogWrite(FanPin, FanPWM);
digitalWrite(A0, HeaterActive);
// Handle inputs:
StateUp = !digitalRead(UpPin);
StateDown = !digitalRead(DownPin);
StateMenu = !digitalRead(MenuPin);
StateOK = !digitalRead(OKPin);
// Handle Menu Selection
if ((StateMenu > 0) && (MenuActive == 0)) {
delay(Buttondelay);
MenuActive = 1;
MenuChange = 1;
} else if ((StateMenu > 0) && (MenuActive == 1)) {
delay(Buttondelay);
MenuActive = 2;
MenuChange = 1;
} else if ((StateMenu > 0) && (MenuActive == 2)) {
delay(Buttondelay);
MenuActive = 3;
MenuChange = 1;
} else if ((StateMenu > 0) && (MenuActive == 3)) {
delay(Buttondelay);
MenuActive = 0;
MenuChange = 1;
} else if ((MenuActive > 0) && (StateOK > 0)) {
delay(Buttondelay);
SaveSettings = 1;
MenuActive = 4;
MenuChange = 1;
}
// Handle Menu Function
if (MenuActive == 1) { // DMX
if ((StateUp > 0) && (StateDown < 1)) {
if (startChannel < 511) {
startChannel = startChannel + 1;
} else {
startChannel = 1;
}
MenuChange = 1;
delay(Buttondelay);
} else if ((StateUp < 1) && (StateDown > 0)) {
if (startChannel > 1 ) {
startChannel = startChannel - 1;
} else {
startChannel = 511;
}
MenuChange = 1;
delay(Buttondelay);
}
AddByte0 = startChannel / 256;
AddByte1 = startChannel % 256;
} else if (MenuActive == 2) { // Fan
if ((StateUp > 0) && (StateDown < 1)) {
if (FanDefaultLevel < 255 ) {
FanDefaultLevel = FanDefaultLevel + 1;
} else {
FanDefaultLevel = 0;
}
MenuChange = 1;
delay(Buttondelay);
} else if ((StateUp < 1) && (StateDown > 0)) {
if (FanDefaultLevel > 0 ) {
FanDefaultLevel = FanDefaultLevel - 1;
} else {
FanDefaultLevel = 255;
}
MenuChange = 1;
delay(Buttondelay);
}
} else if (MenuActive == 3) { // Pump
if ((StateUp > 0) && (StateDown < 1)) {
if (PumpDefaultLevel < 255) {
PumpDefaultLevel = PumpDefaultLevel + 1;
} else {
PumpDefaultLevel = 0;
}
MenuChange = 1;
delay(Buttondelay);
} else if ((StateUp < 1) && (StateDown > 0)) {
if (PumpDefaultLevel > 0 ) {
PumpDefaultLevel = PumpDefaultLevel - 1;
} else {
PumpDefaultLevel = 255;
}
MenuChange = 1;
delay(Buttondelay);
}
}
// Handle EEPROM update:
if (SaveSettings == 1) {
EEPROM.update(AddFirst, 0);
EEPROM.update(AddDMX, AddByte0);
EEPROM.update(AddDMX + 1, AddByte1);
EEPROM.update(AddFan, FanDefaultLevel);
EEPROM.update(AddPump, PumpDefaultLevel);
SaveSettings = 0;
}
// Handle Display:
// Display clear
if (MenuChange == 1) {
lcd.clear();
MenuChange = 0;
}
// Menu handler
if (MenuActive < 1) {
lcd.setCursor(0, 0);
lcd.print("SnoerFZ");
if (DMXNotactive == 1) {
unsigned long currenttimedmxflash = millis();
if (currenttimedmxflash - previousMillisDmx >= 1000 ) {
previousMillisDmx = currenttimedmxflash;
if (DMXflash == 0 ) {
lcd.setCursor(8, 0);
lcd.print("No DMX");
DMXflash = 1;
} else {
lcd.setCursor(8, 0);
lcd.print(" ");
DMXflash = 0;
}
}
} else {
lcd.setCursor(8, 0);
lcd.print("DMX:");
lcd.setCursor(13, 0);
lcd.print(startChannel);
}
int FanPWMPrint = (FanPWM / 2.54);
lcd.setCursor (0, 1);
lcd.print("Fan:");
lcd.setCursor(4, 1);
lcd.print(FanPWMPrint);
int PumpPWMPrint = (PumpPWM * 4);
if (HeaterTimeout == 0){
lcd.setCursor (8, 1);
lcd.print("Pump:");
lcd.setCursor(13, 1);
lcd.print(PumpPWMPrint);
} else if (HeaterTimeout == 1){
lcd.setCursor (8, 1);
lcd.print("LowTemp");
}
} else if (MenuActive == 1) {
lcd.setCursor(0, 0);
lcd.print("Set DMX:");
lcd.setCursor (0, 1);
lcd.print(startChannel);
} else if (MenuActive == 2) {
lcd.setCursor(0, 0);
lcd.print("Set Fan Default:");
lcd.setCursor (0, 1);
lcd.print(FanDefaultLevel);
} else if (MenuActive == 3) {
lcd.setCursor(0, 0);
lcd.print("Set Pump Default:");
lcd.setCursor (0, 1);
lcd.print(PumpDefaultLevel);
} else if (MenuActive == 4) {
lcd.setCursor(0, 0);
lcd.print("Writing Values");
delay(2000);
MenuActive = 0;
MenuChange = 1;
} else if (MenuActive == 99) {
lcd.setCursor(0, 0);
lcd.print("Debug");
lcd.setCursor (0, 1);
lcd.print(AddByte0);
lcd.setCursor (7, 1);
lcd.print(AddByte1);
}
}