Temperature Controller
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
Detail on this page 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
Sample Code
Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xa0); //Instruction to write WCR-00 Wire.send(0x20); //Send a D value of 32 Wire.endTransmission();
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 (00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99) - Q(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year) - Q Sets the date of the RTC DS1307 Chip. ex. Q1157193040209 * R (0-4) - Need to Define this better it is for transferring X9241 registers * S - System Status * B - RTC - Memory Dump */ #include "Wire.h" #define DS1307_I2C_ADDRESS 0x68 #define X9241_I2C_ADDRESS 0x2D // 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 int i; 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; byte test; // 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 // This function is ripe for bugs. Probably need to put in checks for valid numbers or the RTC will get hung up. void setDateDs1307() { second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. minute = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); hour = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); dayOfWeek = (byte) (Serial.read() - 48); dayOfMonth = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); month = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); year= (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0x00); 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(0x00); 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); } 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; // Take 5 sec average of temperature 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(" "); } else if (command == 66) { //If command = "B" RTC1307 Memory Dump Serial.println(" RTC 1307 Dump Begin"); // Wire.beginTransmission(DS1307_I2C_ADDRESS); // Wire.send(0x0f); // Wire.send(0xff); // Wire.endTransmission(); Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0x00); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 65); for (i = 1; i <= 65; i++) { test = Wire.receive(); Serial.println(test, DEC); } Wire.endTransmission(); Serial.println(" RTC1307 Dump end"); } else if (command == 82) { //If command = "R" Set Duct Position if (Serial.available()) { command = Serial.read(); // This code sets up the Persistent Registers and is not necessarily needed all the time, so can be removed from program eventually if (command == 49) { // If command = "1" Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc0); // This is the set register command c and the 16 registers are 0-f Wire.send(0x0a); // This line is the value to set the register Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc1); Wire.send(0x14); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc2); Wire.send(0x20); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc3); Wire.send(0x3c); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc4); Wire.send(0x0a); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc5); Wire.send(0x14); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc6); Wire.send(0x20); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc7); Wire.send(0x3c); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc8); Wire.send(0x0a); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xc9); Wire.send(0x14); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xca); Wire.send(0x20); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xcb); Wire.send(0x3c); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xcc); Wire.send(0x0a); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xcd); Wire.send(0x14); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xce); Wire.send(0x20); Wire.endTransmission(); delay(100); Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0xcf); Wire.send(0x3c); Wire.endTransmission(); } else if (command == 50) { // If command = "2" Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0x10); // Global Load WCR's with Reg-00 Wire.endTransmission(); } else if (command == 51) { // If command = "3" Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0x11); // Global Load WCR's with Reg-01 Wire.endTransmission(); } else if (command == 52) { // If command = "4" Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0x12); // Global Load WCR's with Reg-10 Wire.endTransmission(); } else if (command == 53) { // If command = "5" Wire.beginTransmission(X9241_I2C_ADDRESS); Wire.send(0x13); // Global Load WCR's with Reg-11 Wire.endTransmission(); } } //*********** Read operation just not working :~( //Wire.beginTransmission(X9241_I2C_ADDRESS); //Wire.send(0x90); //Serial.println("made it 1"); // Wire.endTransmission(); //Serial.println(test, DEC); //Wire.beginTransmission(X9241_I2C_ADDRESS); //Wire.requestFrom(X9241_I2C_ADDRESS, 1); //Wire.send(0x90); //Serial.println("made it 2"); //test = bcdToDec(Wire.receive()); //test = Wire.receive(); //Serial.println(test, DEC); //Serial.println(Wire.available()); //Wire.endTransmission(); //Serial.println(test, DEC); // Wire.beginTransmission(DS1307_I2C_ADDRESS); // Wire.send(0x0f); // Wire.send(0xff); // Wire.endTransmission(); Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0x0f); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 1); // for (i = 1; i <= 30; i++) { test = Wire.receive(); Serial.println(test, DEC); // } Wire.endTransmission(); } 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.