hedrickms code

Share you PDE file with our community
Post Reply
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

hedrickms code

Post by hedrickms »

Ok I am finally giving this a try and posting for all to review/use as necessary. I want to thank everyone on this awesome forum for all the great threads and code samples etc... that hopefully will work (in my code) and that have helped me get this done. I have to admit I was a little scared about attempting this (not a serious coder ... just a fooled around for fun) but after doing some reading/research and studying what has been posted by some very talented folks everything worked out fine and I understand more about this controller. BTW... This is the best purchase I have ever made.

My code: It does all the basic controls...heating/cooling pumping, turn relays, and feeding modes. What is unique is how I am trying to utilize some of these items (nothing fancy). Heating and cooling is based on a seasonal temps (I created my own to try). I set it up so I can adjust every month. The other unique thing is my control of pumps and since my lighting is a reef breeder and not controllable I thought it would be fun to see if I can get a random pump mode (daily) and an occasional storm mode (we'll see if it works).

Please look over and provide any comments/feedback to fix or make better.

Enjoy:

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

//******************************************
//define ports
#define Skimmer 		1
#define ReturnPump		2
#define FugeLight		3
#define WCPump			4
#define Heater			5
#define Jebao_MP10		6
#define Cooling			7
#define ATOpump			8
//******************************************

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

    int avgph[10];
    unsigned long totalavgph=0;
    byte avgindex=0;

void DrawCustomMain()
    {
      byte x;
      byte y = 2;
      char text[7];

      // *********** CHANGE TEMP READOUT COLOR DEPENDENT ON FAN AND HEATER STATUS ***********
      int TempColor;        // Color for drawing temperature
      boolean FanOn = ReefAngel.Relay.Status(Cooling);    // Get the status of the fan relay
      boolean HeatOn = ReefAngel.Relay.Status(Heater);   // Get the status of the heater relay
      if (HeatOn) 
      {
        TempColor = COLOR_NAVY;    // Blue text, too cold, heater is on
      }
      if (FanOn)   
      {
          TempColor = COLOR_RED;   // Red text, too warm, fan is on
      }
      if (!HeatOn && !FanOn) 
      {
          TempColor = COLOR_GREEN;  // Green text, no fan or heater on
      }
      // ***********************************************************************************
     
      ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 30, 2, "Hedrick's REEF");       // Put a banner at the top
      ReefAngel.LCD.DrawDate(6, 119);                                                      // Put the date and time at the bottom
      ReefAngel.LCD.Clear(COLOR_BLACK, 1, 11, 132, 11);                                    // Draw a black line under the banner
      x = 6;
      y += MENU_START_ROW*1.0;                                                               // MENU_START_ROW is 10, according to globals.h, so y=2+10+1=13
      ReefAngel.LCD.DrawText(COLOR_BLUE, COLOR_WHITE, x, y+1, "Tank Temp   PH");
      x = 6;
      y = MENU_START_ROW*0.8;
      ConvertNumToString(text, ReefAngel.Params.PH, 100);                                  // Get pH reading and convert
      ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+73, y+12, text, Font8x16);    // Put pH on the screen
      ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);                       // Get T1 temp and convert
      x = 6;
      y += MENU_START_ROW*1.3;
      ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, TempColor, x, y, text);                   // Draw the temperature, white numbers on a colored background
      x += 6;
      y += MENU_START_ROW*1.2;
      ReefAngel.LCD.DrawText(COLOR_BLUE, COLOR_WHITE, x-6, y+5, "Stand Temp");
      ConvertNumToString(text, ReefAngel.Params.Temp[T2_PROBE], 10);                       // Get T2 temp and convert
      y += MENU_START_ROW*1.2;
      x = 6;
      ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, TempColor, x, y, text);                   // Draw the temperature, white numbers on a colored background
      x += 6;
      y += MENU_START_ROW*2.2;

  ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,25,y,"ATO",Font8x8);            // Draw the Float switch status
  if (ReefAngel.HighATO.IsActive()) {
    ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_RED);
  } else {
    ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_GREEN);
  }
  x += 6;
      y += MENU_START_ROW*1.6;
  ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,25,y,"Skimmate",Font8x8);
  if (!ReefAngel.LowATO.IsActive()) {
    ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_RED);
  } else {
    ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_GREEN);
  }
      
      
      byte TempRelay = ReefAngel.Relay.RelayData;                                          // Code for drawing the relay box
      TempRelay &= ReefAngel.Relay.RelayMaskOff;
      TempRelay |= ReefAngel.Relay.RelayMaskOn;
      ReefAngel.LCD.DrawOutletBox(12, 100, TempRelay);
   }
void DrawCustomGraph()
{
}
////// Place global variable code above here


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 = Port1Bit | Port2Bit | Port8Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port8Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = Port3Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port1Bit | Port3Bit | Port5Bit | Port6Bit;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 840 );

    // Feeding and Water Change mode speed
    ReefAngel.DCPump.FeedingSpeed=25;
    ReefAngel.DCPump.WaterChangeSpeed=0;

    
    // Ports that are always on/off
    ReefAngel.Relay.On( ReturnPump );
    ReefAngel.Relay.Off( WCPump );
    ReefAngel.Relay.On( Jebao_MP10 );


    ////// Place additional initialization code below here
		randomSeed(now()%SECS_PER_DAY);
		
		//Custom Variable [0] =  Month/Season
		//Custom Variable [1] =  NTM Feeding mode time remaining
		//Custom Variable [2] =  Storm Mode (24/17)
		//Custom Variable [3] =  Pump Mode
    ////// Place additional initialization code above here
}//End Setup

void loop()
{
    ReefAngel.StandardLights( FugeLight,21,0,9,0 );
    // seasonal temperatures
    SeasonalTemps();
	
	// skimmer on with delay
	ReefAngel.Relay.DelayedOn(Skimmer);
	ReefAngel.DCPump.UseMemory = true; //use Portal Settings 
	ReefAngel.DCPump.ActinicChannel=Sync; // portal settings
    ReefAngel.DCPump.DaylightChannel=AntiSync; //  portal setting
    ////// Place your custom code below here
   
    //Set DCPump (Jebao_MP10)
    JebaoMode();
	// Monitor for float switch for sump level (too low) and turn off return
	CheckFloatSwitches();
	//check and set Jebao for Feeding mode and Turn Skimmer Off if ReturnPump off
	SkimmerOffMode(Skimmer);

    //ATO High Switch
    ReefAngel.SingleATOHigh(ATOpump);

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

    // This should always be the last line
    ReefAngel.Portal( "hedrickms", "xxxxxx" );
    ReefAngel.ShowInterface();
} //End Loop

void CheckFloatSwitches()
{
  static boolean atocheck = false;
  static boolean atoalertsent = false;
  static boolean switchalertsent = false;
  static boolean skimmeralertsent = false;
  static unsigned long atotimeout;
  static unsigned long timeout;
  static WiFiAlert atoAlert, switchAlert, skimmerAlert;

  if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
   return;
  else
  {
  //if ato is on set flag and timer
	  if (ReefAngel.HighATO.IsActive() && ReefAngel.Relay.Status(ATOpump))
	  {
	    atocheck = true;
		atotimeout = now();
	  }

      if (bitRead(ReefAngel.AlertFlags,ATOTimeOutFlag))
	   {
		 if (!atoalertsent)
		 {
			atoAlert.Send("ATO+pump+disabled.");
		    atoalertsent = true;
		 }
		  ReefAngel.Relay.Override(ATOpump,0);
	   // Turn off return if sump level is low
		  if (ReefAngel.HighATO.IsActive() && now()-timeout>3600) //if the ato float is active for 1 hours turn off return skimmer and ato
		   { 
		     if (!switchalertsent)
		     {
			  switchAlert.Send("Sump+level_low+alarm!+Return+pump+Skimmer+disabled.");
			  ReefAngel.Relay.Override(ReturnPump,0);
			  switchalertsent = true;
			 }
		   }
		   else switchalertsent = false; //reset switchalert flag so alert can be sent if needed
	   } 
	   else 
	   {
	     timeout = now();
	     atoalertsent = false; //reset atoalert flag so alert can be sent if needed
		 //run ato for additional 10secs after ato triggered to avoid float bouncing activation
		 if (atocheck && now()-atotimeout<10)
		 {
		   ReefAngel.Relay.On(ATOpump);
		 }
		 else
		 {
		  atocheck = false;
		  ReefAngel.Relay.Off(ATOpump);
		 }
	   }

	  // turn off skimmer if skimmate overflows
      if (!ReefAngel.LowATO.IsActive()) //active by default
	   { 
	     if (!skimmeralertsent)
	     {
           skimmerAlert.Send("Skimmer+Overflow+alarm!+Skimmer+disabled.");
           skimmeralertsent = true;
         }
	     ReefAngel.Relay.Override(Skimmer,0);
	   }
	   else skimmeralertsent = false; //reset skimmer flag so alert can be sent if needed
	   
  }
}// End CheckFloatSwitches

void SkimmerOffMode (byte relayport)
{
  // Turn off relay if Return pump has been shut off
  if (!ReefAngel.Relay.Status(ReturnPump) && ReefAngel.Relay.Status(relayport))
  {
    ReefAngel.Relay.Override(relayport,0);
  }
} //End SkimmerOffModes

void JebaoMode()
{
     static boolean feedingalert = false;
     static boolean pumpstormalert = false;
	 static unsigned long isfeeding;
	 static byte ranMode = random (30);
 	 static byte ranPumpMode = ranMode%9;
     static WiFiAlert pumpAlert;

    if (ReefAngel.DCPump.Mode == Custom)
	 {
		 if (ReefAngel.DisplayedMenu==FEEDING_MODE)
		 {
			 isfeeding = now();
			 feedingalert = false; //reset feeding flag so alert can be sent if needed
		 }
		 if (now()-isfeeding<3600) // Continue for the 60 minutes
		 { 
		   if (!feedingalert)
		   {
    	     pumpAlert.Send("Pump+Mode+NTM+Feeding!+Activated.");
		     feedingalert = true;
		   }
		     ReefAngel.PWM.SetDaylight( NutrientTransportMode(30,70,140,true));
		     ReefAngel.PWM.SetActinic( NutrientTransportMode(30,70,140,false));
			 ReefAngel.CustomVar[1]=((now()-isfeeding)/60);
		 }
		 else 
		 {
			 if (ReefAngel.CustomVar[1]>0) ReefAngel.CustomVar[1]=0;//reset feed timer portal variable if was in feeding mode;
			 if ((now()%SECS_PER_DAY >= 75600) || (now()%SECS_PER_DAY < 28800)) // night mode 9pm -> 8am 
			 {
			   if (now()%SECS_PER_DAY == 75600) pumpstormalert = false; //reset pump flag at 9pm so alert can be sent if needed
			   if (!pumpstormalert)
			   {
				 pumpAlert.Send("Pump+Mode+Sine+NightMode!+Activated.");
				 pumpstormalert = true;
			   }
			   ReefAngel.PWM.SetDaylight(SineMode(25,35,20, true));
			   ReefAngel.PWM.SetActinic(SineMode(25,35,20, false));
			   ReefAngel.CustomVar[3]=99;//night mode = 99
			 }// end night mode 8am	
			 else   //  choose a random pump mode (ReefCrest, TidalSwell, ShortPulse, LongPulse, Else) between 0 and 8
			 {
			  if (now()%SECS_PER_DAY == 28800)//at 8am set pump mode and determine if storm
			  {
				pumpstormalert = false; //reset pump flag so alert can be sent if needed
				//set random pump mode at start of each day (midnight) and determine if storm will occur
				ranMode = random(30);
				ranPumpMode = ranMode%9;
			  }
			  else if (ranMode==27 || ranMode==11)//storm mode only after 8am
			  {
				 if (!pumpstormalert)
				 {
					//enter storm mode for pumps (random)
					pumpAlert.Send("Pump+Mode+STORM!+Activated.");
					pumpstormalert = true; //reset pump flag so alert can be sent if needed
				 }
				 StormMode();
			     ReefAngel.CustomVar[2]=ranMode;
                 ReefAngel.CustomVar[3]=0;
				}
				else
				{
				  switch (ranPumpMode)
				  {
					case 0:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+ShortPule+case0!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      }
				      ReefAngel.PWM.SetActinic( ShortPulseMode(10,70,600,true) );
					  ReefAngel.PWM.SetDaylight( ShortPulseMode(10,70,600,false) ); 
					  break;
					 case 1:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+ReefCrest+case1!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      } 					 
					  ReefAngel.PWM.SetDaylight( ReefCrestMode(50,20,true) ); 
					  ReefAngel.PWM.SetActinic( ReefCrestMode(50,20,false) );
					  break;
					 case 2:
					  if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+TideMode+case2!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      }  					 
					  ReefAngel.PWM.SetActinic( ShortPulseMode(0,75,800,true) );
					  ReefAngel.PWM.SetDaylight( ShortPulseMode(0,75,800,false) ); 				
					  break;
					 case 3:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+ElseMode+case3!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      }					 
					  ReefAngel.PWM.SetDaylight( ElseMode(55,25,true) );
					  ReefAngel.PWM.SetActinic( ElseMode(55,25,false) );
					  break;
					 case 4:
					  if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+TideMode+case4!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      } 
					  ReefAngel.PWM.SetDaylight( ReefCrestMode(55,25,true) ); 
					  ReefAngel.PWM.SetActinic( ReefCrestMode(55,25,false) );
					  break;
					 case 5:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+LongPulse+case5!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      } 					 
					  ReefAngel.PWM.SetDaylight( LongPulseMode(20,70,10,true) );
					  ReefAngel.PWM.SetActinic( LongPulseMode(20,70,10,false) );
					  break;
					 case 6:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+ElseMode+case6!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      } 					 
					  ReefAngel.PWM.SetDaylight( ElseMode(50,15,true) ); 
					  ReefAngel.PWM.SetActinic( ElseMode(50,15,false) );
					  break;
					 case 7:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+SineWave+case7!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      } 					 
					  ReefAngel.PWM.SetDaylight(SineMode(25,50,20, true));
					  ReefAngel.PWM.SetActinic(SineMode(25,50,20, false));
					  break;
					 case 8:
				      if (!pumpstormalert)
				      {
				        //enter storm mode for pumps (random)
				        pumpAlert.Send("Pump+Mode+ShortPule+case8!+Activated.");
				        pumpstormalert = true; //reset pump flag so alert can be sent if needed
				      } 					 
					  ReefAngel.PWM.SetActinic( ShortPulseMode(20,65,300,true) );
					  ReefAngel.PWM.SetDaylight( ShortPulseMode(20,65,300,false) );  
					  break;
				  }//end of random pump mode
				  ReefAngel.CustomVar[2]=ranMode;
				  ReefAngel.CustomVar[3]=ranPumpMode;
			 }//end else switch
			 }//end else pump mode
		 }//end else
	 } //end of DCPump custom

} // End Void JebaoRandomMode()

void StormMode ()
{
	 if ((now()%SECS_PER_DAY >= 28800) && (now()%SECS_PER_DAY < 43200))    //  8am - 12 pm
	 { 
		 ReefAngel.PWM.SetDaylight( NutrientTransportMode(40,85,140,true));
		 ReefAngel.PWM.SetActinic( NutrientTransportMode(40,85,140,false));
	 }
	 else if ((now()%SECS_PER_DAY >= 43200) && (now()%SECS_PER_DAY < 64800))    //  12pm - 6pm
	 { 
	  ReefAngel.PWM.SetDaylight( LongPulseMode(30,55,10,true) );
	  ReefAngel.PWM.SetActinic( LongPulseMode(30,55,10,false) );
	 }		
	 else if ((now()%SECS_PER_DAY >= 64800) && (now()%SECS_PER_DAY < 72000))    //  6pm - 8pm
	 { 
		 ReefAngel.PWM.SetDaylight( NutrientTransportMode(35,75,260,true));
		 ReefAngel.PWM.SetActinic( NutrientTransportMode(35,75,260,false));
	 }
	 else if ((now()%SECS_PER_DAY >= 72000) && (now()%SECS_PER_DAY < 75600))    //  8pm - 9pm
	 {
	  ReefAngel.PWM.SetDaylight( ElseMode(65,25,true) ); 
	  ReefAngel.PWM.SetActinic( ElseMode(65,25,false) );
	 }

}//end StormMode
 
 void SeasonalTemps ()
 {
  ReefAngel.CustomVar[0]=month();
  static int heatArray[][2] = { {792,796},// default in case of error in month=0 (June)
                    {770,774},//January (winter)
                    {774,778},//February (winter)
                    {775,779},//March (early spring)
                    {779,783},//April (spring)
                    {785,789},//May (spring)
                    {792,796},//June (early summer)
                    {799,803},//July (summer)
                    {806,810},//August (summer)
                    {796,801},//September (early fall)
                    {787,791},//October (fall)
                    {780,784},//November (fall)
                    {775,779} };//December (early winter)
					
  static int coolArray[][2] = { {794,799},// default in case of error in month=0 (June)
                    {772,776},//January (winter)
                    {776,780},//February (winter)
                    {777,781},//March (early spring)
                    {781,785},//April (spring)
                    {787,791},//May (spring)
                    {794,798},//June (early summer)
                    {801,805},//July (summer)
                    {808,812},//August (summer)
                    {798,803},//September (early fall)
                    {789,793},//October (fall)
                    {782,786},//November (fall)
                    {777,781} };//December (early winter)
					
  ReefAngel.StandardHeater( Heater,heatArray[month()][0],heatArray[month()][1]);
  ReefAngel.StandardFan(Cooling,coolArray[month()][0],coolArray[month()][1]);
 }//end seasonalTemps

 byte ElseMode( byte MidPoint, byte Offset, boolean WaveSync )
    {
      // Static's only initialize the first time they are called
      static unsigned long LastChange=millis();        // Set the inital time that the last change occurred
      static int Delay = random( 500, 3000);           // Set the initial delay
      static int NewSpeed = MidPoint;                  // Set the initial speed
      static int AntiSpeed = MidPoint;                 // Set the initial anti sync speed
      if ((millis()-LastChange) > Delay)               // Check if the delay has elapsed
      {
        Delay=random(500,5000);                        // If so, come up with a new delay
        int ChangeUp = random(Offset);                 // Amount to go up or down
        if (random(100)<50)                            // 50/50 chance of speed going up or going down
        {
          NewSpeed = MidPoint - ChangeUp;
          AntiSpeed = MidPoint + ChangeUp;
        }
        else
        {
          NewSpeed = MidPoint + ChangeUp;
          AntiSpeed = MidPoint - ChangeUp;
        }
        LastChange=millis();                           // Reset the time of the last change
      }
      if (WaveSync)
      {
        return NewSpeed;
      }
      else
      {
        return AntiSpeed;
      }
    }//end Elsemode()
	
	
Last edited by hedrickms on Wed Nov 19, 2014 6:44 pm, edited 5 times in total.
89delta
Posts: 163
Joined: Mon Oct 15, 2012 7:21 pm
Location: Leesburg, GA

Re: hedrickms code

Post by 89delta »

Love the Seasonal Temps portion of your code...may steal it for mine and go off the temps from the GBR.
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

of course you can. I believe it is working although I have not had the code operational more than a week so I can not confirm that all the months are in fact working. I do not see any reason why they wouldnt
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

I thought about the GBR temps but thought some of temps got pretty cold and didnt want to risk trying it in my tank.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: hedrickms code

Post by lnevo »

I love it. The only thing i would do differently is store the season temps in a multidimensional array. It would then be easier to see the temps in one place and make modifications. You also wouldn't need the case statement as you could just do something like this.

ReefAngel.StandardHeater(Heater,heat_temp[month()][0],heat_temp[month()][1]);
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: hedrickms code

Post by lnevo »

I have to check the actual syntax of that suggestion, but it would still be the same approach.
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

That is a really good suggestion. I will have to play with it to see if I can figure it out. Thanks for the input. If I get it working I will repost my code. Did you see any other potential issues? I plan on removing the notifications once I know it is properly working.

Thanks again.
89delta
Posts: 163
Joined: Mon Oct 15, 2012 7:21 pm
Location: Leesburg, GA

Re: hedrickms code

Post by 89delta »

Yeah I saw what the temps were like....kind of worries me as well. But if its thriving there I dont see why it wouldn't work. Although i'm running my LEDs with GPS coordinates to give me my photoperiod duration so it might just work.

// http://www.divethereef.com/Guides/SeasonsF.asp
//Water Temps Based from Great Barrier Reef
//Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
//84 84 82 80 79 78 72 72 74 79 80 82
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

ok so I am having trouble trying to figure this multi-dim array out. Any idea where I can check/lookup the syntax etc..?

Thanks again.
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

Update: I am testing it now and it appears to be working so unless anyone can find any issues I think I can say success. :D (amazing I didnt think I could do it)

Ok I did some searching and maybe I'm heading in the right direction. Is this on the right path? Does it look correct?

I will try it out but would like to see if I am doing this properly.

Code: Select all

 void SeasonalTemps ()
 {
  static int heatArray[][2] = { {792,796},// default in case of error in month=0 (June)
                    {770,774},//January (winter)
                    {774,778},//February (winter)
                    {775,779},//March (early spring)
                    {779,783},//April (spring)
                    {785,789},//May (spring)
                    {792,796},//June (early summer)
                    {799,803},//July (summer)
                    {806,810},//August (summer)
                    {796,801},//September (early fall)
                    {787,791},//October (fall)
                    {780,784},//November (fall)
                    {775,779} };//December (early winter)
					
  static int coolArray[][2] = { {794,797},// default in case of error in month=0 (June)
                    {772,775},//January (winter)
                    {776,779},//February (winter)
                    {777,780},//March (early spring)
                    {781,784},//April (spring)
                    {787,790},//May (spring)
                    {794,797},//June (early summer)
                    {801,804},//July (summer)
                    {808,811},//August (summer)
                    {798,802},//September (early fall)
                    {789,792},//October (fall)
                    {782,785},//November (fall)
                    {777,780} };//December (early winter)	
					
  ReefAngel.StandardHeater( Heater,heatArray[month()][0],heatArray[month()][1]);
  ReefAngel.StandardFan(Cooling,coolArray[month()][0],coolArray[month()][1]);
 }//end seasonalTemps


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

Re: hedrickms code

Post by lnevo »

Sweet! Very nice.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: hedrickms code

Post by binder »

yeah, what lee said....looks good. nice work. :)
Smotz
Posts: 412
Joined: Sat Mar 30, 2013 5:02 pm
Location: CT, USA

Re: hedrickms code

Post by Smotz »

I like this! This should be a library, no ?
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

Does anyone know why the random(7) function would always select #5 when the controller reboots? I am not sure if it is always doing this yet (cause I rebooted everyday) but my pumps are not switching modes during the day.

Ideas?

code below:

Code: Select all

void JebaoMode()
{
     static boolean feedingalert = false;
     static boolean pumpstormalert = false;
	 static unsigned long isfeeding;
	 static int ranMode = random (9);
     static WiFiAlert pumpAlert;

    if (ReefAngel.DCPump.Mode == Custom)
	 {
		 if (ReefAngel.DisplayedMenu==FEEDING_MODE)
		 {
			 isfeeding = now();
			 feedingalert = false; //reset feeding flag so alert can be sent if needed
		 }
		 if (now()-isfeeding<5400) // Continue for the 90 minutes
		 { 
		   if (!feedingalert)
		   {
    	     pumpAlert.Send("Pump+Mode+NTM+Feeding!+Activated.");
		     feedingalert = true;
		   }
		     ReefAngel.PWM.SetDaylight( NutrientTransportMode(30,70,140,true));
		     ReefAngel.PWM.SetActinic( NutrientTransportMode(30,70,140,false));
		 }
		 else if ((now()%SECS_PER_DAY >= 82800) || (now()%SECS_PER_DAY < 28800)) // night mode 11pm -> 8am 
		 {
		   if (now()%SECS_PER_DAY == 82800) pumpstormalert = false; //reset pump flag so alert can be sent if needed
		   if (!pumpstormalert)
		   {
		     pumpAlert.Send("Pump+Mode+Sine+NightMode!+Activated.");
		     pumpstormalert = true;
		   }
		   ReefAngel.PWM.SetDaylight(SineMode(30,50,20, true));
  		   ReefAngel.PWM.SetActinic(SineMode(30,50,20, false));
		 }// end night mode 8am	
		 else   //  choose a random pump mode (ReefCrest, TidalSwell, ShortPulse, LongPulse, Else) between 0 and 8
		 { 
		  if (now()%SECS_PER_DAY == 28800)//at 8am set pump mode and determine if storm
		  {
		    pumpstormalert = false; //reset pump flag so alert can be sent if needed
		    //set random pump mode at start of each day (midnight) and determine if storm will occur
		    ranMode = random(30);
			if (ranMode!=29 || ranMode!=17) ranMode = random (9);//if not storm set normal random pump mode
		  }
		  if (ranMode==29 || ranMode==17)//storm mode
			{
			  if (!pumpstormalert)
		      {
		        //enter storm mode for pumps (random)
		        pumpAlert.Send("Pump+Mode+STORM!+Activated.");
		        pumpstormalert = true; //reset pump flag so alert can be sent if needed
		      }  
		     StormMode();
			}
			else
			{
  		      switch (ranMode)
		      {
				case 0:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+ShortPule+case0!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  }  
				  ReefAngel.PWM.SetActinic( ShortPulseMode(0,60,400,true) );
				  ReefAngel.PWM.SetDaylight( ShortPulseMode(0,60,400,false) ); 
				  break;
				 case 1:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+ReefCrest+case1!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  }  
				  ReefAngel.PWM.SetDaylight( ReefCrestMode(50,20,true) ); 
				  ReefAngel.PWM.SetActinic( ReefCrestMode(50,20,false) );
				  break;
				 case 2:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+TidalSwell+case2!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  }  
				  ReefAngel.PWM.SetDaylight( TidalSwellMode(70,true) );
				  ReefAngel.PWM.SetActinic( TidalSwellMode(70,false) );
				  break;
				 case 3:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+TidalSwell+case3!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  }  			
				  ReefAngel.PWM.SetDaylight( TidalSwellMode(50,true) );
				  ReefAngel.PWM.SetActinic( TidalSwellMode(50,false) );
				  break;
				 case 4:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+TideMode+case4!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  } 
				  ReefAngel.PWM.SetDaylight( TideMode(50,30,70) );
				  ReefAngel.PWM.SetActinic( TideMode(50,30,70) );
				  break;
				 case 5:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+LongPulse+case5!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  } 
				  ReefAngel.PWM.SetDaylight( LongPulseMode(20,60,10,true) );
				  ReefAngel.PWM.SetActinic( LongPulseMode(20,60,10,false) );
				  break;
				 case 6:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+ElseMode+case6!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  } 
				  ReefAngel.PWM.SetDaylight( ElseMode(50,30,true) ); 
				  ReefAngel.PWM.SetActinic( ElseMode(50,30,false) );
				  break;
				 case 7:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+SineWave+case7!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  } 
				  ReefAngel.PWM.SetDaylight(SineMode(40,70,20, true));
				  ReefAngel.PWM.SetActinic(SineMode(40,70,20, false));
				  break;
				 case 8:
				  if (!pumpstormalert)
				  {
				   //enter storm mode for pumps (random)
				   pumpAlert.Send("Pump+Mode+ShortPule+case8!+Activated.");
				   pumpstormalert = true; //reset pump flag so alert can be sent if needed
				  } 
				  ReefAngel.PWM.SetActinic( ShortPulseMode(10,50,600,true) );
				  ReefAngel.PWM.SetDaylight( ShortPulseMode(10,50,600,false) );  
				  break;
			  }//end of random pump mode
		 }//end else switch
		 }//end else pump mode
	 } //end of DCPump custom

} // End Void JebaoRandomMode()
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: hedrickms code

Post by lnevo »

Because random() isn't seed'ed by default. So if you were troubleshooting something, you'd always have the same stream of random numbers. You will need to seed it with something that would also change, like the current time.

This is what I have:

randomSeed(now()/SECS_PER_DAY);
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

Ahh... got it. Thanks a bunch. Do you seed under Setup ()?
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: hedrickms code

Post by lnevo »

Yes. My INO is in my signature
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

Awesome... Thanks again!

I should have checked there first (my apologies). Sometimes I get a little trigger happy :lol:
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

ok code updated on first post to include fixes to random mode (thanks Lee!). Everything seems to be working.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: hedrickms code

Post by lnevo »

Awesome! Now comes the incessant tweaking and feature adding. :)
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

Already planning the next mod :D

P.S. I already had to order a new cable :) -- all the constant updates ended up pulling/breaking the terminal ends on the cable.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: hedrickms code

Post by lnevo »

You may want to consider ordering the bluetooth module :)
hedrickms
Posts: 32
Joined: Tue Jul 29, 2014 7:36 pm

Re: hedrickms code

Post by hedrickms »

I'm seriously thinking about it. Is the bluetooth module easy to setup and use?

Does anyone know a good/cheap bluetooth adapter for a windows 8 (cheapo) laptop?
Post Reply