Temperature Controller
From Combustory
Welcome to Combustory
Any questions or comments:
- Send them to - combustor@combustory.com
|
Warning
This page is in progress and none of the code can be considered good or complete. I am just using this as an alternate storage of the code for right now.
Summary
Functional Description of the Method
Requirements
Example of Method
Quick Guide:
Detailed Guide:
I2C
X9241A - Digital Potentiometer
There are basically only two functions that I am after right now which are both three byte instructions:
- Read WCR(Wiper Control Register) for the four potentiometers 0-3 (So far this is failing miserably)
- Send 1st byte - Address (my circuit - 01011010 or 0x2D)(binary - 0101 A3 A2 A1 A0) A values are actual pins set to high or low for an address.
- Send 2nd byte - Instruction (binary - 1001 (1/0)(1/0) 00) - The two bits are used to choose the potentiometer
- Read WCR requested Byte
- Write WCR for the four potentiometers 0-3 (This works)
- Send 1st byte - Address (my circuit - 01011010 or 0x2D)(binary - 0101 A3 A2 A1 A0) A values are actual pins set to high or low for an address.
- Send 2nd byte - Instruction (binary - 1010 (1/0)(1/0) 00) - The two bits are used to choose the potentiometer
- Send WCR Byte - Potentiometer value (binary - 00 D5 D4 D3 D2 D1 D0) - D values are the 0-63 potentiometer positions
DS1307 - Real Time Clock
The code for this very useful chip came from the [Glacial Wanderer]
A/C_Control_v.01 code
While this says v.01, don't count on it being a released v.01, I am still working on v.01, this is a back up
/*
* A/C Control v.01
* by <http://www.combustory.com> John Vaughters
* Credit to:
* Maurice Ribble - http://www.glacialwanderer.com/hobbyrobotics for RTC DS1307 code
*
* Turns on an LED for temperatures from analog pins 1-5 on
* digital pins 2-6 when the temperature rises above the THRESHOLDS 1-5.
* The program also implements a
* Serial Communication method that utilizes a leading CHAR for each command Described below.
* Commands:
* T(1-4) - Temp1-5 Status ex. T1, T2, etc
* C(1-4)(0-9) - Increment THRESHOLD1-4 by (1-9) ex. C15 increments THRESHOLD1 BY 5 (Note: C40 will give you a status of THRESHOLD4)
* D(1-4)(0-9) - Decrement THRESHOLD1-4 by (1-9) ex. D59 decrements THRESHOLD5 BY 9 (Note: D10 will give you a status of THRESHOLD1)
* A(0-1) - Manual AC on command A1 is AC on, A0 is AC off
* F(0-1) - Manual AC on command A1 is FAN on, A0 is FAN off
* Q - Q Sets the date of the RTC DS1307 Chip
*/
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
// Global Variables
int val_cnt = 0; // counter for the temp_val
int temp1Pin = 0; // select the input pin for the Thermistor
int temp2Pin = 1; // select the input pin for the Thermistor
int temp3Pin = 2; // select the input pin for the Thermistor
int temp4Pin = 3; // select the input pin for the Thermistor
int temp1_val[5] = {0,0,0,0,0}; // variable to store the value coming from the sensor
int temp2_val[5] = {0,0,0,0,0}; //
int temp3_val[5] = {0,0,0,0,0}; //
int temp4_val[5] = {0,0,0,0,0}; //
int temp1_avg; // average over poll time of the temp values
int temp2_avg;
int temp3_avg;
int temp4_avg;
int duct1 = 2; // Ducts open or close using a digital output
int duct2 = 3;
int duct3 = 4;
int duct4 = 5;
int THRESHOLD1 = 580; // Default theshold values
int THRESHOLD2 = 580;
int THRESHOLD3 = 580;
int THRESHOLD4 = 580;
int ac_on = 13;
int fan_on = 12;
int command = 0; // This is the command char, in ascii form, sent from the serial port
long polltime = 1000; // The time to Poll the tempPins
long previousMillis = 0; // will store last time Temp was updated
long ac_on_start = 0; // Start A/C delay timer
long ac_on_delay = 10000; // Time to wait before checking the ducts again
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
// Watch for scope issues with Global Variables
/*void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99*/
void setDateDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307 and prints result
// Watch for scope issues with Global Variables
void getDateDs1307()
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
second = bcdToDec(Wire.receive() & 0x7f);
minute = bcdToDec(Wire.receive());
hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
dayOfWeek = bcdToDec(Wire.receive());
dayOfMonth = bcdToDec(Wire.receive());
month = bcdToDec(Wire.receive());
year = bcdToDec(Wire.receive());
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(year, DEC);
}
void setup() {
Wire.begin();
Serial.begin(57600);
pinMode(duct1, OUTPUT);
pinMode(duct2, OUTPUT);
pinMode(duct3, OUTPUT);
pinMode(duct4, OUTPUT);
pinMode(ac_on, OUTPUT);
pinMode(fan_on, OUTPUT);
// Initialize Date/Time to update RTC DS1307 - You need to run the Q command right after you download this program
// This is temporary until a more complex date time command is finished
second = 15;
minute = 41;
hour = 12;
dayOfWeek = 5;
dayOfMonth = 5;
month = 9;
year = 8;
}
void loop() {
if (millis() - previousMillis > polltime) {
previousMillis = millis(); // remember the last time
if (millis() - ac_on_start > ac_on_delay) {
if (digitalRead(duct1) || digitalRead(duct2) || digitalRead(duct3) || digitalRead(duct4)){ // If any ducts are turned on turn on the A/C
if (digitalRead(ac_on) != HIGH) { // Check ac_on state
digitalWrite(ac_on,HIGH);
getDateDs1307();
Serial.println(" - AC ON");
}
ac_on_start = millis();
}
else if (digitalRead(ac_on) != LOW){ //Check ac_on state
digitalWrite(ac_on,LOW);
getDateDs1307();
Serial.println(" - AC OFF");
}
}
temp1_val[val_cnt] = analogRead(temp1Pin); // read the value from the sensors
temp2_val[val_cnt] = analogRead(temp2Pin);
temp3_val[val_cnt] = analogRead(temp3Pin);
temp4_val[val_cnt] = analogRead(temp4Pin);
val_cnt ++;
if (val_cnt == 5) {
val_cnt = 0;
}
temp1_avg = (temp1_val[0] + temp1_val[1] + temp1_val[2] + temp1_val[3] + temp1_val[4])/5;
temp2_avg = (temp2_val[0] + temp2_val[1] + temp2_val[2] + temp2_val[3] + temp2_val[4])/5;
temp3_avg = (temp3_val[0] + temp3_val[1] + temp3_val[2] + temp3_val[3] + temp3_val[4])/5;
temp4_avg = (temp4_val[0] + temp4_val[1] + temp4_val[2] + temp4_val[3] + temp4_val[4])/5;
// Check Thresholds against the Temperatures and set the ducts HIGH or LOW
if (temp1_avg >= THRESHOLD1) {digitalWrite(duct1, HIGH);}
else {digitalWrite(duct1, LOW);}
if (temp2_avg >= THRESHOLD2) {digitalWrite(duct2, HIGH);}
else {digitalWrite(duct2, LOW);}
if (temp3_avg >= THRESHOLD3) {digitalWrite(duct3, HIGH);}
else {digitalWrite(duct3, LOW);}
if (temp4_avg >= THRESHOLD4) {digitalWrite(duct4, HIGH);}
else {digitalWrite(duct4, LOW);}
if (Serial.available()) { // Look for char in serial que and process if found
command = Serial.read();
if (command == 84) { // If command = "T"
command = Serial.read();
if (command == 49) { // If command = "1" print the Temp1
Serial.print("Temp1 = ");
Serial.print(temp1_avg); //
Serial.print(" ");
}
else if (command == 50) { // If command = "2" print the Temp2
Serial.print("Temp2 = ");
Serial.print(temp2_avg); //
Serial.print(" ");
}
else if (command == 51) { // If command = "3" print the Temp3
Serial.print("Temp3 = ");
Serial.print(temp3_avg); //
Serial.print(" ");
}
else if (command == 52) { // If command = "4" print the Temp4
Serial.print("Temp4 = ");
Serial.print(temp4_avg); //
Serial.print(" ");
}
}
else if (command == 67) { //If command = "C" Change Temp Threshhold
if (Serial.available()) {
command = Serial.read();
if (command == 49) { // If command = "1" print the THRESHOLD1
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Increment the Threshold by number sent
THRESHOLD1 += command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD1 = ");
Serial.print(THRESHOLD1); //
Serial.print(" ");
}
}
else if (command == 50) { // If command = "2" print the THRESHOLD2
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Increment the Threshold by number sent
THRESHOLD2 += command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD2 = ");
Serial.print(THRESHOLD2); //
Serial.print(" ");
}
}
else if (command == 51) { // If command = "3" print the THRESHOLD3
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Increment the Threshold by number sent
THRESHOLD3 += command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD3 = ");
Serial.print(THRESHOLD3); //
Serial.print(" ");
}
}
else if (command == 52) { // If command = "4" print the THRESHOLD4
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Increment the Threshold by number sent
THRESHOLD4 += command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD4 = ");
Serial.print(THRESHOLD4); //
Serial.print(" ");
}
}
}
}
else if (command == 68) { //If command = "D" Change Temp Threshhold
if (Serial.available()) {
command = Serial.read();
if (command == 49) { // If command = "1" print the THRESHOLD1
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Decrement the Threshold by number sent
THRESHOLD1 -= command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD1 = ");
Serial.print(THRESHOLD1); //
Serial.print(" ");
}
}
else if (command == 50) { // If command = "2" print the THRESHOLD2
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Decrement the Threshold by number sent
THRESHOLD2 -= command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD2 = ");
Serial.print(THRESHOLD2); //
Serial.print(" ");
}
}
else if (command == 51) { // If command = "3" print the THRESHOLD3
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Decrement the Threshold by number sent
THRESHOLD3 -= command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD3 = ");
Serial.print(THRESHOLD3); //
Serial.print(" ");
}
}
else if (command == 52) { // If command = "4" print the THRESHOLD4
command = Serial.read();
if (command > 47 && command < 58) { // If command is between 0-9 Decrement the Threshold by number sent
THRESHOLD4 -= command - 48; // ASCII math to get value sent
Serial.print("THRESHOLD4 = ");
Serial.print(THRESHOLD4); //
Serial.print(" ");
}
}
}
}
//**************** Warning - This is a potential for problem - Consider a manual lock out feature to lock out manual commands
//**************** Possibly create a command to open up manual commands for a certian time period then shut them off again automatically
else if (command == 65) { //If command = "A" Change Temp Threshhold
if (Serial.available()) {
command = Serial.read();
if (command == 49) { // If command = "1" print the AC ON message
getDateDs1307();
Serial.print(" - Manual AC ON ");
ac_on_start = millis(); // Set the AC to a delay before it can be turned off again
digitalWrite(ac_on,HIGH);
}
else if (command == 48) { // If command = "0" print the AC OFF message
getDateDs1307();
Serial.print(" - Manual AC OFF ");
digitalWrite(ac_on,LOW);
}
}
}
else if (command == 70) { //If command = "F" Change Temp Threshhold
if (Serial.available()) {
command = Serial.read();
if (command == 49) { // If command = "1" print the FAN ON message
getDateDs1307();
Serial.print(" - Manual FAN ON ");
ac_on_start = millis();
digitalWrite(fan_on,HIGH);
}
else if (command == 48) { // If command = "0" print the FAN OFF message
getDateDs1307();
Serial.print(" - Manual FAN OFF ");
digitalWrite(fan_on,LOW);
}
}
}
//********************** End of Warning Zone *******************************
// *************** This Section Will list the Staus of the Controller
else if (command == 83) { //If command = "S" Print Controller Status
getDateDs1307();
Serial.println(" ");
Serial.println(" ");
Serial.print("Temp1 = ");
Serial.println(temp1_avg);
Serial.print("Temp2 = ");
Serial.println(temp2_avg);
Serial.print("Temp3 = ");
Serial.println(temp3_avg);
Serial.print("Temp4 = ");
Serial.println(temp4_avg);
Serial.println(" ");
Serial.print("THRESHOLD1 = ");
Serial.println(THRESHOLD1);
Serial.print("THRESHOLD2 = ");
Serial.println(THRESHOLD2);
Serial.print("THRESHOLD3 = ");
Serial.println(THRESHOLD3);
Serial.print("THRESHOLD4 = ");
Serial.println(THRESHOLD4);
Serial.println(" ");
if (digitalRead(duct1) == HIGH) {Serial.println("duct1 ON");}
else{Serial.println("duct1 OFF");}
if (digitalRead(duct2) == HIGH) {Serial.println("duct2 ON");}
else{Serial.println("duct2 OFF");}
if (digitalRead(duct3) == HIGH) {Serial.println("duct3 ON");}
else{Serial.println("duct3 OFF");}
if (digitalRead(duct4) == HIGH) {Serial.println("duct4 ON");}
else{Serial.println("duct4 OFF");}
Serial.println(" ");
if (digitalRead(fan_on) == HIGH) {Serial.println("Fan ON");}
else{Serial.println("Fan OFF");}
if (digitalRead(ac_on) == HIGH) {Serial.println("AC ON");}
else{Serial.println("AC OFF");}
Serial.print("A/C Delay (millisec) = ");
Serial.println(ac_on_delay);
Serial.print("Temp Polling (millisec) = ");
Serial.println(polltime);
Serial.println(" ");
}
else if (command == 81) { //If command = "Q" Set Date
setDateDs1307();
getDateDs1307();
Serial.println(" ");
}
Serial.println(command); // Echo command char found in serial que
command = 0; // reset command
}
}
}
//*****************************************************The End***********************
A/C_Control_v.01 User Guide
Commands
Troubleshooting
Summary
When Troubleshooting a multi-functional issue, it is best practice to break down the issue into pieces and test each piece as a separate system. However, we will first run through a quick test to see if we can find any obvious issues first.