Page 1 of 1

BIG OOPS today by my Reef Angel+

Posted: Wed May 01, 2013 5:51 pm
by 00Warpig00
Ok...

so I haven't been around here for a while but I need to vent a little after what happened today with my RA+

Can anyone give me some advice on *how* this may have happened... do I have a bug in my code? I have not made any code changes since 3/9/2013 and I had a doosey surface today... :shock:

So I have some issues with my temp probes and what I believe is noise or bad probe that has been causing an overheat flag reporting a temp of 130+ degrees. Thats nothing new I have had that issue for a while... What is new..

Today when my controller tripped an overheat flag at 10:30am this morning the controller decided all by it self that it needed to turn on my Maxijet 600 RO/DI ATO pump for the whole day. Not sure WHY it stayed on so long. It didnt show as masked on on my android app, just ON. I didn't even notice the ATO pump was on until I saw a notification e-mail from the portal that the overheat had tripped several hours earlier and I checked the tank with the droid app. :'( looking at the app I was like "OH SH.T! my ato pump is on" so I masked it off (it was not masked ON it was just ON) and abruptly left work early and drove home 23 miles at about 80 mph. I get in the door and yes... My entire full 44 gallon Brute of RODI water had been pumped into my sump. My sump had overflowed the excess it could not hold (I'm guessing about 15 gallons) into the bottom of my stand. Luckily When I designed my stand I raised my sump off the floor on top of the 2x8's the stand is made from and decided when I put it together to put a shower curtain liner in bottom to make a kind of water catch. Been two and a half years and this is the FIRST DT/SUMP overflow I have had. The water catch at the bottom was FULL of water. There was a little bit that leaked out but overall the catch saved my ass. No calls from the downstairs neighbors yet about me installing a new waterfall in my unit. Hopefully that will not happen. The salinity of course dropped like a rock in my tank from 30ppt down to 26ppt from all that RODI water. My fish seem to be ok so far. I pumped the catch empty and pumped my sump completely empty and then pumped the 44Gallons of 1.025 SW into the sump for a water change while I was dealing with this issue as well as an effort to bring my salinity back up a bit. tat brought it back up to 27ppt. So far the fish seem ok and No calls from the downstairs neighbor (YET). Lucky it's a FOWLR tank... ugg...

I have included my running code (Version 104, I use a memory spot to keep track of my current code)
My Libs at the time were 1.0.3 I have updated to 1.0.5 but not recompiled or uploaded to the RA+ yet. can anyone fathom a guess as to what the cause of my controller turning on my ATO pump and leaving it on may have been... :(

I have unplugged my RO/SW ATO pumps from the controller for now since it cannot be trusted at this point...

Here is my current running code

_Running_Config_104

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 <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 <ReefAngel.h>

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


    // Initialize Alert variables
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1MinTemp=9999;
    int T1MaxTemp=1;
    int T1Temp=1;

    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port2;

    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


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


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Running_Config_Revision_104
        InternalMemory.write(100, 104);


        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
        InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon boot.   

        //*****End Custom Menu Additions


        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that are always on
        ReefAngel.Relay.On( Port3 );
        ReefAngel.Relay.On( Box1_Port5 );
        ReefAngel.Relay.On( Box1_Port6 );
        ReefAngel.Relay.On( Box1_Port7 );


        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;   


        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardLights( Box1_Port1,13,0,23,0 );
        ReefAngel.StandardLights( Box1_Port2,13,0,23,0 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions

      // Removes LED's from a "MASKED" State
      if ( InternalMemory.read(199) == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
        }

      // MASKS LED's Off
      if ( InternalMemory.read(199) == 1 )
        {
          ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
          ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
          ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
          ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
        }

      if ( InternalMemory.read(199) == 2 )
        {
          ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
          ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
          ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
          ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
        }

      else
        {
        }
           
    //*****End Custom Menu Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions


        T1Temp=ReefAngel.Params.Temp[T1_PROBE];

    //T1MaxTemp = T1Temp;
    //T1MinTemp = T1Temp;

          if ( T1Temp > T1MaxTemp ) T1MaxTemp = T1Temp;
              InternalMemory.write(102, T1MaxTemp);
           
          if ( T1Temp < T1MinTemp ) T1MinTemp = T1Temp;
              InternalMemory.write(101, T1MinTemp);

       
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

       
        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
        if ( AlertCritical >= 1 ) AlertCritical = 5;   
        ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

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

        ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
        ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
        ReefAngel.CustomVar[2]=CustomIOExpander;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=InternalMemory.read(199);
        ReefAngel.CustomVar[5]=AlertNonCritical;
        ReefAngel.CustomVar[6]=AlertCritical;   
        ReefAngel.CustomVar[7]=ATOBrutePort;
       
        if ( ReefAngel.CustomVar[0]== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)
          {
            ATOBrutePort=Port7;
          }
        else
          {
            ATOBrutePort=Port2;
          }
        ReefAngel.StandardATO(ATOBrutePort,40 );
        if (iochannel2flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
          }
        if (iochannel4flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
          }
         
        //*****End ATO By Salinity Additions


        //*****Begin Custom IO Expander Additions

        //*****End Custom IO Expander Additions


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

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


    //*****Begin Custom Menu Additions

    //Mask LED's On. Forces LED's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Off. Forces LED's Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin WC Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              // TODO finish countdown on screen
              // show countdown on screen
              //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
              //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End WC Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,76, "SAL:" );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,76, "L" );   
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,76, "H" );       
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,76, ReefAngel.Params.Salinity );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,76, T1MinTemp );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,76, T1MaxTemp );   
        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }



If anyone can find any coding issues that would cause this, please speak up. :)

Thanks,

Nick

BIG OOPS today by my Reef Angel+

Posted: Wed May 01, 2013 8:23 pm
by lnevo
Don't see anything, but I also don't see something important...if you have a salinity probe you should put some safety in there if your salinity drops below x then disable the ato regardless and then set an alert for it. Don't let yourself get caught by surprise again. Glad e incident was contained. I'm sure the fish will come through. Keep in mind people do freshwater dips...

Re: BIG OOPS today by my Reef Angel+

Posted: Wed May 01, 2013 8:48 pm
by enigma32
That sucks :-(

I'm no RA expert yet, but I've been maintaining my own custom controller for a number of years now... and I reached the same conclusion as lnevo when reading your code.

Also, I run an extra float switch that kills the ATO pump regardless of what the microcontroller decides if the sump level gets much above normal, to minimize the chance of a programming glitch causing a mess. Obviously not much help after the fact, but worth considering when looking toward the future...

Good luck with getting everything back to normal.

Re: BIG OOPS today by my Reef Angel+

Posted: Wed May 01, 2013 9:53 pm
by rimai
I don't see anything wrong with the code either.
Did you have any trigger to watch for salinity?

Re: BIG OOPS today by my Reef Angel+

Posted: Thu May 02, 2013 11:07 pm
by 00Warpig00
Thanks for taking the time to look over my code guys. :) I looked and looked at it too and I cant figure out what went wrong. It appears as if the entire chain of events was triggered by my temp probe/noise issue momentarily reporting a 130+ degree temp to the controller. You may have noticed that my code has a minimum/maximum temp reading that keeps a high\Low temp displayed on my screen at all times. I didnt know it was a probe/noise issue until I added this code that showed me the 130+ degree high's as they only lasted for milliseconds at best, although long enough for the controller code to catch them. I was very happy to see that the new libs seem to address this very issue of stray short duration mis-reportings. I will see if i can re compile with 1.0.5 this weekend. I also have some other stuff I need to do with the tank\controller.

Thanks also for the ideas on putting in a low salinity trigger to mask off both my SW\RO ATO Pumps if things get too High\Low. I have nothing like that yet in my code and it is a GREAT idea that I missed. I will have to look into the best way to accomplish this for my setup. I also appear to need to double check some things in my code. I have a sump full float switch that if it is triggered *should* shut down those pumps, but it is entirely possible I missed putting the required code in to handle that situation when I though it was there. As for a second failsafe on the sump full float concept I may have to look into setting up a low voltage controlled relay that can disable those two pumps in an event like this.

As for my tank... At has been more than 24 hours and all my fish seem oblivious to what has occurred. So do my downstairs neighbors. :) this could have turned out MUCH WORSE! My salinity is still a bit low I mixed up another batch of SW tonight and will be topping with it plugging my pumps in manually until back to "normal" and until I can recompile and upload with the new libs and do some verification that the controller can again be trusted with the chore of ATO.

Nick

Re: BIG OOPS today by my Reef Angel+

Posted: Fri May 03, 2013 5:03 am
by barbianj
Using the water level sensor would allow you to get an alert when the water reached a certain height, adding another layer of safety.