/* Seven Segment 4 digit driver Made for an LED display with a single common anode for all digits. */ // constants won't change. They're used here to //pins for segment of the displays, Semi random due to board layout considerations. const int segA = 7; const int segB = 5; const int segC = 8; const int segD = 4; const int segE = 3; const int segF = 9; const int segG = 6; const int pinSO = 11; //MISO const int pinSCK = 13; //Serial Clock const int pinSSB = 12; //enable serial interface LOW. const int pinButton = 2; const int pinRelay = 10; //probe variables int temp = 0; //run for 10-20 minutes to determine offset. As the thermocouple booster chips warms up the reading will rise a bit. int calibration = -10; //temp calibration compensation * .25deg C #define READINGNUM 5 int readings[READINGNUM]; unsigned int readingCurrent = 0; //button variables int buttonState; int lastButtonState = LOW; long lastDebounceTime = 0; long debounceDelay = 250; //pins for the digits in the display int digit[4] ={ 14,15,16,17}; int tempReadDelayTime = 1000; unsigned long lastDelay = 0; int segments[8][7] = { { 1,0,0,0,0,0,0 }, { 0,1,0,0,0,0,0 }, { 0,0,1,0,0,0,0 }, { 0,0,0,1,0,0,0 }, { 0,0,0,0,1,0,0 }, { 0,0,0,0,0,1,0 }, { 0,0,0,0,0,0,1 }, { 0,0,0,0,0,0,0 } }; //Digit Mapping int numbers[16][7] = { { 1,1,1,1,1,1,0 } ,//0 { 0,1,1,0,0,0,0 } ,//1 { 1,1,0,1,1,0,1 } ,//2 { 1,1,1,1,0,0,1 } ,//3 { 0,1,1,0,0,1,1 } ,//4 { 1,0,1,1,0,1,1 } ,//5 { 1,0,1,1,1,1,1 } ,//6 { 1,1,1,0,0,0,0 } ,//7 { 1,1,1,1,1,1,1 } ,//8 { 1,1,1,1,0,1,1 } , //9 { 1,1,1,0,1,1,1 } ,//A { 0,0,1,1,1,1,1 } ,//b { 1,0,0,1,1,1,0 } ,//C { 0,1,1,1,1,0,1 } ,//d { 1,0,0,1,1,1,1 } ,//E { 1,0,0,0,1,1,1 }//F }; #define PRESETSCOUNT 8 int tempPresets[PRESETSCOUNT] = { 0, 110, 120, 125, 130, 135, 140, 150 }; int currentTarget = 0;//default temp is 0 void setup() { //start off with all the seg pins OFF pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT); pinMode(segG, OUTPUT); pinMode(digit[0], OUTPUT); pinMode(digit[1], OUTPUT); pinMode(digit[2], OUTPUT); pinMode(digit[3], OUTPUT); //Temp Probe setup pinMode(pinSO, INPUT); pinMode(pinSCK, OUTPUT); pinMode(pinSSB, OUTPUT); digitalWrite(pinSSB, HIGH);//disable device. //button setup pinMode(pinButton, INPUT); //relay pinMode(pinRelay, OUTPUT); digitalWrite(pinRelay, LOW); //Serial.begin(9600); delay(1000); //pre-seed the averaging data. int t = read_temp(pinSSB,0,calibration,10); for(int i = 0; i < READINGNUM; i++) { readings[i] = t; } } void loop(){ readTemp(); handleButton(); } void handleButton() { //button debounce if((millis() - lastDebounceTime) > debounceDelay) { int reading = digitalRead(pinButton); if(buttonState != reading && buttonState == LOW) { currentTarget = (currentTarget + 1) % PRESETSCOUNT; } buttonState = digitalRead(pinButton); lastDebounceTime = millis(); } if(!buttonState) { printThreeDigitNum(temp); lightDigit(digit[0], numbers[15]);//Print the F in the temp; } else { printThreeDigitNum(tempPresets[currentTarget]); } } int readTemp() { if((millis() - lastDelay > tempReadDelayTime)) { lastDelay = millis(); readings[readingCurrent] = read_temp(pinSSB,0,calibration,2); //leave a degree in the middle to prevent bouncing the relay if(temp < tempPresets[currentTarget]) { digitalWrite(pinRelay, HIGH); } if(temp > tempPresets[currentTarget]) { digitalWrite(pinRelay, LOW); } //Serial.print("Temp F:"); //Serial.println(temp); //Serial.println(buttonState); } for(int i = 0; i < READINGNUM; i++) { temp += readings[i]; } temp /= READINGNUM; temp /= 10; if(++readingCurrent >= READINGNUM) { readingCurrent = 0; } return temp; } void printThreeDigitNum(unsigned int num) { num = num % 1000; int h = num / 100; num -= h * 100; int t = num / 10; num -= t * 10; int o = num; lightDigit(digit[3], numbers[h]); lightDigit(digit[2], numbers[t]); lightDigit(digit[1], numbers[o]); } void resetDigits() { digitalWrite(digit[0], LOW); digitalWrite(digit[1], LOW); digitalWrite(digit[2], LOW); digitalWrite(digit[3], LOW); } void lightDigit(int digit, int pattern[]) { resetDigits(); digitalWrite(digit, HIGH); digitalWrite(segA, !pattern[0]); digitalWrite(segB, !pattern[1]); digitalWrite(segC, !pattern[2]); digitalWrite(segD, !pattern[3]); digitalWrite(segE, !pattern[4]); digitalWrite(segF, !pattern[5]); digitalWrite(segG, !pattern[6]); delay(2); } /* Create a function read_temp that returns an unsigned int with the temp from the specified pin (if multiple MAX6675). The function will return 9999 if the TC is open. Usage: read_temp(int pin, int type, int error) pin: the CS pin of the MAX6675 type: 0 for ˚F, 1 for ˚C error: error compensation in digital counts samples: number of measurement samples (max:10) */ unsigned int read_temp(int pin, int type, int error, int samples) { unsigned int value = 0; int error_tc; float temp; unsigned int temp_out; for (int i=samples; i>0; i--){ digitalWrite(pin,LOW); // Enable device /* Cycle the clock for dummy bit 15 */ digitalWrite(pinSCK,HIGH); digitalWrite(pinSCK,LOW); /* Read bits 14-3 from MAX6675 for the Temp Loop for each bit reading the value and storing the final value in 'temp' */ for (int i=11; i>=0; i--){ digitalWrite(pinSCK,HIGH); // Set Clock to HIGH value += digitalRead(pinSO) << i; // Read data and add it to our variable digitalWrite(pinSCK,LOW); // Set Clock to LOW } /* Read the TC Input inp to check for TC Errors */ digitalWrite(pinSCK,HIGH); // Set Clock to HIGH error_tc = digitalRead(pinSO); // Read data digitalWrite(pinSCK,LOW); // Set Clock to LOW digitalWrite(pin, HIGH); //Disable Device } value = value/samples; // Divide the value by the number of samples to get the average /* Keep in mind that the temp that was just read is on the digital scale from 0˚C to 1023.75˚C at a resolution of 2^12. We now need to convert to an actual readable temperature (this drove me nuts until I figured this out!). Now multiply by 0.25. I tried to avoid float math but it is tough to do a good conversion to ˚F. THe final value is converted to an int and returned at x10 power. */ value = value + error; // Insert the calibration error value if(type == 0) { // Request temp in ˚F temp = ((value*0.25) * (9.0/5.0)) + 32.0; // Convert value to ˚F (ensure proper floats!) } else if(type == 1) { // Request temp in ˚C temp = (value*0.25); // Multiply the value by 25 to get temp in ˚C } temp_out = temp*10; // Send the float to an int (X10) for ease of printing. /* Output 9999 if there is a TC error, otherwise return 'temp' */ if(error_tc != 0) { return 9999; } else { return temp_out; } }