At the thrift store I found another one of these 12V Igloo electric coolers. They have a 35W Peltier cooler installed in them and can keep food and drinks nice and cold even on a warmer day. This particular unit I managed to score for only $7.00, which I thought was a good deal.After getting it home and plugging it into 12V, I discovered that it didn’t work at all, so I decided that I was going to order a replacement cooler and make it a better unit, one that could potentially freeze things if I desired. I knew that the cooler wouldn’t need to run continuously, and not only do I need to just shoot for a target temperature, but I could introduce an energy saving mode where the cooler shuts completely off for a period of time in an effort to extent the overall run time.
I decided to use an arduino, a couple new fans, a couple of DS18b20 temperature sensors like this one:
Then there was the matter of obtaining a replacement peltier cooler. I found something rather interesting and neat at this eBay auction (click here). This cooler is a pre-cascaded unit, meaning that there are two modules operating in a cascade and they’re already the appropriate sizing offset and everything. It is thicker than a standard single layer module, but that’s okay. Check out the datasheet here:
Spec_TB-2-199-199-0.8Right now I’m just using a relay to switch the cooler on and off, along with the fans. I’m using a PWM output pin on the Arduino to actually drive the speed control on the external fan. For now at least, the internal fan is at a fixed low speed.
I ran the cooler overnight, and the temperature sensor said that it was 49*F inside the cooler. When I measured the temperature of the water using a thermometer, it said it was 36*F. Clearly the air inside the cooler, or the internal sensor as a result of being affected by the warmer air outside is creating warmer readings and doesn’t accurately represent the temperature of the contents inside. For now I just picked my cutoff temperatures to be in an area where I know the food will remain very cold but not frozen. I’m not sure totally how I’m going to remedy / improve the temperature measurement inside. We’ll see how it works for now. Here is my laptop doing some datalogging of the cooler, checking out the functionality:
One of the other things you’ll notice is how low the voltage is, 10.8 while the cooler is drawing a 5.5amp load from a power supply outputting 12.5 volts. I need to put the voltage sense wire at the actual power socket itself, but clearly there are some losses in the 16 gauge wire that I’m using inside the unit. The feed cord which is 6 feet long is also 18 gauge, so there are some losses there. This skews the results, but we can adjust our calibration values to match. For example, when you look at the code, you’ll notice that the voltage when it goes into “high power” mode is set to 12v, this is actually about 13 at the battery, which is only attainable during a charge state or while the vehicle is running. If I change the cord / wiring around, it’ll be interesting to measure and see how the voltage changes. At Its peak, it draws around 5.5 – 6 amps, and around 4.5amps in the lower power modes after the internal temperature is cold.
Here is the code that runs on the arduino for the cooler controller. It’s probably what most would consider rudimentary, I am not terribly experienced when it comes to coding, but it works quite alright, so there is that..
/* * Cooler controller one wire TEC control * * PINS: * pin 2: One wire bus for temperature sensors * pin 3: Output transistor to switch on and off relay * pin 5: External fan PWM wire * pin A0: Voltage divider to measure input voltage * * Sensor index 0 is external sensor * Sensor index 1 is internal sensor */ // Include the libraries we need #include <OneWire.h> #include <DallasTemperature.h> // Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 2 // On/off output is on pin 3 #define outputrelay 3 #define extfanoutput 5 #define ADCIN A0 //Analog input pin for voltage sensing is on channel A0 int maxoutsidetemp = 170; //Maximum outside temperature in F int internaltarget = 46; //Internal target temperature in F int lowpowertarget = 49; //Internal target termperature in F when running in low power mode int externaltarget = 110; //Target external heatsink temperature int shutdowninterval = 90; //Amount of time in minutes that will pass before shutdown interval occurs int shutdownduration = 30; //Amount of time in minutes that the cooler will be shutdown for int extfanspeed = 70; //Fan Speed in percent, default is 70% int hysteresis = 5; //hysteresis period float voltagecutoff=8.5; //Shut down cooler when it's below this voltage float powersavecutoff=12; //Start power saving when voltage is below 12 float adccalibration = 6.2; //ADC calibration for reading the voltage divider int currentexternaltemp=0; // Current temperature variables. int currentinternaltemp=0; int shutdowntimer=shutdowninterval; //Where the current timer is stored, initialized with the shudowninterval float voltage=0; // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); void displaystatus(){ Serial.print(voltage); Serial.print("V. EXT: "); Serial.print(currentexternaltemp); Serial.print("*F INT: "); Serial.print(currentinternaltemp); Serial.println("*F."); return; } void getsensors(){ Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); // Send the command to get temperatures currentexternaltemp = sensors.getTempFByIndex(0); //Get temperature and store it in the external temperature variable currentinternaltemp = sensors.getTempFByIndex(1); //Get temperature and store it in the internal temperature variable voltage=analogRead(ADCIN); //Read the analog value of input voltage and store it voltage = ((voltage*3.2)*adccalibration); voltage = voltage/1000; return; } void setexternalfanspeed(int percentspeed){ analogWrite(extfanoutput,map(percentspeed,0,100,0,255)); return; } /* * The setup function. We only start the sensors here */ void setup(void) { // start serial port Serial.begin(9600); //Set serial speed Serial.println("Doogielabs portable fridge controller"); pinMode(3,OUTPUT); // Tell arduino that we want to use this pin as an output digitalWrite(3,HIGH); //Turn cooler off by default // Start up the library for the temperature sensors sensors.begin(); setexternalfanspeed(extfanspeed); // Default fan speed is 70% } /* * Main Program Loop */ void loop(void) { // call sensors.requestTemperatures() to issue a global temperature // request to all devices on the bus getsensors(); // Get Sensor data if(currentexternaltemp>maxoutsidetemp){ //If the max temperature outside is exceeded, shut down cooler digitalWrite(outputrelay, HIGH); //Turn off cooler for(;;); // Loop infinitely after to ensure cooler does not turn on again until power is reset } displaystatus(); if(voltage<powersavecutoff){ //If cooler is on and in powersave mode, adjust fan speed if(currentexternaltemp > externaltarget)extfanspeed+=15; if(currentexternaltemp < externaltarget)extfanspeed-=5; if(extfanspeed<1)extfanspeed=0; //Impose upper and lower limits if(extfanspeed>100)extfanspeed=100; } if(voltage>powersavecutoff && outputrelay==LOW)extfanspeed=100; //If cooler is not in power save mode and is on, balls to the wall if(voltage<voltagecutoff){ //If voltage is below the cutoff threshold digitalWrite(outputrelay, HIGH); //Turn off the cooler for(int i=60; i>1; i--){ //Repeat 60 times for a total off wait time of 1 hour delay(60000); //Wait 60 seconds Serial.println("Low voltage cutout mode"); getsensors(); } } if(voltage>=powersavecutoff && (currentinternaltemp+hysteresis)>internaltarget){ digitalWrite(outputrelay,LOW); //Power on cooler and attempt to reach coldest possible desired temperature shutdowntimer=shutdowninterval; // Reset shutdown timer for power saving mode, as we have no need to save power Serial.println("Powersaving mode disabled"); } if(shutdowntimer==0){ // When the shut down timer interval is reached shutdowntimer=shutdowninterval; //Re-intitalize the shutdown timer digitalWrite(outputrelay,HIGH); // Turn off cooler module for power saving mode. for(int i=shutdownduration; i>0; i--){ Serial.print("Low voltage power mode "); //Spit out the time remaining on the debug port Serial.print(i); Serial.print(" minutes remaining."); getsensors(); // Get sensor data displaystatus(); // Display current status delay(60000); // Delay for 1 minute and then continue low voltage power mode } } if(currentinternaltemp<=internaltarget)digitalWrite(outputrelay,HIGH); //Shut down system at desired temp if(voltage<=powersavecutoff && currentinternaltemp <= lowpowertarget)digitalWrite(outputrelay,HIGH); // Shut down system in low power mode at desired temp if(currentinternaltemp > lowpowertarget+hysteresis && voltage<=powersavecutoff){ digitalWrite(outputrelay,LOW);// Startup system at low power target temp Serial.println("Low Power target mode active"); } shutdowntimer --; //Decrement shutdown timer by 1 Serial.print(shutdowntimer); Serial.println(" Minutes remaining until power off."); setexternalfanspeed(extfanspeed); //Write out the fanspeed Serial.print("External Fanspeed percentage: "); Serial.println(extfanspeed); delay(60000); // Delay for 1 minute then and do loop again }
There are definitely some things I’d love to do differently, such as:
- Picking up voltage monitoring from the power input port
- Using 4 wire fan PWM to also control the internal fan to help run a defrost cycle / adjust cooling
- Adjusting the code to monitor temperature changes at a frequency more often than a minute.
- Not using linear voltage regulation and instead a switching converter for lower power.
- Eliminating the relay and using a FET to switch the cooler on and off.
- Ditch the arduino and utilize a PIC microcontroller instead
I am not done with the code yet, expect it to be updated again / change over the next couple weeks. I may even accomplish some of the above goals.