Skip to content

Instantly share code, notes, and snippets.

@DerBierBaron
Created December 9, 2017 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DerBierBaron/89ee1b72185f6dbf8f0554607b91a399 to your computer and use it in GitHub Desktop.
Save DerBierBaron/89ee1b72185f6dbf8f0554607b91a399 to your computer and use it in GitHub Desktop.
[code]
#include <OneWire.h> /*sensor bus library*/
#include <DallasTemperature.h> /*DS18B20 library*/
#include <ShiftedLCD.h> /*to use 74HC595 shift register with LCD*/
#include <SPI.h>
#include <PID_v1.h>
#include <EEPROM.h>
#define CONFIG_VERSION "f01"
#define CONFIG_START 25
#define PWM6 OCR4D /*Pin 6 shortcut*/
#define PWM6_MAX OCR4C /*terminal timer count*/
#define RELAIS 7 /*Relais output pin 9*/
#define TARGET_UP 18 /*up button pin 18*/
#define TARGET_DOWN 19 /*down button pin 19*/
#define DBG false
#define DEBUG(x) if(DBG && Serial) { Serial.print (x); }
#define WAIT 500
#define DUTY_MIN 64 /*minimum fan speed (0...255)*/
#define DUTY_DEAD_ZONE 64 /*delta between minimum output for the PID and DUTY_MIN (DUTY_MIN - DUTY_DEAD_ZONE)*/
#define KP 0.4
#define KI 0.4
#define KD 0.05
const unsigned char One_Wire_Bus = 8;
int sensor_count = 0;
const unsigned int Latch_Pin = 10;
bool lastUp = false, lastDown = false;
bool up, down = false;
bool blank = false;
bool blink = true;
unsigned long prev1, prev2, prev3, prev4 = 0; /*time placeholders*/
double duty;
double dtemp, ctemp;
bool fanRunning = true;
struct StoreStruct
{
char version[4];
double target;
} storage = {
CONFIG_VERSION,
40
};
PID fanPID(&ctemp, &duty, &storage.target, KP, KI, KD, REVERSE);
OneWire oneWire(One_Wire_Bus); /*sensor Pin to Bus*/
DallasTemperature sensors(&oneWire);
LiquidCrystal lcd(Latch_Pin); /*initialize LCD shift with latchpin of 74HC595*/
void pwm6configure() /*Configuration PWM clock*/
{
TCCR4A = 0;
TCCR4B = 4; /*4 sets 23437Hz*/
TCCR4C = 0;
TCCR4D = 0;
PLLFRQ = (PLLFRQ & 0xCF) | 0x30;
OCR4C = 255;
}
void pwmSet6(int value) /*Set PWM to D6 (Timer4 D), argument is PWM between 0 and 255*/
{
OCR4D = value; /*set PWM value*/
DDRD |= 1 << 7; /*set Output Mode D7*/
TCCR4C |= 0x09; /*activate channel D*/
}
void loadConfig() /*Check if saved bytes have the same "version" and loads them. Otherwise it will load the default values*/
{
if (EEPROM.read(CONFIG_START + 0) == CONFIG_VERSION[0] &&
EEPROM.read(CONFIG_START + 1) == CONFIG_VERSION[1] &&
EEPROM.read(CONFIG_START + 2) == CONFIG_VERSION[2])
for (unsigned int t = 0; t < sizeof(storage); t++)
*((char*)&storage + t) = EEPROM.read(CONFIG_START + t);
}
void saveConfig()
{
for (unsigned int t = 0; t < sizeof(storage); t++)
EEPROM.update(CONFIG_START + t, *((char*)&storage + t));
}
void writeTemp(double temp)
{
sensors.requestTemperatures(); /*get Temperature*/
temp = sensors.getTempCByIndex(0);
lcd.setCursor(10, 0);
lcd.print(temp, 1);
}
void writeTarget()
{
lcd.setCursor(10, 1);
lcd.print(storage.target, 1);
}
void writeBlank()
{
lcd.setCursor(10, 1);
lcd.print(" ");
delay(500);
}
void writeLCD ()
{
writeTemp(dtemp);
if (blank)
{
writeBlank();
}
else
{
writeTarget();
}
}
void setup()
{
Serial.begin(19200);/*start serial connecction to PC*/
if(DBG)
{
while (!Serial) {} /*WAIT FOR THE SERIAL CONNECTION FOR DEBUGGING*/
}
DEBUG("Fans...");
// pinMode(SPD_IN, INPUT);
pinMode(RELAIS, OUTPUT);
pinMode(TARGET_UP, INPUT_PULLUP);
pinMode(TARGET_DOWN, INPUT_PULLUP);
// attachInterrupt(digitalPinToInterrupt(SPD_IN), pickRPM, FALLING);
DEBUG("Display...");
pwm6configure();
loadConfig();
DEBUG("PID..."); /*Setup the PID to work with our settings*/
fanPID.SetSampleTime(WAIT);
fanPID.SetOutputLimits(DUTY_MIN - DUTY_DEAD_ZONE, 255);
fanPID.SetMode(AUTOMATIC);
DEBUG("Fans...");
pwmSet6(255); /*Let fan run for 5s*/
delay(5000);
lcd.begin(16, 2); /*set up LCD's columns and rows*/
lcd.print("Temp.: ");
lcd.setCursor(14, 0);
lcd.print((char)223);
lcd.setCursor(15, 0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("SET-Temp.:");
lcd.setCursor(14, 1);
lcd.print((char)223);
lcd.setCursor(15, 1);
lcd.print("C");
DEBUG("Sensor...");
sensors.begin();
sensor_count = sensors.getDeviceCount();/*check number of attached sensors*/
DEBUG("Ready.\n\n");
prev1 = millis();
}
void loop()
{
unsigned long cur = millis();
bool shouldPrint = false;
lastUp = up;
lastDown = down;
up = !digitalRead(TARGET_UP);
down = !digitalRead(TARGET_DOWN);
prev3 = cur;
sensors.requestTemperatures();
double t = sensors.getTempCByIndex(0);
if (!isnan(t))
{
dtemp = round(t * 2.0) / 2.0;
ctemp = round(t);
}
fanPID.Compute();
if (cur - prev1 >= WAIT)
{
prev1 = cur;
//unsigned long _duration = duration;
//unsigned long _ticks = ticks;
//duration = 0;
//Calculate fan speed
// float Freq = (1e6 / float(_duration) * _ticks) / 2;
// speed = Freq * 60;
// ticks = 0;
//Turn the fans ON/OFF
if (round(duty) < DUTY_MIN)
{
digitalWrite(RELAIS, HIGH);
PWM6 = 0;
fanRunning = false;
}
else
{
fanRunning = true;
PWM6 = duty;
digitalWrite(RELAIS, LOW);
}
shouldPrint = true; /* Things have changed. remind to update the display */
DEBUG("- Target; ");
DEBUG(storage.target);
DEBUG(" - Temp: ");
DEBUG(ctemp);
DEBUG(" - Duty: ");
DEBUG(map(round(duty), 0, 255, 0, 100));
DEBUG(" - prev3: ");
DEBUG(prev3);
DEBUG("\n");
}
/* Checks if the +/- buttons are pressed and if it's not the first time they've been pressed. */
if (up && !lastUp == up && storage.target < 255)
{
storage.target++;
}
if (down && !lastDown == down && storage.target > 0)
{
storage.target--;
}
/* If either + or - buttons are pressed, enter target mode and display the current target on the lcd. */
if (up || down)
{
//targetMode = true;
shouldPrint = true;
prev3 = cur;
}
/* If 3 secs have elapsed and no button has been pressed, exit target mode. */
if (cur - prev3 >= 3000)
{
if (blink)
{
blank = true;
blink = false;
shouldPrint = true;
}
else
{
blank = false;
blink = true;
shouldPrint = true;
}
}
else
{
saveConfig(); /* Save the config only when exiting targetMode to reduce EEPROM wear */
}
if (shouldPrint)
{
writeLCD();
}
}
[/code]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment