SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By luke gq
#93687
I just got an arduino a couple days ago and have only taken a java class but i think it turned out ok. here is the code for the board. I borrowed the temp and time stuff from others and modified it to suit my needs. :) let me know if you have any suggestions. ill be starting the wood and fiberglass work as soon as i gets a bit warmer.

Code: Select all
//Wine Cooler v.01

//02-16-2010

/*This project is a simple design for a temperature controlled
cooler complete with lighting and a serial monitor to the PC.

NTC 10k Thermistor Schematic:
(Ground) ---- (10k-Resister) -------|------- (Thermistor) ---- (+5v)
                                     |
                                Analog Pin 0

Pin List:
Analog 0 10K_thermistor1 +Voltage Divider with 10K Potentiometer
Analog 1 10K_thermistor2 +Voltage Divider with 10K Potentiometer
Analog 2 reed_Switch and Coil Trigger when brought high.
Analog 3 Menu_Set_Button +10K Resistor to Ground
Analog 4 Menu_up_Button +10K Resistor to Ground
Analog 5 Menu_Down_Button +10K Resistor to Ground
Digital 6 Menu_Left_Button +10K Resistor to Ground
Digital 7 Menu_Right_Button +10K Resistor to Ground
Digital 8 Relay1_Peltier 230W@12V,19.6A attached with transistor 2n2222 and diode
Digital 9 Relay2_Heat_Exhaust_Fan attached with transistor 2n2222 and diode
Digital 10 Relay3_CCFL attached with transistor 2n2222 and diode
Digital 13 Led status light +330 ohm resistor
Digital 2,3,4,5,11,12 Display_Lines  16*2
*/

#include <LiquidCrystal.h>
#include <math.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int therm1 = 0;                              // Cooler Temperature Sensor pin
const int therm2 = 1;                              // Electronics Temperature Sensor pin
const int door = 16;                               // Sets door pin
const int MenuSet = 17;                            // Menu Set Button pin
const int MenuUP = 18;                             // Menu Down Button pin
const int MenuDN = 19;                             // Menu Up Button pin 
const int MenuLT = 6;                              // Menu Left Button pin
const int MenuRT = 7;                              // Menu Right Button pin
const int RelayCooler = 8;                         // Triggers peltier plate and fan assembly
const int RelayHeatFan = 9;                        // Triggers fans of control compartment
const int RelayCCFL = 10;                          // Triggers internal cooler light
const int ledStat = 13;                            // Shows status light
int setTemp;                                       // State of the set temp from menu
float ActualTemp;                                  // States the temp inside the cooler
float ControlTemp;                                 // States temperature around powersupply and controller
int DoorState;                                     // States is door is open or closed
int up;                                            // States Pin Status
int down;                                          // States Pin Status
int left;                                          // States Pin Status
int right;                                         // States Pin Status
float TimeAlive;                                   // States the number of minutes the cooler has been on since shutdown
int second=0, minute=0, hour=0;
int set;

// Inputs ADC Value from Thermistor and outputs Temperature in Celsius
//  requires: include <math.h>
//  Utilizes the Steinhart-Hart Thermistor Equation:
//  Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]^3}
//  where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08
 float Thermister(int RawADC) {
 float Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15;                            // Convert Kelvin to Celcius
 Temp = (Temp * 9.0)/ 5.0 + 32.0;                 // Convert Celcius to Fahrenheit
 return Temp;
}

void setup() {
   pinMode(MenuSet, INPUT);                          //sets menu buttons as inputs on digital channels
   pinMode(MenuDN, INPUT);                           //sets menu buttons as inputs on digital channels 
   pinMode(MenuUP, INPUT);                           //sets menu buttons as inputs on digital channels  
   pinMode(MenuLT, INPUT);                           //sets menu buttons as inputs on digital channels
   pinMode(MenuRT, INPUT);                           //sets menu buttons as inputs on digital channels
   pinMode(RelayCooler, OUTPUT);                     //sets peltier assembly as output
   pinMode(RelayHeatFan, OUTPUT);                    //sets cabinet fan output
   pinMode(RelayCCFL, OUTPUT);                       //sets CCFL lamp output
   pinMode(ledStat, OUTPUT);                         //sets led output pin
   Serial.begin(9600);                               //Start serial communications at 9600 baud
   lcd.begin(16, 2);                                 //Start lcd initialization
   setTemp = 82;                                     //Sets default temp setting
   hour = 10;                                        //Sets time.  for now this is done here but in the 
   minute = 46;                                      //future it will be done by the menu buttons
  }
  
void loop() {
  ControlTemp = float(Thermister(analogRead(1)));   //Reads from thermistors and assigns value to float.
  ActualTemp = float(Thermister(analogRead(0)));
  ControlTemp = analogRead(therm2);                  
  DoorState = digitalRead(door);                    //Finds out if the door is open or closed
  up = digitalRead(MenuUP);                         //detects the state of the buttons
  down = digitalRead(MenuDN);
  left = digitalRead(MenuLT);
  right = digitalRead(MenuRT);
  float x = (millis() / 1000);                      //Breaks down millis() to minutes
  TimeAlive = x / 60;
  Display();                                        //cals main display function to display the current temp of the cooler
  buttons();                                        //calls the buttons() function to execute commands based on the buttons pressed
  serial();                                         //out puts data to serial for debugging.  may also be used to set the future clock

static unsigned long lastTick = 0;
if (millis() - lastTick >= 1000) {
lastTick = millis();
second++;
}
                                                    // move forward one minute every 60 seconds
if (second > 59) {
minute++;
second = 0;                                         // reset seconds to zero
}
                                                    // move forward one hour every 60 minutes
if (minute > 59) {
hour++;
minute = 0;                                         // reset minutes to zero
}
                                                    
if (hour > 23) {
hour = 0;                                           // reset hours to zero
}
if (setTemp < ActualTemp){                          //Compares temperature vs. setting
  cool();                                           //starts the cooler system
 }
 else{
    digitalWrite(ledStat, LOW);                     //if temp is ok cooler shuts down
    digitalWrite(RelayCooler, LOW);
 }
}
void cool(){                                        //function to control cooler objects
    digitalWrite(ledStat, HIGH);  
    digitalWrite(RelayCooler, HIGH);
    delay(2000);
}
void serial(){                                      //Displays serial output for debuggin but will latter be used for data logging and 
    Serial.print("The cooler temerature is:");      //remote control
    Serial.print(ActualTemp);
    Serial.println();
    Serial.print("The internal temperature is:");
    Serial.print(ControlTemp);
    Serial.println();
    Serial.print("The set temperature of the cooler:");
    Serial.print(setTemp);
    Serial.println();
    Serial.print("Time:");
    Serial.print(hour);
    Serial.print(":");
    Serial.print(minute);
    Serial.println();
    Serial.print("Time since last shutdown:");
    Serial.print(TimeAlive);
    Serial.println();
    Serial.println();
     }  
void Display(){                                     //Function to run the home screen display
      lcd.clear();
      lcd.print("Wine Cooler is @ ");
      lcd.setCursor(0, 1);
      lcd.print(ActualTemp);
      lcd.print("^F");
      lcd.setCursor(8, 1);
      lcd.print(hour, DEC);
      lcd.print(":");
      lcd.print(minute, DEC);
      if(set = 0){
      lcd.print(",AM");
      }
      else{
      lcd.print(",PM");
      }
  }
void buttons(){                                     //Function to look at the button values and do the actions needed.
if (DoorState == LOW){                              //checks door for left open state
    lcd.clear();
    lcd.print("*****ALERT!*****");
    lcd.setCursor(3, 1);
    lcd.print("DOOR OPEN!");
    digitalWrite(RelayCCFL, HIGH);
    digitalWrite(RelayCooler, LOW); 
    digitalWrite(ledStat, HIGH); 
    delay(2);
    digitalWrite(ledStat, LOW); 
      }
else{
  digitalWrite(RelayCCFL, LOW);  
  }
 
if (up == HIGH) {                                   //checks the up button for temperature setting
      setTemp = setTemp ++ ;
      digitalWrite(ledStat, HIGH);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("New Temperature:"); 
      lcd.setCursor(0, 1);
      lcd.print(setTemp);
      digitalWrite(ledStat, LOW);
 delay(500);     
  } 
else if (down == HIGH){                            //checks the down button for temperature setting
      setTemp = setTemp -- ;
      digitalWrite(ledStat, HIGH);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("New Temperature:"); 
      lcd.setCursor(0, 1);
      lcd.print(setTemp);
      digitalWrite(ledStat, LOW);
      delay(500);       
    }
else if (left == HIGH){                             //checks the left button for time setting setting
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Set Time"); 
      lcd.setCursor(0, 1);
      lcd.print(hour, DEC);
      lcd.print(":");
      lcd.print(minute, DEC);
      if(set = 0){
      lcd.print(", AM");
      }
      else{
      lcd.print(", PM");
      }
   } 
else if (right == HIGH){                           //checks the left button to display time since shutdown in minutes.
    lcd.clear();
    lcd.print("Time Alive:");
    lcd.setCursor(0, 1);
    lcd.print(TimeAlive); 
   delay(10); 
  }
}
By luke gq
#93777
so ive updated the code after figuring out that the millis() function has allot of weird issues like running over and such. ill post the new code tonight after testing it out along with a couple pictures.
By Exonerd
#94040
This looks like a fun temperature control system.

That's quite a power hungry peltier setup you have! :shock: I might be able to give a few suggestions to enhance the heat transfer if you describe your physical setup. Are you using fans or something to circulate air on both sides of the peltier?
By luke gq
#94093
Well I have the cooling system worked out with two peltier plates attached to heatsinks and a fan assembly. I then created a heat tunnel to remove heat from both units. they are powered by a computer power supply. its worked out very well so far and the tunnel is capable of dissipating 600Watts of heat if need to but because once the cooler has cooled it will be short duty cycles to keep it cool. My problem right now is that the time function is off. the time does not stay accurate for more than 15 minutes and im not sure how to remedy the problem. I have since changed the code and how the buttons are read in an effort to fix it but it didn't seem to make a difference. Anybody got some ideas?
By riden
#94097
One problem is that every time cool() is called, you are doing a 2 second delay creating at least a one second slippage. You will get better resolution if you adjust the seconds based on the actual number of milliseconds elapsed.
By luke gq
#94098
i really seem to need the delay functions to prevent teetering on the thermoelectric heat pumps....do you think i should just go to a i2c real time clock?
By riden
#94109
An external clock would make things a lot simpler and be more accurate in the long run. However, the millis() function should be interrupt driven and you could that value as the indicator for when to flip the seconds. Your current code always increments by one second. Using the millis() would take into account your 2 second delay.
By luke gq
#94110
could you give me an example because im not quite following you on that. I apologize as im pretty new to this (first time actually).
By riden
#94151
The following should provide better accuracy. I haven't confirmed that the following code is correct Wiring syntax, but you can get the idea. Your clock will drift over time, but maybe this will be good enough for your purposes. The strategy is to set a target one second in the future. In the main loop the code checks to see if one second (or more) has elapsed. If so, add 1 to seconds plus any additional full seconds (t / 1000). Then target is set to one second into the future LESS any remaining overage (t mod 1000). I don't know if this will be a factor with your program, but you will have to watch out for millis() overflow, which will occur every 49.7 days of continuous operation (assuming millis() starts at 0).
Code: Select all
unsigned long target = millis() + 1000; // one second from now
unsigned long current;
unsigned long overCount;

// in your loop...

current = millis();
if (current >= target) {
  overCount = current - target;
  seconds += 1 + (overCount / 1000); 
  target = current + (1000 - (overCount % 1000));
}
Edit: Replaced references to non-existent 't' with 'overCount'
Last edited by riden on Thu Feb 25, 2010 4:04 pm, edited 1 time in total.
By luke gq
#94567
Awesome i will give that a shot tonight and see how it does. I hyad to take a break for a bit because the clock was making me so frustrated. Now looking at this, if i were to use a delay would the millis() keep counting or will it pause the counting and then pick up where it left off?
By riden
#94573
millis() is driven by an interrupt so delay() shouldn't be an issue. The simplest delay is a series of tight loops which the timer will periodically interrupt. Be sure to let us know if you get better timer results.

Edit: Egads, I just found an issue with the code I posted. I'll fix it.