Toxicantidote 12v fridge rebuild
Advertisement
Advertisement

12v fridge rebuild

March 2024

Recently my Evakool 55L vehicle fridge stopped cooling properly. Further investigation revealed that the temperature sensor was not operating correctly. The temperature reading would randomly plummet to -30°c or so in a matter of seconds, even though the fridge compartment was closer to +30°c. I've tried spoiled food, and it doesn't agree with me.

The teardown

The control circuitry and compressor for this unit are housed behind a vented panel at the bottom rear of the unit. It consists of a compressor with attached controller, condenser coil with cooling fan and a small control panel PCB. As expected, the compressor sits on shock mounts to reduce its noise.
Inside the compressor/electronic enclosure area

At the heart of this system is the very common ZH25G compressor, which is used in a range of 12/24v fridges from various brands. This compressor has a cooling capacity of between 45W and 75W and uses the extremely common R134a refrigerant. Controlling the compressor is a model ZY-CC150DC12/24V-B3 control board from an unknown manufacturer. This controller looks to be near-universal for 12/24v fridges, as it is capable of controlling a range of DC compressors. The only major variation I have been able to find is a Danfoss model that also incorporates an AC-DC power supply so the fridge can be powered from mains. My guess is that the compressor, condenser and controller are sold as a single OEM unit to a range of manufacturers for them to integrate in to their products.
The compressor controller module (outside)

Inside the controller enclosure is a conformally coated PCB. It is a bit hard to tell with the coating, but it looks as if some or all of the IC labels have been ground off to try and hamper reverse engineering efforts. No matter, we can simply interface with the controller itself.
The compressor controller module (inside)

The control panel PCB is relatively simple, with an STM STC15W408AS as the brains of the operation. It is an improved 8051 based MCU, presumably chosen for its wide voltage range, low power usage, noise tolerance and mature toolchain. Other than the MCU, the control panel PCB has two buttons for temperature control, two 7 segment displays for temperature display, a linear regulator for power and basic circuitry for interfacing with the compressor controller. I did notice something that looks suspiciously like an programming or debugging header, but I wasn't game to go down the firmware reverse engineering rabbit hole.

Front of the stock displayBack of the stock display

Connection between the control panel PCB and compressor controller consists of four lines. Two are for power, one is to set compressor speed, and the other is to read fault flash codes from the compressor controller. The inbuilt NTC thermistor connects at the other end of the board (the two black wires in the picture above).

Interfacing

Unfortunately there is not detailed information on this controller readily available, so the information below has been compiled by trawling through various incomplete sources as well as my own testing.

Compressor controller pinout

Below is a listing of the compressor controller interface pins and their function from top to bottom of the compressor controller (when mounted on the compressor):

LabelFunction
-Ground
+12/24v supply
F+12v to condenser fan
F-Fan ground
DFault LED
CCommon for P and T terminals
PBattery protection setting
TNTC thermistor connection

Lets dive in to each of those..

- and +

This one is pretty straighforward. It is the 12v or 24v DC supply to run the compressor and controller.

F+ and F-

This provides power for a 12v fan fitted to the condenser coil. Note that even when the system is running from a 24v supply, these pins will output 12v for the fan. Output is limited to 500mA continuous, with a 1A allowance for start-up inrush current. Exceeding this current limit will cause the controller to turn off the fan output completely and report a fan fault. More on this later.

D

Designed for the cathode of an LED (with the anode connected to the supply via a resistor). Pulled low for 250ms increments a number of times depending on the fault, and then repeated every 4s. Below are the number of flashes and the corresponding fault:

Number of flashesFault
1The supply voltage is too high or too low (as set by the battery protection settings). Usually means your battery powering the fridge is going flat.
2Fan over current or too many compressor restarts in a short space of time. Triggered if your fan has seized up. May trigger if you replace the fan with one that is too powerful (more on this later).
3Compressor over current. Could be a faulty compressor, controller or blocked refrigerant tubes.
4Compressor cannot maintain speed. Same reasoning as three flashes, except this could possibly be caused by a power supply (or cabling) that can't deliver enough current to the unit.
5Controller overheated. Something has probably gone wrong with the compressor controller, or you are operating somewhere very hot without much ventilation.

C

Common point for connection to P and/or T terminals via appropriate resistor. More on that below.

P

The value of this resistor (between C and P terminals determines the voltage at which your fridge will shut down due to low voltage. The over-voltage setting is not configurable. Values are per the below table. I have not tested the behaviour of intermediate values, but I assume it would follow a curve between the two nearest values? In my fridge, this terminal is left unused. Since I am using my fridge in 12v mode, this means my fridge will shut down below 11v and only restart when the voltage is above 12.3v again. Additionally, it will shut down if the voltage is above 17v.

Resistor value (ohms)12v system24v system
Cut-out (volts)Cut-in (volts)Maximum (volts)Cut-out (volts)Cut-in (volts)Maximum (volts)
09.610.91721.322.735
16009.71121.522.9
24009.911.121.823.2
360010.011.32223.4
470010.111.422.323.7
620010.211.522.523.9
820010.411.722.824.2
1100010.511.82324.5
1400010.611.923.324.7
1800010.81223.625
2400010.912.223.825.2
33000
or not fitted
1112.324.125.5

T

This port is designed for connection to either a 5kΩ potentiometer, 5kΩ NTC thermistor or thermal switch to be connected between C and this port. It controls the compressor speed. The values quoted below are for the ZH25G compressor. Other compressors will require different values for control. In my fridge, this loop has 523Ω resistance, corresponding to a compressor speed somewhere between 2600RPM and 3000RPM.

Compressor speed (RPM)Resistance ΩLoop current in mA (between C and T)
20000 (short circuit)5
2100514.8
22001004.6
23001504.4
24002004.2
25002774
26003303.8
30006923
31008162.8
32009632.6
330011372.4
340013312.2
350015232
Stop>3000 or open circuitN/A

Existing thermal sensor

This is nothing special. Just a 5kΩ@25°c NTC thermistor. As stated before, this part is defective. I tried to see if I could replace this to get things going again but it is very deeply embedded in to the body of the fridge. Without knowing where the refrigerant lines to the evaporator line run, I'm not game to try and excavate it. Besides, that's not a very fun hack.

The rebuild

So, an excuse to rebuild. What do I want from this fridge?

Obviously the first thing is is needs to cool things at least as well as it did before. If at all possible, I'd like to make it cool more effectively. After that, I want a control panel that shows me the current and set temperatures at the same time. And finally, I'd like it to interface via Wi-Fi with my existing status display head solution I have made for my car.

Sections needed

To pull this off, I'm going to need:

  1. An MCU paired with a screen and some buttons
  2. A circuit to set the compressor speed using variable resistance
  3. A circuit to watch for and interperet any fault codes from the compressor controller
  4. A DC-DC regulator to step down from 12/24v to whatever voltage the MCU and screen require

First, the MCU. I already had a Raspberry Pi Pico W laying around doing nothing. This comes with Wi-Fi, a few ADC channels and is supported by CircuitPython. I find Python much easier to code with than C and its derivatives. Plus CircuitPython has commercial backing that ensures it has a wide range of libraries available.

Ok, so it's going to be a Pico W, and it's going to run CircuitPython. Next up, the display. To start, I made a quick list of display controllers supported by CircuitPython. I then headed to an online bazaar to see what I can pick up. I found an SH1106 based OLED monochrome display, which was a rather fitting light blue on black. Since this particular bazaar has a minimum order value, I also tacked on some waterproofed DS18B20 temperature sensors, hoping to have a quick and easy time polling a device digitally, rather than working with an NTC thermistor. To finish off my order, I also picked up some tiny DC-DC converter modules.

Unfortunately for me, both of the DS18B20 sensors I received did not seem to work, even with the required pull-ups. After further research, I concluded that these were either faulty, or counterfeit parts. Oh well, back to an NTC thermistor.

Characterising the NTC

On the surface, an NTC seems pretty simple. Just make a voltage divider with it and read the divider voltage to determine the temperature. A rabbit-hole of research ensued. The short version: NTC response is not linear, not even close. I guess this is why many applications use an NTC to determine if a specific temperature has been exceeded, rather than actually determining the exact temperature. You can easily find the resistance at one temperature, but finding the resistance at any temperature (or rather, the temperature at any resistance) is much less straighforward.

Thankfully, greater minds than mine have solved this. You characterise the response at three points, and then use the Steinhart-Hart equation to calculate three coefficients, which can later be used to translate resistance to temperature. There are even online calculators for this. Having said this, many thermistor manufacturers may provide three resistance/temperature reference points, or even the actual coefficients. Mine did not.

How do we apply this practically? With a 'good enough' approach. I soldered some wires to my NTC thermistor and wrapped the end in glue lined heatshrink to (hopefully) waterproof it. The wires from the NTC were then connected to a multimeter measuring resistance. With an off-the-shelf meat thermometer from the local discount store as my reference, I noted the ambient air temperature and corresponding resistance. Next I did the same measurement except after a minute or so in a cup of boiling water. Finally, I did another measurement after a minute or so in water filled with ice cubes.

TestTemperatureResistance
Ambient26°c9939Ω
(Almost) boiling water91°c1003Ω
Ice cooled water8°c24700Ω

I put these values in to the online calculator to get the three coefficients needed (A, B and C). To test these coefficients, I then calculated the temperatures based on the resistances alone with the equation: T = 1 / (A + B * log(R) + C *log(R)3) - 273.15) where R is the NTC resistance and T is the temperature (in degrees celsius). This equation was pulled from the source of the linked online calculator. Sure enough, the calculated temperatures were close enough to my measured temperatures.

To make this more maintainable for myself. I decided that I wanted to be able to simply define the temperature and corresponding resistance for three points at the top of my program on the MCU, and have the MCU work it out on the fly. After picking more equations from the source of the online calculator above, I ended up with the following two Python functions:


import math

def get_temperature(reference_voltage, adc_value, divider_resistor, coefficient_A, coefficient_B, coefficient_C):
    '''
        Gets the temperature of the NTC thermistor. Assumes the ADC has 63335 
        steps. Assumes the NTC goes to the reference voltage and the divider 
        resistor goes to ground.
        
        Arguments:
            reference_voltage - The maximum voltage that the ADC allows.
            adc_value - The ADC value (0-65535).
            divider_resistor - The value of the other resistor in a divider with
                the NTC.
            coefficient_x - The three coefficients from the Steinhart-Hart
                equation.
                
        Returns:
            Temperature in degrees celsius
    '''
    ## work out the resistance of the thermistor using ohm's law
    volt = reference_voltage - (reference_voltage * (adc_value / 65535))
    current = (reference_voltage - volt) / divider_resistor
    r_ntc = volt / current

    ## work out the temperature of the thermistor
    temp = (1/(coefficient_A+coefficient_B*math.log(r_ntc)+coefficient_C*math.pow(math.log(r_ntc),3))-273.15)

    return temp

def calculate_coefficient(a_r, a_c, b_r, b_c, c_r, c_c):
    '''
        Calculates the Steinhart-Hart equation to generate coefficients for the
        NTC given resistance/temperature pairs.
        
        Arguments:
            a_r, b_r, c_r - Resistance at arbitrary A, B and C.
            a_c, b_c, c_c - Temperature (degrees celsius) that correspond to the
                resistances given above.
                
        Returns:
            Steinhart-Hart equation coefficients A, B and C.
    '''
    ## convert to kelvin
    a_k = a_c + 273.15
    b_k = b_c + 273.15
    c_k = c_c + 273.15

    ## calculate coefficients
    c = ((1/a_k-1/b_k)-(math.log(a_r)- math.log(b_r))*(1/a_k-1/c_k)/(math.log(a_r)-math.log(c_r)))/((math.pow(math.log(a_r),3)-math.pow(math.log(b_r),3)) - (math.log(a_r)-math.log(b_r))*(math.pow(math.log(a_r),3)-math.pow(math.log(c_r),3))/(math.log(a_r)-math.log(c_r)))
    b = ((1/a_k-1/b_k)-c*(math.pow(math.log(a_r),3)-math.pow(math.log(b_r),3)))/(math.log(a_r)-math.log(b_r))
    a = 1/a_k-c*(math.log(a_r))*(math.log(a_r))*(math.log(a_r))-b*math.log(a_r)

    return a, b, c

This code assumes that the MCU ADC has 65535 steps, and that the NTC thermistor connects between the ADC reference voltage (usually the supply voltage) and the ADC pin, and then another fixed value (divider) resistor is connected from the same ADC pin to ground.

With that done, now I have the ability to measure temperature with 'good enough' accuracy for a fridge.

Making an MCU controlled variable resistor

No need to reinvent the wheel here. Digital potentiometers exist, and allow you to set said device to a specific resistance over an I2C bus. Unfortunately for me, I couldn't get the digital potentiometer I had to work. It would either stay at it's full resistance, or jump to a random resistance. Hours of frustrating attempts to debug it gave me nothing.

Do I really need fine-grained compressor speed control? Not really. Time for a simple albeit slightly cumbersome plan. Using the compressor speed table above I decide to aim to have three possible settings: off, low speed (2000RPM) and high speed (3500RPM). This means I need to have resistances of 0Ω, ≈1500Ω and ≥3000Ω available. For safety, low speed should be the default setting. Accidentally freezing food is generally safer than letting it get hot and spoil.

I use two SPDT relays configured as follows:

This gives me resistances of ≈0Ω (low speed), 1500Ω (high speed); and ∞Ω (off). I then built a quick relay driver and added a flyback diode, and the quick and dirty 'variable resistor' was ready to interface with my MCU.

Powering the system

This is pretty much done for me already. I connected the 12/24v input to my tiny DC-DC converter and adjusted it for 5v. 5v is then fed to the MCU VIN pin, and 3.3v is taken from the MCU's on-board voltage regulator.

Interpreting the flash codes

This should be as simple as watching for falling edges right? Yes, but CircuitPython lacks interrupts. Threads then? Also not supported. Polling? The MCU is too busy doing the display and Wi-Fi stuff to do that reliably.

My first thought was to use a 4000-series binary counter, and then feed this in to a buffer IC for the MCU to read when it is ready. The binary counter would be reset by a 555 timer circuit with a period slightly longer than the maximum possible amount of time taken to show a fault flash code (3.5sec, 5 flashes). I set about drawing this up, feeling proud that I'd found another oppurtunity to insert a 555 in a design and do things with discrete logic, rather than pressing another MCU to perform such a menial task.

The pride was short-lived though, when I came to the realisation that this was needlessly complex. I thought of the KISS (Keep It Simple, Stupid) principle, and the fact that the relatively complicated 'solution' would introduce many possible points of failure in the vibrating, electrically noisy and hot environment that is my car fridge. Also at this point I already had the MCU and display wired and in a printed case, with a finite number of wires terminating in to a neat plug that connected to a second PCB in another printed case for interfacing with the compressor controller. The complex method would require additional wires to be run. More mess, more tedium, more headaches and more waiting for prints.

So, I looked through my parts storage and found a postage stamp sized 32u4 based Arduino. It has USB for programming, it's supported by Arduino, it has a UART and hardware interrupts. I reconfigured the wiring on my compressor controller interface PCB. Instead of providing connections to relay drivers and the fault line, the interconnection to the MCU/display PCB now carried a UART connection and 3.3v supply.

This Arduino would be tasked with accepting commands from the main MCU to set the compressor speed relays via the UART interface, and reporting back any fault flash codes. Because the Arduino had some spare inputs, an RGB LED was also added to the second board for status indication. Last but not least, the Arduino talks at 5v, while the Raspberry Pi Pico W talks at 3.3v. Again I took the easy way out, and used a prefabricated level shifter PCB that I had in my parts collection.

Coding the Arduino

Now, as I mentioned earlier, C isn't my strong suit for programming, but I've cobbled together the necessary code to get the Arduino to act as a bridge to the compressor interface. I did initially experiment with using the SoftwareSerial library so I could keep the USB interface available for debugging, but for some reason I could not get the receive SoftwareSerial pin to actually see data. I had probed the pin on the Arduino with a USB-UART adaptor, and could see the commands arriving at the Arduino. Not wanting to exhaust more time, I simply switched back to the good-old hardware UART.


// pins where things are connected
#define PIN_INTERRUPT 2

#define PIN_LED_R 11
#define PIN_LED_G 10
#define PIN_LED_B 9

#define PIN_STATUS 13

#define PIN_RELAY_1 A0
#define PIN_RELAY_2 A1

// let the compiler know to expect flash count changes anytime
volatile unsigned char flash_count = 0;

// initialise other state variables
unsigned char last_flash_count = 0;
unsigned long last_flash_time = 0;
unsigned long keep_alive = 0;
char cmdByte;

void setup() {
  // set the pins to input or output as needed
  pinMode(PIN_INTERRUPT, INPUT_PULLUP);
  pinMode(PIN_RELAY_1, OUTPUT);
  pinMode(PIN_RELAY_2, OUTPUT);
  pinMode(PIN_LED_R, OUTPUT);
  pinMode(PIN_LED_G, OUTPUT);
  pinMode(PIN_LED_B, OUTPUT);
  pinMode(PIN_STATUS, OUTPUT);
  digitalWrite(PIN_STATUS, LOW);

  // cycle the RGB LED through red-green-blue
  digitalWrite(PIN_LED_R, HIGH);
  digitalWrite(PIN_LED_G, LOW);
  digitalWrite(PIN_LED_B, LOW);
  delay(200);
  digitalWrite(PIN_LED_R, LOW);
  digitalWrite(PIN_LED_G, HIGH);
  digitalWrite(PIN_LED_B, LOW);
  delay(200);
  digitalWrite(PIN_LED_R, LOW);
  digitalWrite(PIN_LED_G, LOW);
  digitalWrite(PIN_LED_B, HIGH);
  delay(200);
  digitalWrite(PIN_LED_R, HIGH);
  digitalWrite(PIN_RELAY_1, LOW);
  digitalWrite(PIN_RELAY_2, LOW);
  
  // attach the interrupt to watch for a falling edge on the interrupt pin
  attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT), isr_flash, FALLING);

  // start the UART
  Serial1.begin(9600);
}

void loop() {
  // turn off interrupts while getting the flash count so that the interrupt
  // handler doesn't run while we are getting the value
  noInterrupts();
  unsigned char fc = flash_count;
  interrupts();

  // get the current time (since starting) 
  unsigned long now = millis();
  unsigned long age = now - last_flash_time;
  unsigned long ka_age = now - keep_alive;
  
  // send a keepalive roughly every second
  if (ka_age > 1000) {
    Serial1.print(F("PING"));    
    keep_alive = now;
  }
  
  // give a 250ms buffer after a flash sequence before considering 'finished'.
  // (250ms on, 250ms off)
  if ((age > 750) || (fc > 5)) {
    noInterrupts();
    flash_count = 0;
    fc = 0;
    last_flash_count = 0;
    interrupts();
  }
  
  // if the flash count has increased since last loop, reset the timer
  if (fc > last_flash_count) {
    last_flash_time = now;
    last_flash_count = fc;
  } 

  // look for data on the serial line
  for (int i = 0; i < Serial1.available(); i++) { // if serial data is available to read
    digitalWrite(PIN_STATUS, HIGH); // turn on the inbuilt led
    cmdByte = Serial1.read(); // read it
    if (cmdByte == 0x0A || cmdByte == 0x53) { // if the character is an S or a newline
      Serial1.flush(); // clear the input buffer
      if (fc > 0) { // if there is an error..
        Serial1.print(F("STATUS ERROR ")); // start with an error message
        Serial1.print(fc); // then number of flashes
        Serial1.print(F(" "));
        // and then a description of the error
        if (fc == 1) {
          Serial1.println(F("Battery low"));          
        } else if (fc == 2) {
          Serial1.println(F("Fan fault or excessive restarts"));
        } else if (fc == 3) {
          Serial1.println(F("Compressor blockage"));        
        } else if (fc == 4) {
          Serial1.println(F("Compressor overload"));
        } else if (fc == 5) {
          Serial1.println(F("Over temperature"));
        } else {          
          Serial1.println(F("Unknown error"));
        }
      } else { // if there is no error
        Serial1.println(F("STATUS OKAY"));
      }
    } else if (cmdByte == 0x31) { // if 1 is received
      // set the compressor to low speed and led to green
      digitalWrite(PIN_RELAY_1, LOW);
      digitalWrite(PIN_RELAY_2, LOW);
      digitalWrite(PIN_LED_R, LOW);
      digitalWrite(PIN_LED_G, HIGH);
      digitalWrite(PIN_LED_B, LOW);
      Serial1.println(F("COMPRESSOR LOW"));
    } else if (cmdByte == 0x30) { // if 0 is received
      // set the compressor to off and led to red
      digitalWrite(PIN_RELAY_1, HIGH);
      digitalWrite(PIN_RELAY_2, LOW);
      digitalWrite(PIN_LED_R, HIGH);
      digitalWrite(PIN_LED_G, LOW);
      digitalWrite(PIN_LED_B, LOW);
      Serial1.println(F("COMPRESSOR OFF"));
    } else if (cmdByte == 0x32) {// if 2 is received
      // set the compressor to high speed and the led to blue
      digitalWrite(PIN_RELAY_1, LOW);
      digitalWrite(PIN_RELAY_2, HIGH);
      digitalWrite(PIN_LED_R, LOW);
      digitalWrite(PIN_LED_G, LOW);
      digitalWrite(PIN_LED_B, HIGH);
      Serial1.println(F("COMPRESSOR HIGH"));
    } else { // if the command is unknown
      // show some help
      Serial1.println(F("Unknown command. Commands:"));
      Serial1.println(F("S or newline - Get fault status"));
      Serial1.println(F("0 - Compressor off"));
      Serial1.println(F("1 - Compressor low speed"));
      Serial1.println(F("2 - Compressor high speed"));
    }
    // turn off the onboard led once the command has been processed
    digitalWrite(PIN_STATUS, LOW);
  } 
  // flush the serial buffer
  Serial1.flush();
}

// called by the falling edge interrupt on the fault pin
void isr_flash () {
  // keep it short and sweet, just increment the flash counter
  flash_count++;  
}

Upgrading the fan

A few weeks after my initial purchase of this fridge, a spot welded bracket broke off inside and lodged in the evaporator cooling fan, breaking two blades. Thankfully it did not pierce the evaporator coil. As with most equipment built to a budget, the fan was cheap and low powered, but it was at least a standard 120mm fan. I replaced this with a more durable and higher flow ebmpapst fan.

The compressor controller fan terminals didn't offer enough current to satisfy the demands of my new fan, so this was initially wired to the supply lines instead so that it was always on. Before the fridge failed the second time (to became the subject of this article), it had offered vastly improved cooling performance over the stock fan, at the expense of more noise. Because of the installtion location, this noise wasn't a problem. Since it was still going strong, this fan received a quick clean and returned to service.

Since I was modifying the wiring of the system anyway, I connected the fan to a relay controlled by the F+ and F- terminals, so that the compressor controller could regulate the operation of the fan again.

Final schematics

The system is split in to two sections. The first has the display, Raspberry Pi Pico W MCU, buttons and a buzzer. It runs the show. The second section with the Arduino and some interfacing circuitry exists to control the compressor speed and catch any fault codes from the compressor controller. I was not able to find any schematics for the compressor controller online.

Display/control section

Schematic of the display/control section

Compressor interface section

Schematic of the compressor interface section

Programming the build

With the system constructed on stripboard, it was time to start coding the display PCB. This photo was from before I had made a simple case for the boards. The NTC is inside the fridge compartment mounted near the top so it will not touch the sides or catch on the food basket when it is removed.
Replacement prototype connected for programming

The most important part of this build is getting to the target temperature. I started with basic logic for compressor speed based on the temperature control:

This worked ok, but has a tendancy to overshoot the set temperature. For example, if the set temperature was 2°c, this would quickly drop down to 2°c, with the compressor speed slowed and then stopped too slowly to avoid overshooting down to about -4°c. I don't always want my fridge to freeze items - it needs to be a fridge sometimes too, so I had to make a distinction. Additionally, the compressor speed would turn on and off frequently, which isn't terribly healthy for a compressor. To solve these two problems, I changed the compressor speed routine so it would only change speed every couple of minutes at most, and made the system use the five minute average temperature to decide the compressor speed. After a night of testing in an environment with a relatively stable temperature, this seemed to work. More on this later.

Fitting the build to the fridge

I cut down my stripboard to the used area, and then 3D printed a case for each of the circuit sections. Once this was done, I stripped out the stock control panel PCB and bezel and then cut the opening wider to fit my new control panel for the fridge. When designing my control panel, I deliberately inset the buttons and screens a few millimetres to avoid damage and inadvertent activation. The compressor interface circuit board was fitted in a space between the refrigerant line and the compressor with high strength double sided tape.

Below is a picture of the new display mounted in place. While I have included a bezel on the sides of the new display, I do regret not including a bezel on the top and bottom of the display to cover the metal cuts better. Also I am aware of the clear plastic layer that should be removed when new. It would not come off cleanly, and kept coming off in small sections, so I gave up and left most of it on. Parts of this fridge are pretty beaten up anyway.
The replacement display and control mounted in the fridge

Working in the real world

As anyone who has tried to build something before knows, something that works in a controlled environment doesn't always translate to the real world. This build is no exception. I tried leaving some drinks in the fridge overnight to cool them down. At this time of year, the night time temperature is rarely under 25°c. When I came out in the morning, I found that the fridge was cool, but not cold enough. Since I didn't have the time to fix it that morning, I set the temperature a bit lower and started driving.

For most of the day, my car sat in an outdoor carpark with no shade. Given the temperature was 38°c that day, it would be a decent test for the fridge. I came back a few times throughout the day and found that the fridge was cool, but not as cold as I had set it. Inspecting my display revealed in most cases that the compressor was off, and holding this setting (because of the rate limiting on speed changes). It would seem that my fridge was cooling as intended, and then resting for too long before keeping up the cooling.

So, another compressor speed logic change: If the temperature is above the five minute average, and above the set temperature, bump up the compressor speed one setting (off->low, low->high) for five minutes to try and get the temperature back down.

What's next?

At this stage I'm still trying to test my latest compressor speed logic change. I think I'll be fiddling with this for some time to try and get things right. Other than that, I'd like to redo the front face of the control panel to better hide the metal cuts, but it was such a pain to get the nuts on to the screws in the cramped compressor compartment that I may just live with it. There are still some weird little crashes now and then, but they seem to be associated with the display, rather than the control logic.

My code also uses the Wi-Fi function to connect to a wireless AP and in turn a status display screen in my car, but doesn't seem to have a reliable connection to the display unit. I will need to do further investigation to work out if this is a signal issue, or if it is some kind of issue with the wireless access point blocking or limiting the broadcast packets used to send messages to the status display head. I would also like the display to save the last set temperature. I did implement this feature, but found that often the attempt to remount the flash partition as read-write would cause the code to lock up, so I disabled the feature. Maybe in the future I will just add an SD card or external non-volatile memory to handle this. For now, I just default to 3°c.

Besides the code issues, it also remains to be seen how physically durable this new system is. It will be subject to a lot of heat, vibration and dust. Despite this, I am hopeful that it will still last me for years to come, and keep my otherwise working refrigerator from becoming a pile of scrap.

Where's the code?

I have the code for the compressor interface Arduino and controller/display head available as Gists. As with all of my Gists, It's not necessarily clean, commented or bug-free.