Close

This one's a dry read...

A project log for RV Rooftop A/C MPU Replacement

This project chronicles the successes, and frustrations to defeating the securities put in place by RV appliance manufacturers.

daniel-rosemanDaniel Roseman 08/16/2014 at 17:490 Comments

So here is the code, and since Hackaday.io doesn't support the code html flag, I will just give it alot of space before I start it and after. I will also eventually share this code on github as well. All of the regular gnu rules still apply. Keep my name on in and if you repost it give me cred. Otherwise enjoy! Oh, and if you have suggestions feel free to drop me a line. I am very approachable like that! ;)

/*
Atwood RV Air Conditioner Controller

This program is designed for an Arduino ProMicro 5V/16MHz from sparkfun.com

software designed, built, and hardware modified by Daniel Roseman 2014 August 13th
*/

#include <EEPROM.h>
#include <avr/wdt.h>


// Defining Variables
int of = 4; //Outdoor Fan Command pin = 4
int heat = 5; //Heat command pin = 5 (PWM)
int comp = 7; //Compressor command pin = 7
int ifa = 8; //Indoor Fan A command pin = 8
int ifb = 9; //Indoor Fan B command pin = 9
int id = A0; //Indoor Coil Analog Input pin = A0
int od = A1; //Outdoor Coil Analog Input pin = A1
int rm = A2; //Room Air Analog Input pin = A2
int oa = A3; //Outdoor Air Analog Input pin = A3
int cool = 14; //12v Cooling command from RV controller
int lfan = 15; //12v Low Fan command from RV controller
int hfan = 16; //12v High Fan command from RV controller

// This setup routine runs once anytime the device starts from scratch
void setup() {
wdt_reset(); //reset watchdog
Serial.begin(300); // open the serial port at 300 bps:
pinMode(of, OUTPUT); // Outside Fan
pinMode(heat, OUTPUT); // Electric Heater
pinMode(comp, OUTPUT); // Compressor
pinMode(ifa, OUTPUT); // Inside Fan Output A
pinMode(ifb, OUTPUT); // Inside Fan Output B
pinMode(id, INPUT); // Indoor Coil Sensor
pinMode(od, INPUT); // Outdoor Coil Sensor
pinMode(rm, INPUT); // Return (Room) Air Sensor
pinMode(oa, INPUT); // Outdoor Air Sensor
pinMode(cool, INPUT); // Cool Call Input
pinMode(lfan, INPUT); // Low Fan Call Input
pinMode(hfan, INPUT); // High Fan Call Input
wdt_enable(WDTO_2S); //Enable watchdog for 2 second delay
if(analogRead(od) > 560){
powerfailSafety();//If outdoor coil temp is above 56c then the outside coil is VERY hot and the compressor "may" have been operating not too long ago. Call powerfailSafety().
}
if(EEPROM.read(1) == 1){
powerfailSafety2(); //If EEPROM address 1 reads "1" on power up then most likely the power failed while compressor was operating. Call powerfailSafety2().
}
}

//Start of Main Loop
void loop() {
wdt_reset(); //reset watchdog
if(analogRead(od) > 795){
hightempSafety(); //If outdoor coil goes above 79.5c, call hightempSafety().
}
if(analogRead(rm) < 150 || analogRead(id) < 200){
freezeSafety(); //If room air temp goes below 15c or indoor coil temp goes below 20F, the call freezeSafety().
}
delay(1000); //delay 1 second
wdt_reset(); //reset watchdog
Serial.print("Indoor Coil = ");
Serial.print(analogRead(id) / 10);
Serial.print("F");
Serial.print("\t");
Serial.print("Outdoor Coil = ");
Serial.print(analogRead(od) / 10);
Serial.print("C");
Serial.print("\t");
Serial.print("Intake Air Temp = ");
Serial.print(analogRead(rm) / 10);
Serial.print("C");
Serial.print("\t");
Serial.print("Outdoor Air Temp = ");
Serial.print(analogRead(oa) / 10);
Serial.print("C");
Serial.print("\t");
Serial.print("Compressor Call = ");
Serial.print(digitalRead(cool));
Serial.print("\t");
Serial.print("Fan Call Low = ");
Serial.print(digitalRead(lfan));
Serial.print("\t");
Serial.print("Fan Call High = ");
Serial.print(digitalRead(hfan));
Serial.print("\t");
Serial.println(" ");

if(digitalRead(cool) == LOW && digitalRead(lfan) == LOW && digitalRead(hfan) == LOW){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
if(EEPROM.read(1) == 1){
EEPROM.write(1, 0);
compressorLockout();
}
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == HIGH && digitalRead(hfan) == LOW) {
digitalWrite(of,HIGH);
digitalWrite(comp,HIGH);
digitalWrite(ifa,LOW);
digitalWrite(ifb,HIGH);
if(EEPROM.read(1) == 0){
EEPROM.write(1, 1);
}
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == LOW && digitalRead(hfan) == HIGH) {
digitalWrite(of,HIGH);
digitalWrite(comp,HIGH);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
if(EEPROM.read(1) == 0){
EEPROM.write(1, 1);
}
}
if(digitalRead(cool) == LOW && digitalRead(lfan) == HIGH && digitalRead(hfan) == LOW) {
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,HIGH);
if(EEPROM.read(1) == 1){
EEPROM.write(1, 0);
compressorLockout();
}
}
if(digitalRead(cool) == LOW && digitalRead(lfan) == LOW && digitalRead(hfan) == HIGH){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
if(EEPROM.read(1) == 1){
EEPROM.write(1, 0);
compressorLockout();
}
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == LOW && digitalRead(hfan) == LOW){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
if(digitalRead(cool) == LOW && digitalRead(lfan) == HIGH && digitalRead(hfan) == HIGH){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == HIGH && digitalRead(hfan) == HIGH){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
}

//This routine is called when the Arduino detects that it has been reset due to a power failure via the temperature sensors
void powerfailSafety(){
wdt_reset(); //reset watchdog
if(analogRead(id) < 420){
delay(1000); //delay 1 second
wdt_reset(); //reset watchdog
digitalWrite(of,HIGH);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
Serial.print("POWER FAIL SAFETY!");
Serial.println(" ");
Serial.print(analogRead(id));
}
return;
}

//This routine is called when the Arduino detects that it has been reset due to a power failure via the value written in EEPROM
void powerfailSafety2(){
wdt_reset(); //reset watchdog
for(int timer = 200; timer > 0; timer--){
delay(1000); //delay 1 second
wdt_reset(); //reset watchdog
digitalWrite(of,HIGH);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
Serial.print("Power Fail Safety Timer = ");
Serial.print(timer);
Serial.println(" ");
Serial.print("You are seeing this message due to the fact that the A/C thinks the power was removed while in operation.");
}
return;
}

void hightempSafety(){
wdt_reset(); //reset watchdog
for(int timer = 200; timer > 0; timer--){
delay(1000); //delay 1 second
wdt_reset(); //reset watchdog
digitalWrite(of,HIGH);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
Serial.print("High Temp Safety Timer = ");
Serial.print(timer);
Serial.println(" ");
Serial.print("You are seeing this message due to the fact that the outdoor coil temp is too high.");
}
return;
}

void freezeSafety(){
wdt_reset(); //reset watchdog
for(int timer = 720; timer > 0; timer--){
delay(1000); //delay 1 second
wdt_reset(); //reset watchdog
digitalWrite(of,HIGH);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
Serial.print("Freeze Safety Timer = ");
Serial.print(timer);
Serial.println(" ");
Serial.print("You are seeing this message due to the fact that the indoor air temp or indoor coil temp is too low.");
Serial.println(" ");
Serial.print("This is usually because the indoor coil has reached a temperature that has caused ice to form on it.");
}
return;
}

void compressorLockout(){
wdt_reset(); //reset watchdog
for(int timer = 200; timer > 0; timer--){
delay(1000); //delay 1 second
wdt_reset(); //reset watchdog
digitalWrite(of,HIGH);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
Serial.print("Compressor Lockout Timer = ");
Serial.print(timer);
Serial.println(" ");
Serial.print("You are seeing this message because the compressor has been turned off for less than 10 minutes.");
Serial.println(" ");
Serial.print("This is a safety lockout to let the pressure that has built up in front of the compressor drain.");

if(digitalRead(cool) == LOW && digitalRead(lfan) == LOW && digitalRead(hfan) == LOW){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == HIGH && digitalRead(hfan) == LOW) {
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,HIGH);
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == LOW && digitalRead(hfan) == HIGH) {
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
}
if(digitalRead(cool) == LOW && digitalRead(lfan) == HIGH && digitalRead(hfan) == LOW) {
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,HIGH);
}
if(digitalRead(cool) == LOW && digitalRead(lfan) == LOW && digitalRead(hfan) == HIGH){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,HIGH);
digitalWrite(ifb,HIGH);
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == LOW && digitalRead(hfan) == LOW){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
if(digitalRead(cool) == LOW && digitalRead(lfan) == HIGH && digitalRead(hfan) == HIGH){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
if(digitalRead(cool) == HIGH && digitalRead(lfan) == HIGH && digitalRead(hfan) == HIGH){
digitalWrite(of,LOW);
digitalWrite(comp,LOW);
digitalWrite(ifa,LOW);
digitalWrite(ifb,LOW);
}
}
return;
}

Discussions