/* 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(); } }