Close

To ATS or not to ATS

A project log for mrHAC

This future style Home Automation System is here to help simplify life without the hassle.

mr-incM.R. Inc 10/02/2015 at 22:520 Comments

Hello there!

I bring to you some great news, I finished my ATS(Automatic transfer switch) last night! Well the 3rd prototype anyway haha.

So, I shall share some photos for you :) ... and maybe a video.

This is the actual switch unit.

The right contactor (top right) is for mains.

The left one is for generator.

(The bottom 2 are the 12v relays)

How the relay and contactors are wired:

LIVE - RELAY SWITCH - CONTACTOR IN

NEUTRAL - CONTACTOR IN


The DB board above the box:

Power from contactors go into the left isolator.

Next to it are 2 surge protectors (L+N)

In the middle (the black thing) is a wire polarity checker, if both lights aren't on, there is an issue with the power coming into the UPS.

Next is another set of surge protectors and the 2 output trip switches.

Left one for the servers and the right for the blue plugs in the house.

So Purdy <3

Here is my Arduino (breadboard for now) controlling the system:

The wires in the front with the blue connectors are outputs for the 2x (12v) relays you saw above.

The wires in the back with the green connectors (not the USB cable) are opto-isolated inputs from the power inputs.

Here are 2x 240v relays that get powered by eksom (mains) or generator and are connected to the Arduino.

(This is how I can tell if there is power coming into the contactors)

:) So that's about it for the hardware side.

I do intend to commit all the code to GitHub but for now, a quick snippet of this code: (Please excuse the lack of comments. It was a quickie)

//Filename: mrHAC-CustomGeneratorController.ino
// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
// Copyright Mitchell Robert (M.R. Inc) 2005 - 2015. All Rights Reserved.
// Author: Mitchell Robert (M.R. Inc)
// Date: 27/09/2015

#include "mrHAC-CustomGeneratorControllerPowerState.h";

bool EskomPower = false;
bool GeneratorPower = false;
CURRENTSWITCHSTATE CurrentSwitch = NONE;
char* GeneratorKey = "$MYGENERATOR=";
int EskomRelayPin = 3;
int GeneratorRelayPin = 4;
int EskomPowerPin = 6;
int GeneratorPowerPin = 7;

/*
 * WHEN THE INPUT IS OPEN, READ=HIGH
 *                 CLOSED, READ=LOW
 */

void setup() {  
  pinMode (EskomRelayPin, OUTPUT);
  pinMode (GeneratorRelayPin, OUTPUT);
  pinMode (EskomPowerPin, INPUT);
  pinMode (GeneratorPowerPin, INPUT);
  
  Serial.begin(9600);
  
  // Force the system to recheck in case the power is currently off.
  EskomPower = !digitalRead(EskomPowerPin);
}

void loop() {
  if (digitalRead(EskomPowerPin) != (EskomPower)) {
    Serial.print("$UNKNOWN+MSG=ESKOM CHANGE TO: ");
    Serial.print(!EskomPower);
    Serial.println("$");
    delay(3000);    
    if (digitalRead(EskomPowerPin) != (EskomPower)) {
      EskomPower = digitalRead(EskomPowerPin);
      Serial.print("$UNKNOWN+MSG=ESKOM CHANGED TO: ");
      Serial.print(EskomPower);
      Serial.println("$");
    }
    else
      Serial.println("$UNKNOWN+MSG=SURGE$");
  }

  if (digitalRead(GeneratorPowerPin) != (GeneratorPower)) {
    Serial.print("$UNKNOWN+MSG=GENERATOR CHANGE TO: ");
    Serial.print(!GeneratorPower);
    Serial.println("$");
    delay(3000);    
    if (digitalRead(GeneratorPowerPin) != (GeneratorPower)) {
      GeneratorPower = digitalRead(GeneratorPowerPin);
      Serial.print("$UNKNOWN+MSG=GENERATOR CHANGED TO: ");
      Serial.print(GeneratorPower);
      Serial.println("$");
    }
    else
      Serial.println("$UNKNOWN+MSG=SURGE$");
  }

  if (!EskomPower && CurrentSwitch == ESKOM) {
    SwitchStateTo(GENERATOR);
  }
  else if (EskomPower && CurrentSwitch == GENERATOR) {
    SwitchStateTo(ESKOM);
  }
  
  else if (!EskomPower && CurrentSwitch == NONE) {
    SerialPrintData("0");
    delay(10000);
    SwitchStateTo(GENERATOR);
  }
  else if (EskomPower && CurrentSwitch == NONE) {
    delay(10000);
    SwitchStateTo(ESKOM);
  }
}

void SwitchStateTo(CURRENTSWITCHSTATE state) {
  Serial.print("$UNKNOWN+MSG=SWITCHING TO ");
  Serial.print(CURRENTSWITCHSTATE_STRING[state]);
  Serial.println("$");
  if (state == GENERATOR) {
    digitalWrite(EskomRelayPin, LOW);
    digitalWrite(GeneratorRelayPin, LOW);
    CurrentSwitch = NONE;
    
    SerialPrintData("1");
    delay(5000);

    if (digitalRead(GeneratorPowerPin) == HIGH) {
      Serial.println("$UNKNOWN+MSG=SUCCESS$");
      delay(5000);
      Serial.println("$UNKNOWN+MSG=SWITCHED");
      digitalWrite(GeneratorRelayPin, HIGH);
      CurrentSwitch = GENERATOR;
    }
    else { 
      Serial.println("$UNKNOWN+MSG=FAIL-NO POWER - DELAYING for 5s$");
      delay(5000);
        
      if (digitalRead(GeneratorPowerPin) == HIGH) {
        Serial.println("$UNKNOWN+MSG=SUCCESS$");
        delay(5000);
        Serial.println("$UNKNOWN+MSG=SWITCHED");
        digitalWrite(GeneratorRelayPin, HIGH);
        CurrentSwitch = GENERATOR;
      }
      else 
        Serial.println("$UNKNOWN+MSG=FAIL-NO POWER$");
    }
  }
  else if (state == ESKOM) {
    digitalWrite(EskomRelayPin, LOW);
    digitalWrite(GeneratorRelayPin, LOW);
    CurrentSwitch = NONE;
    
    SerialPrintData("0");
    delay(1000);

    if (digitalRead(EskomPowerPin) == HIGH) {
      Serial.println("$UNKNOWN+MSG=SUCCESS$");
      digitalWrite(EskomRelayPin, HIGH);
      CurrentSwitch = ESKOM;
    }
    else 
      Serial.println("$UNKNOWN+MSG=FAIL-NO POWER$");
  }
}

void SerialPrintData(char* val) {
  Serial.print(GeneratorKey);
  Serial.print(val);
  Serial.println("$");
}
//Filename: mrHAC-CustomGeneratorControllerPowerState.h
// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
// Copyright Mitchell Robert (M.R. Inc) 2005 - 2015. All Rights Reserved.
// Author: Mitchell Robert (M.R. Inc)
// Date: 27/09/2015

enum CURRENTSWITCHSTATE {
  GENERATOR,
  ESKOM,
  NONE
};
static const char *CURRENTSWITCHSTATE_STRING[] = {
    "GENERATOR", "ESKOM", "NONE"
};

[Video to be attached here.]

Discussions