water change build

Do you have a question on how to do something.
Ask in here.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

I wasn't exactly sure where to put wcTimer==0, sorry mate.

Code: Select all

//Waterchange Mode    
   
  static time_t wcTimer=0;
 
  
  if (ReefAngel.DisplayedMenu == WATERCHANGE_MODE && wcTimer==0);
  {
    wcTimer=now();
  }
  
   if (now()-wcTimer >= 1 && now()-wcTimer < 120)
  {  
    ReefAngel.Relay.Off(Box1_Port7);
    ReefAngel.Relay.Off(Box1_Port8);
  }
  
    if (now()-wcTimer >= 60 && now()-wcTimer < 120)
  {
    if (ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.On(Box1_Port4);
    else  
    ReefAngel.Relay.Off(Box1_Port4);
  }
  
    if (now()-wcTimer >= 120 && now()-wcTimer < 180)
  {
    if (!ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.On(Box1_Port1);
    else 
    ReefAngel.Relay.Off(Box1_Port1);
   } else {
    wcTimer=0;
//    ButtonPress++;
  }
    
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: water change build

Post by lnevo »

Looks right to me
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

Still not triggering on waterchange. I know its a silly question but I'm using the android app to activate not the RA, would this have any effect?
Image
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

Here is my full build encase something is out of the ordinary and causing problems.

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 <ReefAngel.h>
#include <Moon.h>

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


//Standard Dimming//
byte ActinicPWMValue=0;    // For cloud code
byte DaylightPWMValue=0;   // For cloud code

//Dimmer Expansion//
byte WhitePWMValue=0;
byte Actinic1PWMValue=0;
byte SupPWMValue=0;
byte MoonPWMValue=0;


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


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    ReefAngel.SetTemperatureUnit( Celsius );  // set to Celsius Temperature

    ReefAngel.Use2014Screen();  // Let's use 2014 Screen 
//    ReefAngel.AddSalinityExpansion();  // Salinity Expansion Module
//    ReefAngel.AddORPExpansion();  // ORP Expansion Module
    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = Port7Bit | Port8Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = 0;
    ReefAngel.WaterChangePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = 0;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;

// Default Ports
    
    ReefAngel.Relay.On(Port1); //Sump Skimmer  
    
    ReefAngel.Relay.Off(Box1_Port1); //Sump Out
    ReefAngel.Relay.On(Box1_Port6); //Sump Light   
    ReefAngel.Relay.Off(Box1_Port4); //Sump Out 
    
    

// Place additional initialization code below here


    

// Place additional initialization code above here
}

void loop()
{
  
////// Place your custom code below here
  
    ReefAngel.StandardHeater(Port2,220,225); //Sump Heater
    ReefAngel.Relay.Set(Port3,ReefAngel.PWM.GetChannelValue(2)>0); //Sup Power 
    ReefAngel.StandardFan(Port4,230,238); //Chiller
    ReefAngel.Relay.Set(Port7,ReefAngel.PWM.GetChannelValue(4)>0); //Moon Power
    ReefAngel.Relay.Set(Port8,ReefAngel.PWM.GetChannelValue(1)>0); //White / Blue Power  
    
    ReefAngel.StandardLights( Box1_Port5,8,00,16,00 ); //Display Color
    ReefAngel.Relay.On(Box1_Port7); //4FT In

//Sump out
    if (ReefAngel.Relay.isMaskOn(Box1_Port4) && !ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.Override(Box1_Port4,0);
      
//Salt In
    if (ReefAngel.Relay.isMaskOn(Box1_Port1) && ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.Override(Box1_Port1,0);
      
//White off 

  if (hour()==18 && minute()==30 && second()>=0 && hour()==18 && minute()==30 && second()<2)
  {
    ReefAngel.Relay.Off(Port8);
  } else {
    ReefAngel.StandardLights( Port8,5,00,21,00 );
  }

//Display in Failsafe//
    if (ReefAngel.LowATO.IsActive())
      ReefAngel.Relay.On(Box1_Port8);
    else
      ReefAngel.Relay.Off(Box1_Port8);
  
//Boosterpump//
    if (ReefAngel.LowATO.IsActive())
      ReefAngel.Relay.Off(Box1_Port2);
    else
      ReefAngel.Relay.On(Box1_Port2);
      
// Turn off Air Pump if Skimmer has been shutoff   
    if (ReefAngel.Relay.Status(Port1)>0)
      ReefAngel.Relay.On(Port6);
    else
      ReefAngel.Relay.Off(Port6);  
       
//Lighting Control//

    ActinicPWMValue=PWMSlope(5,00,21,00,10,100,180,ActinicPWMValue);
    DaylightPWMValue=PWMSlope(6,30,18,30,10,70,180,DaylightPWMValue);
    WhitePWMValue=PWMSlope(6,30,18,30,0,60,180,WhitePWMValue);
    Actinic1PWMValue=PWMSlope(5,00,21,00,2,80,180,Actinic1PWMValue);
    SupPWMValue=PWMSlope(8,00,16,00,0,80,200,SupPWMValue);
    MoonPWMValue=PWMSlope(21,00,5,00,1,MoonPhase(),235,0); 
    
    CheckCloud();
    
    ReefAngel.PWM.SetActinic(ActinicPWMValue);
    ReefAngel.PWM.SetDaylight(DaylightPWMValue);    
    
//Lighting expansion control//

    ReefAngel.PWM.SetChannel( 0, WhitePWMValue); 
    ReefAngel.PWM.SetChannel( 1, Actinic1PWMValue);
    ReefAngel.PWM.SetChannel( 2, SupPWMValue);
    ReefAngel.PWM.SetChannel( 3, SupPWMValue);
    ReefAngel.PWM.SetChannel( 4, MoonPWMValue);
    ReefAngel.PWM.SetChannel( 5, MoonPWMValue);
        
    
//Waterchange Mode    
   
  static time_t wcTimer=0;
 
  
  if (ReefAngel.DisplayedMenu == WATERCHANGE_MODE && wcTimer==0);
  {
    wcTimer=now();
  }
  
   if (now()-wcTimer >= 1 && now()-wcTimer < 120)
  {  
    ReefAngel.Relay.Off(Box1_Port7);
    ReefAngel.Relay.Off(Box1_Port8);
  }
  
    if (now()-wcTimer >= 60 && now()-wcTimer < 120)
  {
    if (ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.On(Box1_Port4);
    else  
    ReefAngel.Relay.Off(Box1_Port4);
  }
  
    if (now()-wcTimer >= 120 && now()-wcTimer < 180)
  {
    if (!ReefAngel.HighATO.IsActive())
    ReefAngel.Relay.On(Box1_Port1);
    else 
    ReefAngel.Relay.Off(Box1_Port1);
   } else {
    wcTimer=0;
//    ButtonPress++;
   }
    



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

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

void CheckCloud()
{

  // ------------------------------------------------------------
  // Change the values below to customize your cloud/storm effect

  // Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
  // For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 1 

  // Percentage chance of a cloud happening today
  // For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100

  // Minimum number of minutes for cloud duration.  Don't use max duration of less than 6
#define Min_Cloud_Duration 7

  // Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 20

  // Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 3

  // Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 10

  // Only start the cloud effect after this setting
  // In this example, start cloud after noon
#define Start_Cloud_After NumMins(6,30)

  // Always end the cloud effect before this setting
  // In this example, end cloud before 9:00pm
#define End_Cloud_Before NumMins(18,30)

  // Percentage chance of a lightning happen for every cloud
  // For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 60

  // Note: Make sure to choose correct values that will work within your PWMSLope settings.
  // For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
  // Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen results could happen.
    // Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
  // In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can fit in that 510 minutes window.
    // It's a tight fit, but it did.

    //#define printdebug // Uncomment this for debug print on Serial Monitor window
#define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process. 

    // Add Random Lightning modes
#define Calm 0    // No lightning
#define Slow 1    // 5 seconds of slow lightning in the middle of a cloud for ELN style (slow response) drivers
#define Fast 2    // 5 seconds of fast lightning in the middle of a cloud for LDD style (fast response) drivers
#define Mega 3    // Lightning throughout the cloud, higher chance as it gets darker
#define Mega2 4   // Like Mega, but with more lightning
  // Set which modes you want to use
  // Example:  { Slow, Fast, Mega, Mega2 } to randomize all four modes.  
  // { Mega2 } for just Mega2.  { Mega, Mega, Fast} for Mega and Fast, with twice the chance of Mega.
  byte LightningModes[] = { Calm, Calm, Calm, Slow, Slow, Slow, Slow, Slow, Mega, Mega2 };

  // Change the values above to customize your cloud/storm effect
  // ------------------------------------------------------------
  // Do not change anything below here

   static byte cloudchance=255;
  static byte cloudduration=0;
  static int cloudstart=0;
  static byte numclouds=0;
  static byte lightningchance=0;
  static byte cloudindex=0;
  static byte lightningstatus=0;
  static int LastNumMins=0;
  static byte lightningMode=0;
  static boolean chooseLightning=true;

  static time_t DelayCounter=millis();    // Variable for lightning timing.  
  static int DelayTime=random(1000);      // Variable for lightning timimg.

  // Every day at midnight, we check for chance of cloud happening today
  if (hour()==0 && minute()==0 && second()==0) cloudchance=255;

#ifdef forcecloudcalculation
  if (cloudchance==255)
#else
    if (hour()==0 && minute()==0 && second()==1 && cloudchance==255) 
#endif
    {
      randomSeed(millis());    // Seed the random number generator
      //Pick a random number between 0 and 99
      cloudchance=random(100); 
      // if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
      if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
      // Check if today is day for clouds. 
      if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0; 
      // If we have cloud today
      if (cloudchance)
      {
        // pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
        numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
        // pick the time that the first cloud will start
        // the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day. 
        cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
        // pick a random number for the cloud duration of first cloud.
        cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
        //Pick a random number between 0 and 99
        lightningchance=random(100);
        // if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
        if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0; 
      }
    }
  // Now that we have all the parameters for the cloud, let's create the effect

  if (cloudchance)
  {
        
    //is it time for cloud yet?
    if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
    {
      DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,0,180);
      WhitePWMValue=DaylightPWMValue;
      //MoonPWMValue=DaylightPWMValue;

      if (chooseLightning) 
      { 
        lightningMode=LightningModes[random(100)%sizeof(LightningModes)]; 
        chooseLightning=false; 
      } 
      switch (lightningMode) 
      {
      case Calm:
        break;
      case Mega:
        // Lightning chance from beginning of cloud through the end.  Chance increases with darkness of cloud.
        if (lightningchance && random(ReversePWMSlope(cloudstart,cloudstart+cloudduration,100,0,180))<1 && (millis()-DelayCounter)>DelayTime)
        {
          // Send the trigger 
          Strike();
          DelayCounter=millis();    // If we just had a round of flashes, then lets put in a longer delay
          DelayTime=random(1000);   // of up to a second for dramatic effect before we do another round. 
        }
        break;
      case Mega2:
        // Higher lightning chance from beginning of cloud through the end.  Chance increases with darkness of cloud.
        if (lightningchance && random(ReversePWMSlope(cloudstart,cloudstart+cloudduration,100,0,180))<2)
        {
          Strike();
        }
        break;
      case Fast:
        // 5 seconds of lightning in the middle of the cloud
        if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5 && (millis()-DelayCounter)>DelayTime)
        {
          Strike();

          DelayCounter=millis();    // If we just had a round of flashes, then lets put in a longer delay
          DelayTime=random(1000);   // of up to a second for dramatic effect before we do another round. 
        }
        break;
      case Slow:
        // Slow lightning for 5 seconds in the middle of the cloud.  Suitable for slower ELN style drivers
        if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5) 
        {
          if (random(100)<20) lightningstatus=1; 
          else lightningstatus=0;
          if (lightningstatus)
          {
            DaylightPWMValue=100; 
          }
          else 
          {
            DaylightPWMValue=0;
          }
          delay(1);
        }
        break;
      default:
        break;
      }
    } 
    else 
    {
      chooseLightning=true; // Reset the flag to choose a new lightning type
    }

    if (NumMins(hour(),minute())>(cloudstart+cloudduration))
    {
      cloudindex++;
      if (cloudindex < numclouds)
      {
        cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
        // pick a random number for the cloud duration of first cloud.
        cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
        //Pick a random number between 0 and 99
        lightningchance=random(100);
        // if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
        if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
      }
    }
  }

  // Write the times of the next cloud, next lightning, and cloud duration to the screen and into some customvars for the Portal.
  if (LastNumMins!=NumMins(hour(),minute()))
  {
    LastNumMins=NumMins(hour(),minute());
    ReefAngel.LCD.Clear(255,0,120,132,132);
    ReefAngel.LCD.DrawText(0,255,5,120,"C");
    ReefAngel.LCD.DrawText(0,255,11,120,"00:00");
    ReefAngel.LCD.DrawText(0,255,45,120,"L");
    ReefAngel.LCD.DrawText(0,255,51,120,"00:00");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=11; 
      else x=17;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart/60));
      ReefAngel.CustomVar[3]=cloudstart/60;    // Write the hour of the next cloud to custom variable for Portal reporting
      if ((cloudstart%60)>=10) x=29; 
      else x=35;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart%60));
      ReefAngel.CustomVar[4]=cloudstart%60;    // Write the minute of the next cloud to custom variable for Portal reporting

    }
    ReefAngel.LCD.DrawText(0,255,90,120,cloudduration);
    ReefAngel.CustomVar[7]=(cloudduration);    // Put the duration of the next cloud in a custom var for the portal
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=51; 
      else x=57;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))/60));
      ReefAngel.CustomVar[5]=(cloudstart+(cloudduration/2))/60;    // Write the hour of the next lightning to a custom variable for the Portal
      if (((cloudstart+(cloudduration/2))%60)>=10) x=69; 
      else x=75;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))%60));    // Write the minute of the next lightning to a custom variable for the Portal
      ReefAngel.CustomVar[6]=(cloudstart+(cloudduration/2))%60;
    }
  }   
}

void Strike()
{
  byte n;
  int newdata;
  byte a=random(1,5);    // Pick a number of consecutive flashes from 1 to 4.  
  for (byte i=0; i<a; i++)
  {
    // Flash on
    analogWrite(daylightPWMPin,255);    // Flash on daylight port
    
    newdata=4095;
    Wire.beginTransmission(0x40);      // Address of the dimming expansion module
    Wire.write(0x8+(4*0));             // 0x8 is channel 0, 0x12 is channel 1, etc.  I'm using channel 0.
    Wire.write(newdata&0xff);          // Send the data 8 bits at a time.  This sends the LSB
    Wire.write(newdata>>8);            // This sends the MSB
    Wire.endTransmission();
    
    
       
    int randy=random(20,80);    // Random number for a delay
    if (randy>71) randy=((randy-70)/2)*100;    // Small chance of a longer delay
    delay(randy);                // Wait from 20 to 69 ms, or 100-400 ms
    
    // Flash off.  Return to baseline.
    
    analogWrite(daylightPWMPin,DaylightPWMValue*2.55);      // Flash off

    newdata=ReefAngel.PWM.GetChannelValue(0);   // Use the channel number you're flashing here
    Wire.beginTransmission(0x40);    // Same as above
    Wire.write(0x8+(4*0));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    
    
    
    delay(random(30,50));                // Wait from 30 to 49 ms 
    wdt_reset();    // Reset watchdog timer to avoid re-boots
  }
}

byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
  long n=elapsedSecsToday(now());
  cstart*=60;
  cend*=60;
  if (n<cstart) return PWMStart;
  if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
  if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
  if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
  if (n>cend) return (int) PWMStart;
}

Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: water change build

Post by lnevo »

I dont see anything that would conflict with it, very frustrating I'm sure. Stick in there. Roberto what are we missing?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

>Activate box 1 port 4, until ato high is off, for 10 minutes (Sump out)

What do you mean with this?
What is the 10 minutes? If box1 port 4 is activated as soon as water change is triggered and stops when float switch is off, what is the 10 minute for?
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

Ports 7 & 8 are my returns. I need them to turn off, then box 1 port 4 drains the sump untill HighATO is off. I need the time delay so the water can backflow from the tanks.
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

Try this:

Code: Select all

    static byte status=255;
    static int LastDisplayedMenu=-1;
    
    if (LastDisplayedMenu!=WATERCHANGE_MODE && ReefAngel.DisplayedMenu==WATERCHANGE_MODE) status=0;
    LastDisplayedMenu=ReefAngel.DisplayedMenu;
    if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
    {   
      if (status==0)
      {
        ReefAngel.Relay.On(Box1_Port4);
        ReefAngel.Relay.Off(Box1_Port7);
        ReefAngel.Relay.Off(Box1_Port8);
        if (!ReefAngel.HighATO.IsActive())
        {
          ReefAngel.Relay.Off(Box1_Port4);
          status=1;
        }
      }
      if (status==1)
      {
        ReefAngel.Relay.On(Box1_Port7);
        ReefAngel.Relay.On(Box1_Port8);
        ReefAngel.Relay.On(Box1_Port1);
        if (ReefAngel.HighATO.IsActive())
        {
          ReefAngel.Relay.Off(Box1_Port1);
          ButtonPress++;
          status=255;
        }
      }
    }
Roberto.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

And I was using this to display the boxes and status variable when on water change:

Code: Select all

        ReefAngel.LCD.DrawText(0,255,10,70,status);
        static byte OldTempRelay=0;
	byte TempRelay = ReefAngel.Relay.RelayData;
	TempRelay &= ReefAngel.Relay.RelayMaskOff;
	TempRelay |= ReefAngel.Relay.RelayMaskOn;
	if (TempRelay!=OldTempRelay)
	{
		OldTempRelay=TempRelay;
		ReefAngel.LCD.DrawOutletBox(12, 80, TempRelay);
	}

        TempRelay = ReefAngel.Relay.RelayDataE[0];
	TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
	TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
	if (TempRelay!=OldTempRelay)
	{
		OldTempRelay=TempRelay;
		ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
	}
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

Its not activating. status flag on the app is showing waterchange mode on, nothing changes though.
Image
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

I have a question with how this script is working

Code: Select all

ReefAngel.Relay.Off(Box1_Port8);
        if (!ReefAngel.HighATO.IsActive())
        {
          ReefAngel.Relay.Off(Box1_Port4);
          status=1;
Once HighATO stops being active will it change straight to the next stage?

I need the switch to function, switching on and off, over a time period so it can drain all of the water from the sump. It can take a while for the tanks to finish draining.

Same with Box1_pPort1, which pumps water into the sump a lot faster then my return pumps.
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

Probably because your float switches are not as you are stating it to be in the original post.
It needs to stay in status 0 until ATOHigh is not active.
If ATOHigh is already not active when you enter water change mode, it will go straight into status 1 and you won't see anything change.
So, there must be something wrong with the way your float was described.
I need the switch to function, switching on and off, over a time period so it can drain all of the water from the sump. It can take a while for the tanks to finish draining.
I'm not following what you are saying.
If box1 port1 pumps water out, it will stay pumping until the float is triggered. You don't need time here because what changes status is the float being triggered and not time.
Unless you are not describing what you want correctly.
I'm very confused what you are trying to do and how you want to do it.
I think it will be easier if you draw a flowchart of what you want and explain exactly how many status and how the statuses advances to next one and what happens in each status phase.
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

I understand what you mean with the float switch, sorry for not being more clear.

>Activate when waterchange mode on

>Ports 7 & 8 turn off
>water drains from the tanks into the sump (stage 1)

>port 4 is on when HighATO is on (stage 2)
>water may still be draining from the tanks so the float switch may turn off
>if the float switch turns off and goes instantly to the next stage water could still be draining from the tanks
>maybe this could only activate after a certain time from stage 1, allowing the tanks to drain
>the float switch could potentially already be in the off position

>Ports 7 & 8 turn on (stage 3)

>port1 is on when HighATO is off
>this pumps water into the sump a lot faster then the returns can get it up, which will switch the HighATO on and end, leaving my sump short of water

If I had the money I would get a water level expansion, I'm just trying to use what i have available. Is there a way to run float switches off the second power board?
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

Ok, so you need a time delay for stage 2 where the float status is only checked after a certain amount of time?
Same for stage 3?
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

A delay will work after port 7 & 8 are turned off.

Not sure with the refill as the switch will need to toggle.
A delay after ports 7 & 8 are on will result in my sump running dry. If then the process ends when HighATO is on the sump won't get enough water to fill the tanks. As I said port 1 pumps water into the sump alot faster then ports 7 & 8 can pump it into the tanks
Image
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

This is why in the original post I wanted the float switch process (being able to turn on and off) to run over a time period. Ensuring all water gets out and enough can be pumped back in
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

I still don't follow the run over time you mention.
A float switch is either active or not active and it can't be over time.
It changes from active to not active in a split of a second.
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

Can we make it so it only changes to the next step if the float switch has changed state for a certain time?

I understand the float switch changes instantly but if it does this and ends the process for port 1, the return pumps will run dry. The return pumps will not pump water up into the tanks faster then port 1 can pump water into the sump. Not sure how to explain this anymore mate
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

Ahhh. now I get it.
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

Good to hear mate. Will it be possible to code?
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: water change build

Post by rimai »

Try this:

Code: Select all

  static byte stage=255;
  static int LastDisplayedMenu=-1;
  static time_t lastHighATOActive=0;

  if (LastDisplayedMenu!=WATERCHANGE_MODE && ReefAngel.DisplayedMenu==WATERCHANGE_MODE) stage=0;
  LastDisplayedMenu=ReefAngel.DisplayedMenu;
  if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
  {   
    if (stage==0)
    {
      ReefAngel.Relay.On(Box1_Port4);
      ReefAngel.Relay.Off(Box1_Port7);
      ReefAngel.Relay.Off(Box1_Port8);
      if (ReefAngel.HighATO.IsActive()) lastHighATOActive=now();
      if (now()-lastHighATOActive>6)
      {
        ReefAngel.Relay.Off(Box1_Port4);
        stage=1;
      }
    }
    if (stage==1)
    {
      ReefAngel.Relay.On(Box1_Port7);
      ReefAngel.Relay.On(Box1_Port8);
      ReefAngel.Relay.On(Box1_Port1);
      if (!ReefAngel.HighATO.IsActive()) lastHighATOActive=now();

      if (now()-lastHighATOActive>6)
      {
        ReefAngel.Relay.Off(Box1_Port1);
        ButtonPress++;
        stage=255;
      }
    }


    int highatostatus=now()-lastHighATOActive;
    ReefAngel.LCD.DrawText(0,255,10,60,"high ato:");
    ReefAngel.LCD.DrawText(0,255,70,60,highatostatus);
    ReefAngel.LCD.DrawText(0,255,10,70,"stage:");
    ReefAngel.LCD.DrawText(0,255,70,70,stage);
    static byte OldTempRelay=0;
    byte TempRelay = ReefAngel.Relay.RelayData;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    if (TempRelay!=OldTempRelay)
    {
      OldTempRelay=TempRelay;
      ReefAngel.LCD.DrawOutletBox(12, 80, TempRelay);
    }

    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    if (TempRelay!=OldTempRelay)
    {
      OldTempRelay=TempRelay;
      ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
    }

  }
Roberto.
tyson_mitchell_88
Posts: 80
Joined: Thu Nov 05, 2015 2:45 pm
Location: Australia

Re: water change build

Post by tyson_mitchell_88 »

This is working perfectly for me now, thanks mate.

Thanks lee for all your help too.

Code: Select all

//Waterchange Mode    
   
  static byte stage=255;
  static int LastDisplayedMenu=-1;
  static time_t lastHighATOActive=0;

  if (LastDisplayedMenu!=WATERCHANGE_MODE && ReefAngel.DisplayedMenu==WATERCHANGE_MODE) stage=1;
  LastDisplayedMenu=ReefAngel.DisplayedMenu;
  if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
  {   
        
    if (stage==1)
    { 
      ReefAngel.Relay.Off(Box1_Port7);
      ReefAngel.Relay.Off(Box1_Port8);
      ReefAngel.Relay.On(Box1_Port4);      
      if (!ReefAngel.HighATO.IsActive()) 
        ReefAngel.Relay.Off(Box1_Port4);
      if (ReefAngel.HighATO.IsActive()) lastHighATOActive=now();
      if (now()-lastHighATOActive>10)
      {
        ReefAngel.Relay.Off(Box1_Port4);
        stage=2;
      }
    }
  
     if (stage==2)
     { 
      ReefAngel.Relay.On(Box1_Port1);
      if (ReefAngel.HighATO.IsActive()) 
       ReefAngel.Relay.Off(Box1_Port1);
      if (!ReefAngel.HighATO.IsActive()) lastHighATOActive=now(); 
           
      if (now()-lastHighATOActive>30)
      {
        ReefAngel.Relay.Off(Box1_Port1);
        ButtonPress++;
        stage=255;
      }
    }
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: water change build

Post by lnevo »

Sorry it took so long. Thanks for being a sport and working through it. I'm glad Roberto was able to step in with an elegant solution :)
Post Reply