/*
Temperature Controller 1/25/2011
Copyright 2011 Eric Friedrich
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#define LCD_PIN 1
#define LINE_ONE_TEXT "Sensor: "
#define LINE_TWO_TEXT " Set: "
#define MAX_TEMP_LEN 10 // For XXX.YYC + 2 spaces + terminator
#define ONE_WIRE_BUS 2
#define INPUT_PIN 0
#define RELAY_PIN 6
#define VER 0.9
static const float error_limit = .5; // Degrees C of error allowed from Control point
static int count = 0;
SoftwareSerial mySerial = SoftwareSerial(0, LCD_PIN);
OneWire ds(ONE_WIRE_BUS);
DallasTemperature sensors(&ds);
DeviceAddress tempSensor = { 0x10, 0x32, 0x3B, 0x36, 0x1, 0x8, 0x0, 0x10 };
unsigned long i=0;
int potVal = 0;
#define MAX_POT_VAL 1023
#define MAX_TEMP_SET 100
void displayClear(void) {
mySerial.print(254, BYTE);
mySerial.print(0x01, BYTE);
}
void displayGotoLineOne(void) {
mySerial.print(254, BYTE);
mySerial.print(128, BYTE);
}
void displayGotoLineOneEnd(void) {
mySerial.print(254, BYTE);
mySerial.print(128 + strlen(LINE_ONE_TEXT), BYTE);
}
void displayGotoLineTwo(void) {
mySerial.print(254, BYTE);
mySerial.print(192, BYTE);
}
void displayGotoLineTwoEnd(void) {
mySerial.print(254, BYTE);
mySerial.print(192 + strlen(LINE_TWO_TEXT), BYTE);
}
void displayLastChar(void) {
mySerial.print(254, BYTE);
mySerial.print(192 + 15, BYTE);
}
// Schematic calls for NPN 2N3904 transistor, but
// substituted PNP 2N4403 instead. This uses a low signal to
// switch instead of a high
static int relay_state = 0;
void relayOn(void) {
if (relay_state == 0) {
digitalWrite(RELAY_PIN, LOW);
relay_state = 1;
}
displayLastChar();
mySerial.print("1");
}
void relayOff(void) {
if (relay_state == 1){
digitalWrite(RELAY_PIN, HIGH);
relay_state = 0;
}
displayLastChar();
mySerial.print("0");
}
void setup(void)
{
pinMode(INPUT_PIN, INPUT);
pinMode(LCD_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH);
mySerial.begin(9600);
displayClear();
mySerial.print("Starting Up...");
delay(2000);
displayClear();
displayGotoLineOne();
mySerial.print(LINE_ONE_TEXT);
displayGotoLineTwo();
mySerial.print(LINE_TWO_TEXT);
// Serial.begin(9600);
// Serial.println("TempControl Board Software VERSION");
sensors.begin();
}
void printFloatTemp(float temp) {
char tempString[MAX_TEMP_LEN];
int decimals = (temp - (int)temp) * 100;
snprintf(tempString, MAX_TEMP_LEN, "%d.%dC ", (int)temp, decimals);
mySerial.print(tempString);
}
static float tempSensorC = 0;
void loop(void)
{
char tempString[MAX_TEMP_LEN];
// Maybe request temp only once per second,
// but need to redraw screen much faster than that
// Get Temp from Sensor and Display on LCD
count++;
if (count == 1) {
sensors.requestTemperaturesByAddress(tempSensor);
tempSensorC = sensors.getTempC(tempSensor);
displayGotoLineOneEnd();
printFloatTemp(tempSensorC);
} else if (count == 1000) {
count = 0;
}
//Serial.print(i++);
//Serial.print("\t");
//Serial.println(tempSensorC);
// Get control point from Pot and Display on LCD
potVal = 1024 - analogRead(INPUT_PIN);
float setPoint = ((float)potVal*MAX_TEMP_SET)/MAX_POT_VAL;
displayGotoLineTwoEnd();
printFloatTemp(setPoint);
// If Temp is above control+e, turn off heater.
// If temp is below control-e, turn on heater.
// 2*error_limit (4 degC) change up or down needed before heater switches states
if (tempSensorC > (setPoint + error_limit)) {
relayOff();
} else if (tempSensorC < (setPoint - error_limit)) {
relayOn();
}
}