Introduction: Air Source Heat Pump Robot - Brain Implant - Arduino
I recently installed an air-source heat pump for water heating system. Usually, they cost around 10000 EUR/USD, but I got used and Chinese made one for just 500 EUR/USD. As you probably know you should never buy used heat-pump, fridge etc., just because owner bought a new one. Usually, they do not break often and if they do or they have some other problem, only then the owner would sell it (if he is evil..). Anyway, I did not consider this and was willing to risk. Also important to notice is that I am living in northern part of Europe (Latvia), so in winters we get temperatures below 15-20°C / -5°F . Air source heat pump might not be the most effective, but it is more effective than for example shallow ground (2m) heat pump that would freeze up the whole yard till summer. Maybe deep bore (+100m) heat pump would be more effective + much more expensive.
Now when we fixed minor problems, like replacing water circulation pump and some leaks in freon system, everything was working fine, but as soon as the ambient temperature was close to water freezing point -5°C till 5°C Heat pump's radiator began to froze-up. As I tracked down the problem I understood that Chinese microcontroller improperly executed defrost cycles. It almost did not execute them at all. Also as this manufacturer do not provide any information about the microcontroller, I had to create my own control panel/microcontroller for the whole system.
After implementing new control panel, I can control every aspect of heat-pump using PC and now it is also much more economic than before and do not build-up ice.
Also, I added an external sensor ("robot eye") that is tracking how much ice has been build upon external radiator/evaporator.
Step 1: Understand Heat-pump
In order to explain how heat-pump works I created interactive animation on my website here: http://yellowrobot.xyz/heat-pump-diag/index.html
I also recommend watching my video on youtube about this yellowrobot.xyz project:
The heat pump uses a physical process of convection to transfer heat using pressurization and de-pressurization. It works exactly like a fridge but its result is heat not cold.
Basically, at winter time, normal operation of an air-source heat pump is following:
- Heating mode
- Freon (R134a) is flowing through the system as shown in an image. Cold freon is being pressed into TXV valve at high pressure where it expands freon at low pressure and drops its temperature drastically. For example to -15°C.
- Now freon Temperature is below ambient temperature. For example, ambient temperature is -10°C.
- Then freon evaporate in evaporator/radiator. The fan helps to speed-up heat exchange.
- During this process, freon absorb heat difference from outside and it heats up to for example -11°C.
- The system has just gained 4°C in energy from ambient temperature.
- Then freon is more in gaseous state than liquid state at low pressure and it is compressed using compressor to high pressure at 60°C
- Then using heat-exchanger heat from freon is transferred to water circulation system
- At normal operation Efficiency (COP = 3) might be much higher than simple oil/coil electrical heaters (COP = 1)
- TXV valves automatically/mehanically adjust depending on outside temperature.
- A great resource about TXV valves: http://www.emersonclimate.com/Documents/FlowContr...
- Ice build-up
- At winter time when ambient temperature are close to 0°C or below often evaporator radiator gets icy because during convection process moisture from air will be attracted to radiator (similarly, like air-conditioner attracts moisture)
- When this happens freon coming out of evaporator/radiator is more in a low-pressure liquid state than gaseous state and cause a compressor to work harder thus it will make much higher electricity bills and reduce a lifetime of the compressor.
- Also as air flow is blocked by ice around the radiator, no heat is extracted from outside. Temperature of freon do not change much by passing through frozen evaporator.
- Efficiency (COP <= 1) of heat-pump drops drastically.
- Defrost mode
- When ice has been detected 3 way/4 way valve is reversed and flow in the system starts to go in other direction. It is extracting heat from inside home and bringing it to external evaporator/radiator to melt ice. During this mode, TXV valve is not important.
- Usually, if ice-build up is detected in a timely fashion it should not take more than 2min to melt whole ice.
- Ice build up can be detected using various sensors like:
- Air-flow differential sensor
- Optical sensors
- Pressure differential sensors in freon pipes
- Just using ambient temperature and simple timer
Step 2: Problem Before
My heat pump that was designed in China used ambient temperature and simple timer to initiate defrost cycle/mode. Unfortunately, they did not manufacture it for the north European climate. Here in Latvia, during winter when outside temperatures are around +5 °C till -5°C we have very moist air that causes huge ice buildup on evaporator/radiator. Interestingly that this heat pump worked much better at temperatures -15°C till -20°C when the air is dry and cold. During this time I had no problems with it and it produced very good efficiency results.
I tried many things to diagnose problems and to hack it, but it was not possible to re-program microcontroller, so I had to devise a plan to replace it all together.
Otherwise, I had to manually wire up defrost mode hack every time heat pump was totally frozen. It was at least 2 times a day + electricity bill was awful when outside temperature was +5 °C till -5°C
Step 3: Build Your Own "brain" Transplant
All source code and Fritzig scheme of circuit is available here on GitHub:
https://github.com/evaldsurtans/heat-pump-arduino-...
Robot "eye"
In order to detect ice buildup, I used an idea from line follower robots that have IR sensor for detecting black line on the surface against a white background. As ice is more or less white when formed on evaporator/radiator I can use this sensor's analog value to discriminate when it should initiate defrost mode/cycle. IR line detecting sensor is just IR diode emitting IR light and other IR diode absorbing reflected light of surface. To secure it from water exposure I used layers of hot glue.
Relays
Luckily inside heat pump's cover, I found circuit diagram that helped me to understand the operation of the system. The heat pump actually uses chained realys where 220V 6A AC relays at controller board trigger next huge 220V 16A AC relay relay downstream. These huge relays then start the compressor, fan, internal heater, valve solenoids, etc. As these are quite powerful they create EMI (Electro-Magnetic Interference), so it is essential to separate them as much as possible from microcontroller circuit. In the end, I used a seperate power source for first layer of relays (220V 6A AC) and triggered them using NPN transistors and Optron/Opto-couplers or Opto-transistors. These then created optical connection between relays and microcontroller. Otherwise there are a lot of problems that might occur as I described them in next step of this instructable.
Microcontroller
As for microcontroller I used original Arduino Mega 2560. I also tried Chinese clone Arduino Mega 1280, but it caused chaos beyond imagination that I described in next step. Original Arduino Mega 2560 works very stable and robust.
PCB
As this is the only prototype I did not bother to produce custom made PCB, but instead, I used dotted soldering plate on which I created as many paths as possible. For other connections, I used jumper wires that are useful for quick testing of ideas and changes in design. If someone wants to replicate this I would advise to create custom PCB to avoid spaghetti of wires.
Temperature sensors
For measuring temperature I used pump's built-in temperature probes that are just dead simple thermo-resistors. I experimentally found its properties using linear regression, because there were no indications of its type. For more precise temperature measures I used also one wire sensors DS18B20 (coupled with 4.7K resistor).
Components needed
- Arduino Mega 2560
- Adafruit Micro-SD breakout
- Micro-SD card
- Power supply at 5V 1-2A (for relays)
- Power supply at 12V 1-2A (for microcontroller)
- Multiple 5V DC - 220V 6A AC Relays + rectifier diodes (flywheel diodes)
- Multiple NPN transistors + 1K ohm resistors
- Multiple Optocouplers / optrons LTV817 (Uis=5kV 35V 50mA >50% DIP4) + 220ohm resistors
- Multiple temperature sensors DS18B20 + 4.7K ohm resistor
- Optional RTC - DS1307 Real Time Clock breakout board
- Dotted PCB soldering plate
Code
Progam is the most important part of the project/brains. Main features of code are:
- Adaptive temperature in heating system depending on outside temperature & water circulation system's temperatures
- Interactive console mode using Serial library to query and set-up parameters, logging information, without reprogramming of chip
- SD card offline memory for operation in between resets and logging of all events and sensor readings
- Optional implementation of offline Real Time Clock module
- Reading all safety sensors like high, low-pressure switches
- Arduino internal voltage monitoring
- Arduino PWM Timer interrupt to keep correct time for operation and logging purposes
- Arduino watchdog interrupt to avoid crashing / hang-up of program
For programming Arduino I would advise using Visual Studio 2015 Community Edition and Visual Micro plugin that is fantastic for coding and debugging http://www.visualmicro.com/ . If you are skeptical and used to Arduino IDE you should try Visual Studio C/C++ auto-completion features. Also JetBrains plugin for C/C++ auto-completion is wonderful https://blog.jetbrains.com/dotnet/tag/resharper-c/
Useful code snippets from whole code on github:
SD card breakout
#include "SD.h" void setup() { if (!SD.begin()) { Serial.println("SD failed!"); } else { Serial.println("SD connected."); } } void testSD() { //if(SD.exists(fileNameHistory)) // SD.remove(fileNameHistory); File myFile = SD.open(F("test2.txt"), FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.print(F("Writing to test2.txt...")); myFile.println(get_full_datetime()); // close the file: myFile.close(); Serial.println(F("done.")); } else { // if the file didn't open, print an error: Serial.println(F("error opening test.txt")); } myFile = SD.open(F("test2.txt")); if (myFile) { Serial.println(F("test2.txt:")); // read from the file until there's nothing else in it: while (myFile.available()) { Serial.write(myFile.read()); wdt_reset(); //tell watchdog that you are still alive (must call in every <8 sec)<br> } // close the file: myFile.close(); } else { // if the file didn't open, print an error: Serial.println(F("error opening test.txt")); } }
Watchdog timer
#include "avr/wdt.h" wdt_enable(WDTO_8S); //restart arduino if there are no response in 8 sec wdt_reset(); //tell watchdog that you are still alive (must call in every <8 sec) void loop() { //do work wdt_reset(); }
Timer interrupts for keeping precise time in parallel of other code
http://astro.neutral.org/arduino/arduino-pwm-pins-...
#include "TimerThree.h"<br> Timer3.initialize(500000); // initialize timer1, and set a 1/2 second period Timer3.pwm(PIN_TIMER_3, 512); // setup pwm on pin 9, 50% duty cycle Timer3.attachInterrupt(timer_callback); // attaches callback() as a timer overflow interrupt
Reading voltage level from internal reference
long readVcc() { // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ADMUX = _BV(MUX5) | _BV(MUX0); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif <br>delay(2); // Wait for Vref to settle <br>ADCSRA |= _BV(ADSC); // Start conversion <br>while (bit_is_set(ADCSRA,ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both<br>long result = (high<<8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 <br>return result; // Vcc in millivolts }
In the end, I just had to replace controller panel and hook up all cables and start testing it.
Step 4: Learn From Mistakes & Iterate Design
EMI (Electro-Magnetic Interference) nightmare
During initial testing, I discovered that Arduino often restarted/reset itself after switching on and off largest components of the system like 150W Fan or Compressor. I tried many solutions to reduce EMI that I suspected caused these restarts:
- Ferrite rings to wires going out of relays - Did not work at all even though it helped other thinkers
- RC snubber circuit around relay contacts (shown in images) - recommended, but did not help
- Flywheel Rectifier diode in between relay contacts and pull down resistor for NPN transistor - very recommended to extend lifetime of relay and reduce sparks inside, but did not help with restart problems
- Electro-magnetic screen / Faraday cage using aluminum foil around microcontroller - did not help
Power source stability nightmare
As all of EMI solutions failed to stop frequent self-induced restart in Arduino Mega, I decided to separate power supplies for microcontroller and relay circuits. I initially used 2 second-hand power supplies from chargers 5V 1A. It did not help to reduce restarting so I added ridiculously many large capacitors to sustain power during interruptions when large relays downstream triggered. It did not help again.
Then I made a rational decision and bought two impulse power sources 5V 2A and 12V 2A. These will work even if 220V AC will drop briefly to 100V AC or its phase is not stable etc. Also, the super important experience I learned is that you should not power Arduino Mega with 5V DC. As they recommend VIN voltage must be at least 7-9V. I switched to 12V.
Optocoupler / optron solution
Then to eliminate any interference from relays I finally re-soldered circuit and added oOptocouplers / optrons. These are transistors that work by using built-in LEDs. They create an optical barrier between both circuits.
BTW I tested using 2 separate power sources and NPN transistors in between with common ground and it did not work. But of course using optocouplers it works beautifully.
Now after all of these modification restarts became much less frequent, but hey still occurred! :@ :@
Memory overflow nightmare
Another thought I had was that the problem occurred because of stack overflow because I used a lot of String objects. As I read about these scenarios here (great article): https://learn.adafruit.com/memories-of-an-arduino/...
I modified code so that it used as much as possible C type strings and avoided any direct heap-based String object concatenation calls.
Fake / Clone Arduino Mega 1280 nightmare
So first I started to implement Arduino Mega watchdog timer to make sure if it hangs up (that sometimes happened too) it would restart itself. Then I discovered that my Arduino Mega 1280 clone/fake had an old buggy bootloader that could not use watchdog timer at all! When watchdog timer interrupt triggered it caused complete hangup - only complete power cut helped to restart it. Then I discovered that this is a common problem to old Arduino Mega 1280 chips that were produced couple years ago and the solution is to rewrite bootloader:
http://www.gammon.com.au/forum/?id=11635
https://www.instructables.com/id/Burn-Arduino-Boot...
I could not stand it anymore so I just bought expensive original Arduino Mega 2560 and after replacement no resets, hangups occurred anymore! Also watchdog interrupt is working fine, but it never has been triggered, except when I induced it.
So the conclusion is that if you do not want many nightmares do not use clone Arduino modules from dx.com, aliexpress, ebay etc.
BTW I also had to remove RTC module (that was also Adafruit clone), because it malfunctioned too :) I made changes in code so that I do not need to use it, but it could still be optionally added and it could be beneficial to keep more precise time.
Step 5: Future Improvements
Manual control/status panel inside building
It could be implemented using another Arduino microcontroller and they both could communicate using Serial cable: http://robotic-controls.com/learn/arduino/arduino...
It also could be possible to attach readings from electricity usage meter to this control block in order to monitor electricity usage and adjust exact temperatures when built-in electric heater could be used to assist heating. Currently, I do not use it at all, but I plan to implement threshold temperature below which it should be used because compressor would be less efficient. This temperature could be around -20°C. We did not experience such temperatures this winter so I could not collect enough data.
IoT connectivity
Another cool feature could be to connect it to a local WiFi network and log it onto web service. This can be achieved with WiFi Arduino modules that are abundant nowadays. It could then also be controlled via web service and it could warn me using my phone about any problems in operation.
More sensors
Other sensors that could be employed to improve heat-pump operation:
- Moisture sensor
- Air flow sensor
- Water circulation flow sensors
- Heating capacity sensors inside water circulation system
- Electricity usage counter
Water circulation pump upgrade
In this system, the previous water pump was broken so I installed a new one and it is not very powerful. In result, we have too big difference between incoming and outgoing water temperature in the heat exchanger. Currently, it is around 5°C, but with a more powerful pump, it could be as low as 1°C. Also, this pump should be controlled with internal microcontroller so the more powerful mode is active only when heat is being generated, but during normal water circulation low power mode should be used.
More analytics
I have attached very interesting graphs that were extracted from statistics stored on SD card. They show heating and defrost cycles depending on ambient temperature and ice accumulation on evaporator radiator. Ice sensor value ranges between 800-300. The lower value means more ice. It is clearly visible that when a temperature is lower then ice forms less, but it forms more when a temperature is closer to 0°C. When a temperature is above +5°C or below -5°C ice is formed more seldom. Also, it is possible to see that evaporator temperature is proportional and below an ambient temperature which indicates good operation of the system. I have also checked superheat value from these numbers and pressure readings on device itself and those are also matching.
Check out my other robot projects here:
http://yellowrobot.xyz/