Mike's RSM 500 Code

Share you PDE file with our community

Posts: 163
Joined: Wed Oct 24, 2012 8:37 am
PostPosted: Wed Jun 08, 2016 3:25 pm
Haha OK..guess I missed it from yours...I'll give it a shot

Sent from my A0001 using Tapatalk
Image

Posts: 163
Joined: Wed Oct 24, 2012 8:37 am
PostPosted: Wed Jun 08, 2016 6:24 pm
Yup adding run swabbie worked... Thanks Lee!

Sent from my A0001 using Tapatalk
Image

Posts: 163
Joined: Wed Oct 24, 2012 8:37 am
PostPosted: Mon Jun 13, 2016 5:45 pm
So I have my Swabbie installed and working, can't wait to see the skimmer in a few days.

I've updated a few things, curiosity of Lee's code.

I tested the ATO high, when the skimmate container is full, and the skimmer went off and sent me the alert.
  • Although when I return the float switch down, I got a Power Restored email?!?!
  • Also the skimmer does not go back to Auto when the float switch is back down. I got a fewDo I need to clear ATO for it to return to Auto?

I also tested turning the Return pump off, which does shut off the ports correctly.
  • But I also got the Power Restored email.
  • And when I manually turned on the ports, I got an email saying Skimmer Container full (maybe just a coincidence from testing ATO High).

Any idea what's going on with the items above?
Tomorrow I will have to test a few more things.

EDIT: Although my ATO High is set for 'On" now and I am getting emails. I did a controller restart and it's not making a difference.
Maybe I am getting many emails because I do not have this line in?
Code: Select all
skimmerAlert.SetDelay(3600);


Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <PAR.h>
#include <WiFiAlert.h>
#include <ReefAngel.h>

// Define Custom Memory Locations
#define Mem_B_SwabbieRepeat   100
#define Mem_B_SwabbieTime     101

// Define Named Relay Ports
#define FlowPumps       1
#define Lights          2
#define Return          3
#define VortechL        4
#define VortechR        5
#define Skimmer         6
#define FanSump         7
#define HeaterSump      8

#define Reactor         Box1_Port1
#define Swabbie         Box1_Port2
#define Unused          Box1_Port3
#define Unused          Box1_Port4
#define Unused          Box1_Port5
#define WCMix           Box1_Port6
#define WCFlow          Box1_Port7
#define WCHeater        Box1_Port8

// Place global variable code below here
// Place global variable code above here

// #################### Setup (controller starting) ####################
void setup()
{
  // This must be the first line
  ReefAngel.Init();  //Initialize controller
  ReefAngel.Use2014Screen();  // Let's use 2014 Screen

  // Ports toggled in Feeding Mode
  ReefAngel.FeedingModePorts = 0;
  ReefAngel.FeedingModePortsE[0] = Port3Bit | Port4Bit | Port5Bit; //Unused ports for testing random feeding

  // Ports toggled in Water Change Mode
  ReefAngel.WaterChangePorts = Port1Bit | Port3Bit; // Flowpumps,Return

  // Ports toggled when Lights On / Off menu entry selected
  ReefAngel.LightsOnPorts = Port2Bit; //Lights

  // Ports turned off when Overheat temperature exceeded
  ReefAngel.OverheatShutoffPorts = Port2Bit | Port8Bit; //Lights,HeaterSump

  // Use T1 probe as temperature and overheat functions
  ReefAngel.TempProbe = T1_PROBE;
  ReefAngel.OverheatProbe = T1_PROBE;

  // ON by default
  ReefAngel.Relay.On(FlowPumps);
  ReefAngel.Relay.On(Return);
  ReefAngel.Relay.On(VortechL);
  ReefAngel.Relay.On(VortechR);

  // OFF by default
  ReefAngel.Relay.Off(Unused);
  ReefAngel.Relay.Off(Swabbie);
  ReefAngel.Relay.Off(WCMix);
  ReefAngel.Relay.Off(WCFlow);
  ReefAngel.Relay.Off(WCHeater);

// ##### Place additional initialization code below here #####
  // Define labels for LCD screen
  ReefAngel.CustomLabels[0]="Flow Pumps";
  ReefAngel.CustomLabels[1]="Lights";
  ReefAngel.CustomLabels[2]="Return";
  ReefAngel.CustomLabels[3]="Vortech L";
  ReefAngel.CustomLabels[4]="Vortech R";
  ReefAngel.CustomLabels[5]="Skimmer";
  ReefAngel.CustomLabels[6]="Fan";
  ReefAngel.CustomLabels[7]="Heater";

  ReefAngel.CustomLabels[Box1_Port1Label] = "Reactor";
  ReefAngel.CustomLabels[Box1_Port2Label] = "Swabbie";
  ReefAngel.CustomLabels[Box1_Port3Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port4Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port5Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port6Label] = "WCMix";
  ReefAngel.CustomLabels[Box1_Port7Label] = "WCFlow";
  ReefAngel.CustomLabels[Box1_Port8Label] = "WCHeater";

  // 5 second timer for power outage detection
  ReefAngel.Timer[1].SetInterval( 5 );   

}

// #################### Loop ####################
void loop()
{
  ReefAngel.Relay.On( Reactor );
  ReefAngel.StandardHeater( HeaterSump );
  ReefAngel.StandardFan( FanSump );
  ReefAngel.StandardLights( Lights ); 

  // ##### Place your custom code below here #####

  RunSwabbie();         // Skimmer neck cleaner
  SetRF();              // Set Vortech modes
  CheckPower();         // Monitor for power loss
  CheckSwitches();      // Monitor Float switches

  /*
  if (ReefAngel.DisplayedMenu = WATERCHANGE_MODE) {
   WaterchangeHeater( HeaterWC, 775, 778 );
   }
   */

  // ##### Place your custom code above here #####

  // This should always be the last line
  ReefAngel.Portal("modulok");
  ReefAngel.ShowInterface();
}

// #################### Custom Function  ####################
void CheckSwitches() {
  static boolean returnOverride=true;
  static WiFiAlert skimmerAlert, atoAlert;

  if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
    returnOverride=true;

  // HighATO=on, delay start Skimmer | HighATO=off, Skimmer shuts off
  if (ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.DelayedOn(Skimmer);
  else
    ReefAngel.Relay.Override(Skimmer,0);
  skimmerAlert.Send("Skimmate+container+full!+Skimmer+shutoff.");

  // If Return pump is off, kill power to others
  if (!ReefAngel.Relay.Status(Return)) {
    ReefAngel.Relay.Override(Skimmer,0);
    ReefAngel.Relay.Override(FanSump,0);
    ReefAngel.Relay.Override(Reactor,0);
    ReefAngel.Relay.Override(HeaterSump,0);
  }

  // Alert if ATO timeput flag
  if (bitRead(ReefAngel.AlertFlags,ATOTimeOutFlag))
    atoAlert.Send("ATO+timeout!+ATO+disabled.");
}

void SetRF() {

  // Vortech MP40 | Constant | Lagoon | ReefCrest | ShortWave 1=10ms | LongWave 1=1s | NutrientTransport 1=10ms | TidalSwell
  if ( ReefAngel.DisplayedMenu != FEEDING_MODE || ReefAngel.DisplayedMenu != WATERCHANGE_MODE ) {
    if ( hour() >= 16 && hour() <= 20 ) {
      ReefAngel.RF.UseMemory = false;
      ReefAngel.RF.SetMode( LongWave, 70, 30 );
    }
    else if ( hour() >= 20 || hour() < 7 ) {
      ReefAngel.RF.UseMemory = false;
      ReefAngel.RF.SetMode( ReefCrest, 40, 0 );
    }
    else {
      ReefAngel.RF.UseMemory = true;
    }
  }
}
void RunSwabbie() {
  int repeat=InternalMemory.read(Mem_B_SwabbieRepeat)*60;
  int runtime=InternalMemory.read(Mem_B_SwabbieTime)*60;
  static time_t t;

  // Manual mode
  if (ReefAngel.Relay.isMaskOn(Swabbie)) {
    ReefAngel.Relay.Auto(Swabbie);
    t=now();
  }

  if (now()-t < runtime) {
    ReefAngel.Relay.On(Swabbie);
  }
  else {
    ReefAngel.DosingPumpRepeat(Swabbie,0,repeat,runtime);   
  }
}

void CheckPower()
{
  static boolean powerOutage = false;
  static WiFiAlert powerAlert;
  static boolean delayedPowerOutage = false;

  // Power Outage - Leave Only Vortech Pumps active
  if ( !ReefAngel.Relay.IsRelayPresent( EXP1_RELAY ) ) {
    powerOutage = true;    //Expansion Relay 1 has lost power
  }

  if ( !powerOutage ) {
    ReefAngel.Timer[1].Start();
  }

  if ( ReefAngel.Timer[1].IsTriggered() ) {
    delayedPowerOutage = true;
  }

  if (delayedPowerOutage) {
    ReefAngel.Relay.Off(FlowPumps);
    ReefAngel.Relay.Off(Return);
    ReefAngel.Relay.Off(Skimmer);
    ReefAngel.Relay.Off(Lights);
    ReefAngel.Relay.Off(FanSump);
    ReefAngel.Relay.Off(HeaterSump);
    ReefAngel.RF.SetMode(Constant,70,0);
    powerAlert.Send("Power+lost!");
  }

  // Power Restored - return equipment back to normal power state
  if ( powerOutage && ReefAngel.Relay.IsRelayPresent( EXP1_RELAY ) ) {
    powerOutage = false;
    delayedPowerOutage = false;
    LastStart = now();
    powerAlert.Send("Power+restored.",true);
  }
}

void WaterchangeHeater(byte HeaterRelay, int LowTemp, int HighTemp)
{
  if (ReefAngel.Params.Temp[T3_PROBE] == 0) return;  // Don't turn the heater on if the temp is reading 0
  if (ReefAngel.Params.Temp[T3_PROBE] <= LowTemp && ReefAngel.Params.Temp[T3_PROBE] > 0) ReefAngel.Relay.On(WCHeater);
  if (ReefAngel.Params.Temp[T3_PROBE] >= HighTemp) ReefAngel.Relay.Off(WCHeater);
}
// #################### Custom Function End ####################

Image
User avatar
Posts: 5338
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Tue Jun 14, 2016 7:42 pm
I'll take a look at your code later this week. The way my code is written it sets the override when these conditions occur so you just have to reset the ports to auto.

Posts: 163
Joined: Wed Oct 24, 2012 8:37 am
PostPosted: Sat Jun 18, 2016 6:21 am
I modified the code a bit and not am not getting skimmate full emails. But for some reason I have power restored emails.

Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <PAR.h>
#include <WiFiAlert.h>
#include <ReefAngel.h>

// Define Custom Memory Locations
#define Mem_B_SwabbieRepeat   100
#define Mem_B_SwabbieTime     101

// Define Named Relay Ports
#define FlowPumps       1
#define Lights          2
#define Return          3
#define VortechL        4
#define VortechR        5
#define Skimmer         6
#define FanSump         7
#define HeaterSump      8

#define Reactor         Box1_Port1
#define Swabbie         Box1_Port2
#define Unused          Box1_Port3
#define Unused          Box1_Port4
#define Unused          Box1_Port5
#define WCMix           Box1_Port6
#define WCFlow          Box1_Port7
#define WCHeater        Box1_Port8

// Place global variable code below here
// Place global variable code above here

// #################### Setup (controller starting) ####################
void setup()
{
  // This must be the first line
  ReefAngel.Init();  //Initialize controller
  ReefAngel.Use2014Screen();  // Let's use 2014 Screen

    // Ports toggled in Feeding Mode
  ReefAngel.FeedingModePorts = 0;
  ReefAngel.FeedingModePortsE[0] = Port3Bit | Port4Bit | Port5Bit; //Unused ports for testing random feeding

  // Ports toggled in Water Change Mode
  ReefAngel.WaterChangePorts = Port1Bit | Port3Bit; // Flowpumps,Return

  // Ports toggled when Lights On / Off menu entry selected
  ReefAngel.LightsOnPorts = Port2Bit; //Lights

  // Ports turned off when Overheat temperature exceeded
  ReefAngel.OverheatShutoffPorts = Port2Bit | Port8Bit; //Lights,HeaterSump

  // Use T1 probe as temperature and overheat functions
  ReefAngel.TempProbe = T1_PROBE;
  ReefAngel.OverheatProbe = T1_PROBE;

  // ON by default
  ReefAngel.Relay.On(FlowPumps);
  ReefAngel.Relay.On(Return);
  ReefAngel.Relay.On(VortechL);
  ReefAngel.Relay.On(VortechR);

  // OFF by default
  ReefAngel.Relay.Off(Unused);
  ReefAngel.Relay.Off(Swabbie);
  ReefAngel.Relay.Off(WCMix);
  ReefAngel.Relay.Off(WCFlow);
  ReefAngel.Relay.Off(WCHeater);

  // ##### Place additional initialization code below here #####
  // Define labels for LCD screen
  ReefAngel.CustomLabels[0]="Flow Pumps";
  ReefAngel.CustomLabels[1]="Lights";
  ReefAngel.CustomLabels[2]="Return";
  ReefAngel.CustomLabels[3]="Vortech L";
  ReefAngel.CustomLabels[4]="Vortech R";
  ReefAngel.CustomLabels[5]="Skimmer";
  ReefAngel.CustomLabels[6]="Fan";
  ReefAngel.CustomLabels[7]="Heater";

  ReefAngel.CustomLabels[Box1_Port1Label] = "Reactor";
  ReefAngel.CustomLabels[Box1_Port2Label] = "Swabbie";
  ReefAngel.CustomLabels[Box1_Port3Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port4Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port5Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port6Label] = "WCMix";
  ReefAngel.CustomLabels[Box1_Port7Label] = "WCFlow";
  ReefAngel.CustomLabels[Box1_Port8Label] = "WCHeater";

  // 5 second timer for power outage detection
  ReefAngel.Timer[1].SetInterval( 5 );   
}

// #################### Loop ####################
void loop()
{
  ReefAngel.Relay.On(Reactor);
  ReefAngel.StandardHeater(HeaterSump);
  ReefAngel.StandardFan(FanSump);
  ReefAngel.StandardLights(Lights);
  ReefAngel.Relay.DelayedOn(Skimmer);

  // ##### Place your custom code below here #####

  RunSwabbie();         // Skimmer neck cleaner
  SetRF();              // Set Vortech modes
  CheckPower();         // Monitor for power loss
  CheckSwitches();      // Monitor float switches

  /*
  if (ReefAngel.DisplayedMenu = WATERCHANGE_MODE) {
   WaterchangeHeater( HeaterWC, 775, 778 );
   }
   */

  // ##### Place your custom code above here #####

  // This should always be the last line
  ReefAngel.Portal("modulok");
  ReefAngel.ShowInterface();
}

// #################### Custom Function  ####################
void CheckSwitches() {
  static boolean returnOverride=true;
  static WiFiAlert skimmerAlert, atoAlert;
  skimmerAlert.SetDelay(3600);
  atoAlert.SetDelay(3600);

  if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
    returnOverride=true;

  // HighATO=off, Skimmer shuts off
  if (!ReefAngel.HighATO.IsActive()) {
    skimmerAlert.Send("Skimmate+container+is+full!+Skimmer+has+been+shutoff.");
    ReefAngel.Relay.Override(Skimmer,0);
  }

  // If Return pump is off, kill power to others
  if (!ReefAngel.Relay.Status(Return)) {
    ReefAngel.Relay.Override(Skimmer,0);
    ReefAngel.Relay.Override(FanSump,0);
    ReefAngel.Relay.Override(Reactor,0);
    ReefAngel.Relay.Override(HeaterSump,0);
  }

  // Alert if ATO timeout flag
  if (bitRead(ReefAngel.AlertFlags,ATOTimeOutFlag))
    atoAlert.Send("ATO+timeout!+ATO+disabled.");
}

void SetRF() {
  // Vortech MP40 | Constant | Lagoon | ReefCrest | ShortWave 1=10ms | LongWave 1=1s | NutrientTransport 1=10ms | TidalSwell
  if ( ReefAngel.DisplayedMenu != FEEDING_MODE || ReefAngel.DisplayedMenu != WATERCHANGE_MODE ) {
    if ( hour() >= 16 && hour() <= 20 ) {
      ReefAngel.RF.UseMemory = false;
      ReefAngel.RF.SetMode( LongWave, 70, 30 );
    }
    else if ( hour() >= 20 || hour() < 7 ) {
      ReefAngel.RF.UseMemory = false;
      ReefAngel.RF.SetMode( ReefCrest, 40, 0 );
    }
    else {
      ReefAngel.RF.UseMemory = true;
    }
  }
}

void RunSwabbie() {
  int repeat=InternalMemory.read(Mem_B_SwabbieRepeat)*60;
  int runtime=InternalMemory.read(Mem_B_SwabbieTime)*60;
  static time_t t;

  // Manual mode
  if (ReefAngel.Relay.isMaskOn(Swabbie)) {
    ReefAngel.Relay.Auto(Swabbie);
    t=now();
  }

  if (now()-t < runtime) {
    ReefAngel.Relay.On(Swabbie);
  }
  else {
    ReefAngel.DosingPumpRepeat(Swabbie,0,repeat,runtime);   
  }
}

void CheckPower()
{
  static boolean powerOutage = false;
  static WiFiAlert powerAlert;
  static boolean delayedPowerOutage = false;

  // Power Outage - Leave Only Vortech Pumps active
  if ( !ReefAngel.Relay.IsRelayPresent( EXP1_RELAY ) ) {
    powerOutage = true;    //Expansion Relay 1 has lost power
  }

  if ( !powerOutage ) {
    ReefAngel.Timer[1].Start();
  }

  if ( ReefAngel.Timer[1].IsTriggered() ) {
    delayedPowerOutage = true;
  }

  if (delayedPowerOutage) {
    ReefAngel.Relay.Off(FlowPumps);
    ReefAngel.Relay.Off(Return);
    ReefAngel.Relay.Off(Skimmer);
    ReefAngel.Relay.Off(Lights);
    ReefAngel.Relay.Off(FanSump);
    ReefAngel.Relay.Off(HeaterSump);
    ReefAngel.RF.SetMode(Constant,70,0);
    powerAlert.Send("Power+lost!");
  }

  // Power Restored - return equipment back to normal power state
  if ( powerOutage && ReefAngel.Relay.IsRelayPresent( EXP1_RELAY ) ) {
    powerOutage = false;
    delayedPowerOutage = false;
    LastStart = now();
    powerAlert.Send("Power+restored.",true);
  }
}

void WaterchangeHeater(byte HeaterRelay, int LowTemp, int HighTemp)
{
  if (ReefAngel.Params.Temp[T3_PROBE] == 0) return;  // Don't turn the heater on if the temp is reading 0
  if (ReefAngel.Params.Temp[T3_PROBE] <= LowTemp && ReefAngel.Params.Temp[T3_PROBE] > 0) ReefAngel.Relay.On(WCHeater);
  if (ReefAngel.Params.Temp[T3_PROBE] >= HighTemp) ReefAngel.Relay.Off(WCHeater);
}
// #################### Custom Function End ####################
Image
User avatar
Posts: 5338
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Tue Jun 21, 2016 5:37 pm
I updated my code the other day. I'm using a different mechanism to delay the power outage. I dont recommend the way you are doing it with the Timer class. I'm not sire whats happening but clearly you are falsely triggering the power outage and this could cause robertos code to not send you the right alert.

Does the skimmer turn off when your float switch changes? If so the code to send the skimmer full alarm should be fine.

Posts: 163
Joined: Wed Oct 24, 2012 8:37 am
PostPosted: Wed Jun 22, 2016 9:37 am
OK, I see you include a delay in the poweroutage code, cool! I will give it a shot and update my code later tonight.

The skimmer does shutoff when the float switch is up, and I got the email. So that seems to be working well. I am waiting for the container to actually fill up for a real test. (It might be two months unless I change to a wetter skimmate)
Image
User avatar
Posts: 5338
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Wed Jun 22, 2016 11:00 am
Cool. Yeah I was getting tired of false alarms :)

Posts: 163
Joined: Wed Oct 24, 2012 8:37 am
PostPosted: Wed Jun 22, 2016 5:33 pm
Not sure why, but the checkpower function isn't working right.

When I kill power to exp relay box only the return shuts off like it should. Lights stay on, skimmer, fan, heater, reactor shut off due to return being off. No email from Power Lost.

After power is returned I get emails every few minutes for Power Restored, and I hear relays but do not see anything switching on or off. The Return does not come back on (waited 5 minutes). Also the ports that shut off when return is off do not reset to auto.

I am curious what this line does. Wait for 300 seconds to signal poweroutage?

Code: Select all
if (now()-powerOutage > 300) {
      ReefAngel.Relay.Set(Return, now()%3600<300);
    }


Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <PAR.h>
#include <WiFiAlert.h>
#include <ReefAngel.h>

// Define Custom Memory Locations
#define Mem_B_SwabbieRepeat   100
#define Mem_B_SwabbieTime     101

// Define Named Relay Ports
#define FlowPumps       1
#define Lights          2
#define Return          3
#define VortechL        4
#define VortechR        5
#define Skimmer         6
#define FanSump         7
#define HeaterSump      8

#define Reactor         Box1_Port1
#define Swabbie         Box1_Port2
#define Unused          Box1_Port3
#define Unused          Box1_Port4
#define Unused          Box1_Port5
#define WCMix           Box1_Port6
#define WCFlow          Box1_Port7
#define WCHeater        Box1_Port8

// Place global variable code below here

  // Vortech Variables
  byte vtMode, vtSpeed, vtDuration;
   
// Place global variable code above here

// #################### Setup (controller starting) ####################
void setup()
{
  // This must be the first line
  ReefAngel.Init();  //Initialize controller
  ReefAngel.Use2014Screen();  // Let's use 2014 Screen

    // Ports toggled in Feeding Mode
  ReefAngel.FeedingModePorts = 0;
  ReefAngel.FeedingModePortsE[0] = Port3Bit | Port4Bit | Port5Bit; //Unused ports for testing random feeding

  // Ports toggled in Water Change Mode
  ReefAngel.WaterChangePorts = Port1Bit | Port3Bit; // Flowpumps,Return

  // Ports toggled when Lights On / Off menu entry selected
  ReefAngel.LightsOnPorts = Port2Bit; //Lights

  // Ports turned off when Overheat temperature exceeded
  ReefAngel.OverheatShutoffPorts = Port2Bit | Port8Bit; //Lights,HeaterSump

  // Use T1 probe as temperature and overheat functions
  ReefAngel.TempProbe = T1_PROBE;
  ReefAngel.OverheatProbe = T1_PROBE;

  // ON by default
  ReefAngel.Relay.On(FlowPumps);
  ReefAngel.Relay.On(Return);
  ReefAngel.Relay.On(VortechL);
  ReefAngel.Relay.On(VortechR);

  // OFF by default
  ReefAngel.Relay.Off(Unused);
  ReefAngel.Relay.Off(Swabbie);
  ReefAngel.Relay.Off(WCMix);
  ReefAngel.Relay.Off(WCFlow);
  ReefAngel.Relay.Off(WCHeater);

  // ##### Place additional initialization code below here #####
  // Define labels for LCD screen
  ReefAngel.CustomLabels[0]="Flow Pumps";
  ReefAngel.CustomLabels[1]="Lights";
  ReefAngel.CustomLabels[2]="Return";
  ReefAngel.CustomLabels[3]="Vortech L";
  ReefAngel.CustomLabels[4]="Vortech R";
  ReefAngel.CustomLabels[5]="Skimmer";
  ReefAngel.CustomLabels[6]="Fan";
  ReefAngel.CustomLabels[7]="Heater";

  ReefAngel.CustomLabels[Box1_Port1Label] = "Reactor";
  ReefAngel.CustomLabels[Box1_Port2Label] = "Swabbie";
  ReefAngel.CustomLabels[Box1_Port3Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port4Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port5Label] = "Unused";
  ReefAngel.CustomLabels[Box1_Port6Label] = "WCMix";
  ReefAngel.CustomLabels[Box1_Port7Label] = "WCFlow";
  ReefAngel.CustomLabels[Box1_Port8Label] = "WCHeater";
}

// #################### Loop ####################
void loop()
{
  ReefAngel.Relay.On(Reactor);
  ReefAngel.StandardHeater(HeaterSump);
  ReefAngel.StandardFan(FanSump);
  ReefAngel.StandardLights(Lights);
  ReefAngel.Relay.DelayedOn(Skimmer);

  // ##### Place your custom code below here #####

  RunSwabbie();         // Skimmer neck cleaner
  SetRF();              // Set Vortech modes
  CheckPower();         // Monitor for power loss
  CheckSwitches();      // Monitor float switches

  /*
  if (ReefAngel.DisplayedMenu = WATERCHANGE_MODE) {
   WaterchangeHeater( HeaterWC, 775, 778 );
   }
   */

  // ##### Place your custom code above here #####

  // This should always be the last line
  ReefAngel.Portal("modulok");
  ReefAngel.ShowInterface();
}

// #################### Custom Function  ####################
void CheckSwitches() {
  static boolean returnOverride=true;
  static WiFiAlert skimmerAlert, atoAlert;
  skimmerAlert.SetDelay(3600);
  atoAlert.SetDelay(3600);

  if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
    returnOverride=true;

  // HighATO=off, Skimmer shuts off
  if (!ReefAngel.HighATO.IsActive()) {
    skimmerAlert.Send("Skimmate+container+is+full!+Skimmer+has+been+shutoff.");
    ReefAngel.Relay.Override(Skimmer,0);
  }

  // If Return pump is off, kill power to others
  if (!ReefAngel.Relay.Status(Return)) {
    ReefAngel.Relay.Override(Skimmer,0);
    ReefAngel.Relay.Override(FanSump,0);
    ReefAngel.Relay.Override(Reactor,0);
    ReefAngel.Relay.Override(HeaterSump,0);
  }

  // Alert if ATO timeout flag
  if (bitRead(ReefAngel.AlertFlags,ATOTimeOutFlag))
    atoAlert.Send("ATO+timeout!+ATO+disabled.");
}

void SetRF() {
  // Vortech MP40 | Constant | Lagoon | ReefCrest | ShortWave 1=10ms | LongWave 1=1s | NutrientTransport 1=10ms | TidalSwell
  if ( ReefAngel.DisplayedMenu != FEEDING_MODE || ReefAngel.DisplayedMenu != WATERCHANGE_MODE ) {
    if ( hour() >= 16 && hour() <= 20 ) {
      ReefAngel.RF.UseMemory = false;
      ReefAngel.RF.SetMode( LongWave, 70, 30 );
    }
    else if ( hour() >= 20 || hour() < 7 ) {
      ReefAngel.RF.UseMemory = false;
      ReefAngel.RF.SetMode( ReefCrest, 40, 0 );
    }
    else {
      ReefAngel.RF.UseMemory = true;
    }
  }
}

void RunSwabbie() {
  int repeat=InternalMemory.read(Mem_B_SwabbieRepeat)*60;
  int runtime=InternalMemory.read(Mem_B_SwabbieTime)*60;
  static time_t t;

  // Manual mode
  if (ReefAngel.Relay.isMaskOn(Swabbie)) {
    ReefAngel.Relay.Auto(Swabbie);
    t=now();
  }

  if (now()-t < runtime) {
    ReefAngel.Relay.On(Swabbie);
  }
  else {
    ReefAngel.DosingPumpRepeat(Swabbie,0,repeat,runtime);   
  }
}

void CheckPower() {
  static time_t powerOutage=false;
  static WiFiAlert powerAlert;

  // Power Outage - Leave Only Vortech Pumps active
  if (!ReefAngel.Relay.IsRelayPresent(EXP1_RELAY) && !powerOutage) //Relay Expansion NOT detected
  {
    powerOutage=now();
    if (now()-powerOutage > 300) {
      ReefAngel.Relay.Set(Return, now()%3600<300);
    }
 
    ReefAngel.Relay.Off(FlowPumps);
    ReefAngel.Relay.Off(Return);
    ReefAngel.Relay.Off(Skimmer);
    ReefAngel.Relay.Off(Lights);
    ReefAngel.Relay.Off(FanSump);
    ReefAngel.Relay.Off(HeaterSump);
    ReefAngel.RF.SetMode(Constant,70,0);
    if (now()-powerOutage > 10) { // Wait 10 seconds before sending to avoid false alarms
      powerAlert.Send("Power+lost!");
      }
  }
 
  // Power Restored - return equipment back to normal power state
  if (powerOutage && ReefAngel.Relay.IsRelayPresent( EXP1_RELAY ) )
  {
    powerOutage=0;
    LastStart=now();
    ReefAngel.RF.SetMode(vtMode,vtSpeed,vtDuration);
    powerAlert.Send("Power+restored.",true);
  }
}

void WaterchangeHeater(byte HeaterRelay, int LowTemp, int HighTemp)
{
  if (ReefAngel.Params.Temp[T3_PROBE] == 0) return;  // Don't turn the heater on if the temp is reading 0
  if (ReefAngel.Params.Temp[T3_PROBE] <= LowTemp && ReefAngel.Params.Temp[T3_PROBE] > 0) ReefAngel.Relay.On(WCHeater);
  if (ReefAngel.Params.Temp[T3_PROBE] >= HighTemp) ReefAngel.Relay.Off(WCHeater);
}
// #################### Custom Function End ####################
Image
User avatar
Posts: 5338
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Wed Jun 22, 2016 6:11 pm
That line says after the power is out for 5 minutes, run the return pump for 5 minutes each hour. This way my UPS conserves power to run the mp40s
PreviousNext

Return to My PDE/INO file

Who is online

Users browsing this forum: No registered users and 2 guests