#include <DallasTemperature.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <elapsedMillis.h> // was working without this so maybe it is already included
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
OneWire ds(3); // on pin 3
int localKey = 0;
int pwm = 50;
int pwm_out;
int percent_on;
int run_pwm;
int reflux_on_time = 1;
int reflux_off_time = 9;
int old_reflux_on_time;
int heater_on_time = 5;
int heater_off_time = 5;
int old_heater_on_time;
int cooling_temp_limit = 70;
int old_cooling_temp_limit;
volatile int flow_count;
int flow_count_threshold = 100; // minimum number of flow counts to not trip overheat condition
float temp1 = 70;
float temp2 = 70;
float set_temp = 70;
int old_set_temp = set_temp; // should be float ???
float preheat_temp = 70;
int old_preheat_temp = preheat_temp; // should be float ???
float show_pwm_percent;
float tempC1;
byte addr[8];
float celsius, fahrenheit;
boolean reflux_on = false;
boolean heater_on;
boolean do_serial = false;
boolean over_heat = false;
boolean no_flow = false;
boolean pre_heat = false;
int address = 0; //EEPROM address to start reading from
int sense_thresh0 = 1700;
int sense_thresh1 = 1700;
int sense_thresh2 = 1700;
int sense_thresh3 = 1700;
int touch_read15 = touchRead(15);
int touch_read16 = touchRead(16);
int touch_read0 = touchRead(0);
int touch_read1 = touchRead(1);
int key_delay = 1500;
int repeat_delay = 500;
int temp_update_interval = 1000;
int mode = 0;
int old_pwm = pwm;
float sense_factor = 1.4;
unsigned int flow_check_interval = 1000;
elapsedMillis temp_check_time = 0;
elapsedMillis button_time = 0;
elapsedMillis reflux_time = 0;
elapsedMillis heater_check_time = 0;
unsigned long previousMillis = 0;
const long interval = 1000;
int check_count;
int pwm_table[] =
{0,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,100,100 // a few extra incase index is wrong
};
// Data wire is plugged into port 11 on the Arduino
#define ONE_WIRE_BUS 3 // was 2 on controller no 1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress thermometer1, thermometer2;
void setup(void) {
sense_thresh0 = sense_factor * touchRead(15);
sense_thresh1 = sense_factor * touchRead(16);
sense_thresh2 = sense_factor * touchRead(0);
sense_thresh3 = sense_factor * touchRead(1);
// Serial.begin(9600);
delay(1000);
// print_serial();
lcd.init(); // initialize the lcd
lcd.init();
lcd.backlight();
lcd.setCursor(2,0);
lcd.print("Hello");
lcd.setCursor(5,1);
lcd.print("Temp");
lcd.setCursor(8,2);
lcd.print("Controller");
lcd.setCursor(1,3);
lcd.print("restoring setings");
delay(1000);
lcd.clear();
address = 0; //EEPROM address to start reading from
int value;
EEPROM.get( address, value );
if ((value < 50) || (value > 125)){ // screwed up or not programmed values so restore defaults
EEPROM.put(address, set_temp);
address = 10;
EEPROM.put(address, pwm);
address = 20;
EEPROM.put(address, reflux_on_time);
address = 30;
EEPROM.put(address, cooling_temp_limit);
address = 40;
EEPROM.put(address, preheat_temp);
}
get_parameters();
pinMode(11, OUTPUT); // ssr control pin
pinMode(21, OUTPUT); // reflux control pin
pinMode(13, OUTPUT);
pinMode(14, INPUT_PULLUP); // flow sensor, not sure if pullup is needed, probalby not
attachInterrupt(digitalPinToInterrupt(14), count_flow, CHANGE);
sensors.begin();
sensors.getAddress(thermometer1, 0);
sensors.getAddress(thermometer2, 1);
sensors.setResolution(thermometer1, 12);
sensors.setResolution(thermometer2, 12);
sensors.setWaitForConversion(false); // makes it async
sensors.requestTemperatures();
sensors.setWaitForConversion(true);
temp1 = sensors.getTempC(thermometer1);
temp2 = sensors.getTempC(thermometer2);
do_relays();
}
void loop(void) {
if (mode >1) mode = 0;
switch (mode) {
case 0:
screen0();
break;
case 1:
screen1();
break;
default:
break;
}
}
void do_relays (){
check_flow();
do_reflux();
control_heater_relay(); // this just turns relay on and off on timmer schedule
get_temps();
check_overtemp();
if (set_temp > temp1){
int diff = int (set_temp - temp1);
if (diff < 0) diff = 0;
if (diff >= 20) {
run_pwm = pwm;
}
else{
run_pwm = (pwm_table[diff] * (pwm/10)) / 10; // currently this is the same as the following but table can be changed
if (run_pwm > pwm) run_pwm = pwm;
}
if (run_pwm < 0) run_pwm = 0;
if (run_pwm > 100) run_pwm = 100;
if (run_pwm >= 1 && run_pwm < 10) run_pwm = 10; // should probably round all run_pwms up but need to figure out how
if (run_pwm > pwm) run_pwm = pwm; // not likely but ...
if (over_heat == true) run_pwm = 0; // this is a little hidden and should be made more clear
heater_on_time = int (run_pwm/10); // change this to run_pwm to change to tenths of a second instead of seconds
heater_off_time = 10 - heater_on_time; // change this to 100 - heater_on_time if above line is changed
}
else{
run_pwm = 0;
heater_on_time = 0;
heater_off_time = 10;
}
}
void screen0(){ // this displays data only, no changes can be made
lcd.clear();
while (mode == 0){
get_temps();
display_temp();
lcd.setCursor(15, 3);
if (reflux_on == true){
lcd.print("R-ON ");
}
else{
lcd.print("R-OFF");
}
// lcd.print("SCR1");
do_relays ();
check_flow;
if (touchRead(1) > sense_thresh3) please_wait();
}
}
void screen1() { // add a while loop
lcd.clear();
while (mode ==1){
if (touchRead(1) > sense_thresh3) please_wait();
check_buttons();
get_temps();
do_relays ();
display_temp();
lcd.setCursor(9, 3);
lcd.print("set TMP/PWM");
}
}
void control_heater_relay(){
if (heater_on_time >0){
if (heater_on == true){
// if ((heater_check_time / 1000) > heater_on_time ){ // change to / 100 to match change below?
if ((heater_check_time / 100) > heater_on_time ){ // change to / 100 to match change below?
heater_check_time = 0;
heater_on = false;
digitalWrite(11, LOW);
digitalWrite(LED_BUILTIN, HIGH);
}
}
else{
if ((heater_check_time / 100) > heater_off_time){
heater_check_time = 0;
heater_on = true;
if (no_flow == false){
digitalWrite(11, HIGH);
}
else digitalWrite (11,LOW);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
else{
digitalWrite(11, LOW);
digitalWrite(LED_BUILTIN, HIGH);
heater_on = false;
}
}
void check_overtemp(){
if((temp2 > cooling_temp_limit) and (mode != 3)){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Shutdown over temp ");
lcd.setCursor(0, 1);
lcd.print("use mode 3 change");
lcd.setCursor(0, 2);
lcd.print("overheat setting");
lcd.setCursor(0, 3);
lcd.print("or cool condenser ");
over_heat = true;
delay(100);
run_pwm = 0;
heater_on_time = 0;
heater_off_time = 10;
digitalWrite(11, LOW);
if (touchRead(1) > sense_thresh3) please_wait();
}
else over_heat = false;
}
void do_reflux(){
if (reflux_on_time >0){
if (reflux_on == true){
if ((reflux_time / 1000) > reflux_on_time ){
reflux_time = 0;
reflux_on = false;
digitalWrite(21, HIGH);
digitalWrite(LED_BUILTIN, HIGH);
}
}
else{
if ((reflux_time / 1000) > reflux_off_time){
reflux_time = 0;
reflux_on = true;
digitalWrite(21, LOW);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
else{
digitalWrite(21, HIGH);
digitalWrite(LED_BUILTIN, HIGH);
reflux_on = false;
}
}
void check_flow(){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) { // check counter every second
check_count ++;
if (check_count > 1000) check_count =0;
if (do_serial) print_serial();
previousMillis = currentMillis;
if (flow_count < flow_count_threshold){
if (mode != 4){
no_flow = true;
}
}
else {
no_flow = false;
}
flow_count = 0;
}
}
void get_temps(){
if (temp_check_time > temp_update_interval){
sensors.setWaitForConversion(false); // makes it async
sensors.requestTemperatures();
sensors.setWaitForConversion(true);
temp1 = sensors.getTempC(thermometer1);
temp2 = sensors.getTempC(thermometer2);
temp_check_time = 0;
}
}
void count_flow(){
flow_count ++;
}
void check_buttons(){
if (touchRead(15) > sense_thresh0){
if (set_temp >= .5) set_temp -= .5;
display_temp();
delay(key_delay);
touch_read15 = touchRead(15);
while (touchRead(15) > sense_thresh0){
set_temp -= 5;
if (set_temp <= 0) set_temp = 0;
touch_read15 = touchRead(15);
do_relays ();
delay(repeat_delay);
display_temp();
}
if (old_set_temp != set_temp){
address = 0;
EEPROM.put(address, set_temp);
old_set_temp = set_temp;
}
// if (do_serial) print_serial();
}
else if (touchRead(16) > sense_thresh1){
if (set_temp <= 124.5) set_temp += .5;
do_relays ();
display_temp();
delay(key_delay);
touch_read16 = touchRead(16);
while (touchRead(16) > sense_thresh1){
set_temp += 5;
if (set_temp >125) set_temp = 125;
touch_read16 = touchRead(16);
do_relays ();
delay(repeat_delay);
display_temp();
}
if (old_set_temp != set_temp){
address = 0;
EEPROM.put(address, set_temp);
old_set_temp = set_temp;
}
// if (do_serial) print_serial();
}
else if (touchRead(0) > sense_thresh2){
pwm += 10;
if (pwm > 100)pwm = 10;
do_relays ();
display_temp();
delay(key_delay);
touch_read0 = touchRead(0);
while (touchRead(0) > sense_thresh2){
pwm += 10;
if (pwm > 100)pwm = 10;
touch_read0 = touchRead(0);
delay(repeat_delay);
do_relays ();
display_temp();
}
if (old_pwm != pwm){
address = 10;
EEPROM.put(address, pwm);
old_pwm = pwm;
}
// if (do_serial) print_serial();
}
}
void please_wait(){
lcd.clear();
lcd.setCursor(0, 0); // position first then line number
lcd.print("Switching to Page ");
int mode_plus_one = mode + 1;
if (mode_plus_one == 5) mode_plus_one = 0;
lcd.print (mode_plus_one);
lcd.setCursor(0, 1);
lcd.print("Please Wait ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
mode ++;
delay(key_delay);
lcd.clear();
}
void display_temp(){
if (over_heat == false){
lcd.setCursor(0, 0);
lcd.print("Set C");
lcd.print(set_temp,1);
lcd.print(" F");
float fsettemp = (DallasTemperature::toFahrenheit(set_temp)); // Converts tempC to Fahrenheit
lcd.print(fsettemp,1);
lcd.setCursor(0, 1);
lcd.print("Temp 1 C");
lcd.print(temp1,1);
float ftemp1 = (DallasTemperature::toFahrenheit(temp1)); // Converts tempC to Fahrenheit
lcd.print(" F");
lcd.print(ftemp1,1);
lcd.print(" "); // clear last two digits in case temp lost one digit
lcd.setCursor(0, 2);
lcd.print("Temp 2 C");
lcd.print(temp2,1);
float ftemp2 = (DallasTemperature::toFahrenheit(temp2)); // Converts tempC to Fahrenheit
lcd.print(" F");
lcd.print(ftemp2,1);
lcd.print(" "); // clear last two digits in case temp lost one digit
lcd.setCursor(0, 3);
if (no_flow == false){
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(pwm);
lcd.print("/");
lcd.print(run_pwm);
if (mode != 1){
if (heater_on){
lcd.print(" on ");
}
else{
lcd.print(" off ");
}
}
}
else{
lcd.setCursor(0, 3);
lcd.print("NO FLOW");
}
}
}
void get_parameters(){
address = 0;
EEPROM.get(address, set_temp);
if ((set_temp< 10) || (set_temp > 125)){
set_temp = 70;
}
address = 10;
EEPROM.get(address, pwm);
if ((pwm< 0) || (pwm > 100)){
pwm = 100;
}
address = 20;
EEPROM.get(address, reflux_on_time);
if ((reflux_on_time< 0) || (reflux_on_time> 10)){
reflux_on_time = 0;
}
address = 30;
EEPROM.get(address, cooling_temp_limit);
if ((cooling_temp_limit< 0) || (cooling_temp_limit > 250)){
cooling_temp_limit = 0;
}
address = 40;
EEPROM.get(address, preheat_temp);
if ((preheat_temp < 0) || (preheat_temp > 100)){
preheat_temp = 100;
}
}
void print_serial(){
Serial.print("check_count ");
Serial.println(check_count);
Serial.print("mode ");
Serial.println(mode);
Serial.print("run pwm ");
Serial.println(run_pwm);
Serial.print("set_temp ");
Serial.println(set_temp);
Serial.print("reflux_on_time ");
Serial.println(reflux_on_time);
Serial.print("cooling_temp_limit ");
Serial.println(cooling_temp_limit);
Serial.print("preheat_temp ");
Serial.println(preheat_temp);
}