Auto Water Change

Do you have a question on how to do something.
Ask in here.
Post Reply
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Auto Water Change

Post by alexwbush »

This has been a project that I've wanted to start for a while amd really the whole reason I bought this controller vice another more simple controller.

I am using the developmental libraries.

I am starting basic. I want to know how to turn on a relay when I activate water change mode. This is from the ReefAngel.cpp file that I tried to plug in a simple on function. Problem is it only turns on the relay after the water change mode is exited and only for a couple seconds (it might be the delay(200) function).

Code: Select all

void ReefAngelClass::WaterChangeMode()
{
        ReefAngel.Relay.On(Box1_Port6);

	LCD.DrawText(ModeScreenColor, DefaultBGColor, 30, 10, "Auto Water Change");
	Timer[0].Start();  //Start Water Change Mode timer
#ifdef DisplayImages
	LCD.DrawEEPromImage(51,55, 40, 30, I2CEEPROM2, I2CEEPROM2_Water_Change);
#endif  // DisplayImages
  
    int t;
    bool bDone = false;
    do
    {
        t = Timer[0].Trigger - now();
        if ( (t >= 0) && ! Timer[0].IsTriggered() )
        {

            LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
            LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);

        }
        else
        {
            bDone = true;
        }

        if ( Joystick.IsButtonPressed() )
        {
            // joystick button pressed, so we stop the feeding mode
            bDone = true;
        }
        delay(200);
    } while ( ! bDone );

    // we're finished, so let's clear the screen and return
    ClearScreen(DefaultBGColor);
    Timer[3].Start();  // start LCD shutoff timer
}
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Auto Water Change

Post by binder »

2 comments:

1. When you are inside the libraries, you don't need to add in ReefAngel. You can change the ReefAngel.Relay.On(Box1_Port6) to be just Relay.On(Box1_Port6).

2. In order to make the port status change, you need to issue the Relay.Write() function call that tells the controller that you want it to update the status of the ports. So your code should be

Code: Select all

Relay.On(Box1_Port6);
Relay.Write();
That will turn on Box1_Port6. It will not shut it off at all when you exit the function. So you will have to add this at the bottom to turn the port off when you return to the normal stuff.

Code: Select all

// we're finished, so let's clear the screen and return
Relay.Off(Box1_Port6);
Relay.Write();
ClearScreen(DefaultBGColor);
// timer stuff
This will turn off that port when you leave.

So, whenever you are changing the port status (on/off), you must do a Relay.Write() to commit the changes. You can issue several commands before issuing the write then they will all be active at the same time.

curt
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

great info, thanks curt!

I see timers that count down... what about ones that count up so I can see how long something has been on?
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Auto Water Change

Post by binder »

alexwbush wrote: I see timers that count down... what about ones that count up so I can see how long something has been on?
This is the same type of coding as with countdown timers. You will need to save the start time and then while it's still running, take the current time and subtract off the start time to give you the elapsed time.

Here is an example:

Code: Select all

void DisplayTimer()
{
    // time_t, uint32_t, unsigned long - these all have the same meaning
    ReefAngel.ClearScreen(DefaultBGColor);
    uint32_t start = millis();
    ReefAngel.Relay.On(Box1_Port6);
    ReefAngel.Relay.Write();
    bool fDone = false;
    int32_t elapsed;
    do
    {
      elapsed = (millis() - start)/1000;  // 1000 milliseconds per second
      ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 40, 20, elapsed);
      if ( ReefAngel.Joystick.IsButtonPressed() )
        fDone = true;
      delay(200);
    } while ( ! fDone );
    ReefAngel.Relay.Off(Box1_Port6);
    ReefAngel.Relay.Write();
    ReefAngel.ClearScreen(DefaultBGColor);
}
What the above function does, is it turns on Box1_Port6 and starts a counter. It displays the number of seconds that the port has been running. It will stop when you press the joystick button.
  • Screen is cleared when function starts.
  • It starts at position 40,20 (x,y and 0,0 is the top left of the screen with the bottom right being 128, 128).
  • It displays the text/counter on the screen.
  • It checks for the button press, then sleeps for 200 milliseconds to prevent flicker.
  • When done, it exits and clears the screen while shutting off the port.
It's like the previous example only with a counter enabled and no countdown being displayed. You can merge them together if you like.

curt
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

I am trying to get a relay (Box1_Port7 is my test relay) to turn off, then after a couple minutes turn on... all inside water change mode (which is on a timer). I tried using the delayon function, but no luck. It will turn off as coded, but won't turn on after 1 min.

Code from my Reefangel.cpp (not the entire thingo I can post the whole thing if need be):

Code: Select all

//Automatic Water Change
void ReefAngelClass::WaterChangeModeStart()
{
	// turn off ports
#ifdef SaveRelayState
	// TODO Test SaveRelayState
	byte CurrentRelayState = Relay.RelayData;
#endif  // SaveRelayState
        
        /*Sequence
         *At start...
         *1. Turn off ATO
         *2. Turn off sump
         *3. Turn off WC heater
         *4. Turn off WC pump
         *After 10 min...
         *3. Turn on WC pump float switch mode
         *4. Turn on sump
         */

        Relay.Off(Box1_Port7);   //Test Relay

        Relay.Write();

        DelayedOn(Box1_Port7, 1);   //Test delay on. Turn on relay after 1 min

        Relay.Write();
	LCD.DrawText(ModeScreenColor, DefaultBGColor, 8, 10, "Auto Water Change");
	Timer[0].Start();  //Start Feeding Mode timer
#ifdef DisplayImages
	LCD.DrawEEPromImage(51,55, 40, 30, I2CEEPROM2, I2CEEPROM2_Water_Change);
#endif  // DisplayImages
}
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Auto Water Change

Post by rimai »

I'd recommend not changing ReefAngel.cpp core file.
What happens is everytime Curt releases an update, your code would be lost and you would have to apply the diff changes all over again.
Instead, put the code you want inside your PDE file.
But, I think the required variable (ReefAngel.DisplayedMenu) is private and can't be accessed.
Maybe there is another variable that could be used and I have missed.
Curt would be able to help on identifying which variable can be used.
Then, the rest is easy to implement.
Roberto.
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

rimai wrote:I'd recommend not changing ReefAngel.cpp core file.
What happens is everytime Curt releases an update, your code would be lost and you would have to apply the diff changes all over again.
Instead, put the code you want inside your PDE file.
But, I think the required variable (ReefAngel.DisplayedMenu) is private and can't be accessed.
Maybe there is another variable that could be used and I have missed.
Curt would be able to help on identifying which variable can be used.
Then, the rest is easy to implement.
I agree... but it seems the only way I can run this off of the menu is by modifying the reefanel.cpp file.

I am using the latest file with simplified menu and have only had to mod two sections, which I am keeping track of for future change to the file.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Auto Water Change

Post by binder »

alexwbush wrote: I agree... but it seems the only way I can run this off of the menu is by modifying the reefanel.cpp file.

I am using the latest file with simplified menu and have only had to mod two sections, which I am keeping track of for future change to the file.
I'm still working on a way to have you be able to create your own menu (like with the main screen), so when that happens you will definitely be able to do this easier.

DelayedOn(...,...) requires it to be called repeatedly in order for it to know when to turn the port on. So you can't just call it once and not ever call it again.

Once you enter into your WaterChangeMode loop, the main StandardInterface function is processing all the additional events. So the WaterChangeStart just does all the initial prep work for water change mode (like with feeding mode) and then, like Roberto said, the DisplayedMenu variable is set to indicate which mode we are in and processes accordingly. Take a look at the ShowInterface function to see what I'm talking about.

There are 2 ways you can proceed until I get my own custom menu created:
1. Make your water change procedure it's own function and handle everything you do in there, but you lose all of the ability to respond to wifi requests and events. The upside is all of your code is contained within a single function and it's easier to replicate, meaning you just copy your function into your PDE file and then add 2 lines of code to the libraries and you are done.
2. Change the menu item to act like a feeding mode or water change mode click (like in ProcessButtonPressMain()). You choose another DisplayedMenu value and change it to that. Then inside your PDE, you check for the DisplayedMenu value to equal your own value and perform all of your functions. The downside with this is you need to make sure that the other functions don't interfere / override what you are doing.


Roberto is correct, ReefAngel.DisplayedMenu is a private variable and cannot be accessed from within the PDE file.

I know you want this water change to happen automatically. You also want your controller to be responsive to wifi requests during the water change. My first quick thought about how to do this is like I do the CustomMain. So it's 2 fold. Create a function prototype inside ReefAngel.h and then call the function from the menu. Then define and create your function inside your PDE file. You will have to do everything inside the function and you will not have wifi connectivity from the function. Then when the function exits, the controller will resume operations. I know it doesn't sound exactly like you want it, but it's a start. It also allows time to think things through better while you are getting something to function. It won't be any different than the previous water change mode not responding to wifi requests.
Inside ReefAngel.cpp in the ProcessButtonPressMain function, change the water change mode case to this:

Code: Select all

case MainMenu_WaterChangeMode:
{
	YourCustomFunction();
// then act like the exit button was pressed
    SelectedMenuItem = DEFAULT_MENU_ITEM;
    DisplayedMenu = DEFAULT_MENU;
    showmenu = false;
#ifdef CUSTOM_MAIN
	DrawCustomGraph();
#else
	LCD.DrawGraph(5, 5);  // Redraw graphic of params
#endif  // CUSTOM_MAIN
}
Then you must handle everything inside your function. Like I said, it's a start, not the most elegant but it works and requires minimal changes to the libraries. I'm sure there is a better way to handle it but I have to think about it more.

I'll have to keep working on it with my custom menu stuff too but that may not be until the weekend at the earliest.

curt
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Auto Water Change

Post by rimai »

What about adding something like this:

Code: Select all

void ReefAngelClass::GetDisplayedMenu()
{
  return DisplayedMenu;
}
Then, his code could have something like this:

Code: Select all

if (ReefAngel.GetDisplayedMenu()==WATERCHANGE_MODE)
{
  //His code here
}
Code has been revised after posted.

Would this work?
This would actually give everyone the ability to code their own code based on the mode they are in too.
Let's say someone wants special code for feeding mode for example.
Roberto.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Auto Water Change

Post by binder »

rimai wrote:What about adding something like this:

Code: Select all

void ReefAngelClass::GetDisplayedMenu()
{
  return DisplayedMenu;
}
Then, his code could have something like this:

Code: Select all

if (ReefAngel.GetDisplayedMenu()==WATERCHANGE_MODE)
{
  //His code here
}
Code has been revised after posted.

Would this work?
This would actually give everyone the ability to code their own code based on the mode they are in too.
Let's say someone wants special code for feeding mode for example.
One problem with this is that ShowInterface also has scenarios based on the mode the controller is in. This is so we can process the wifi requests and such while in the other modes. So if they do something different than the default code, they could encounter some problems. I doubt it would work like you are wanting it to, but you'd have to test to make sure.

Having the GetDisplayedMenu() function to be able to process the menu would work for custom menus but those modes are slightly different than other scenarios since the controller is displaying a different screen and still processing requests from other stuff. I'm going to have to move the feeding and water change mode stuff to their own function. Then, process the main default_menu (main screen) stuff inside ShowInterface and then allow the user to handle the other 2 modes (feeding and water change) in their own function defined inside their PDE just like with CustomMain. Then they would have to handle the feeding mode or water change mode if they want along with whatever menu items they create. If they want the default options then they could just call the default function and be done with it.

This is all just a thought right now.

curt
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

binder wrote:Having the GetDisplayedMenu() function to be able to process the menu would work for custom menus but those modes are slightly different than other scenarios since the controller is displaying a different screen and still processing requests from other stuff. I'm going to have to move the feeding and water change mode stuff to their own function. Then, process the main default_menu (main screen) stuff inside ShowInterface and then allow the user to handle the other 2 modes (feeding and water change) in their own function defined inside their PDE just like with CustomMain. Then they would have to handle the feeding mode or water change mode if they want along with whatever menu items they create. If they want the default options then they could just call the default function and be done with it.

This is all just a thought right now.

curt
awesome ideas! I'll keep messing with the ReefAngel.cpp for now, but look forward to this change!
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Auto Water Change

Post by rimai »

Maybe my idea was a little vague and caused confusion.
Here is the code I tried and worked for me

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (06/14/2011 20:55)
// RA_061411_2055.pde
//
// This version designed for v0.8.5 Beta 12 or later

/* The following features are enabled for this PDE File: 
#define DisplayImages
#define WavemakerSetup
#define DateTimeSetup
#define VersionMenu
#define ATOSetup
#define MetalHalideSetup
#define DirectTempSensor
#define DisplayLEDPWM
#define StandardLightSetup
*/


#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

byte LastDisplayedMenu=0;


void setup()
{
    ReefAngel.Init();  //Initialize controller
    ReefAngel.WaterChangePorts=B10000000;
    // Ports that are always on
    ReefAngel.Relay.On(Port8);
    ReefAngel.Timer[4].SetInterval(3);
}

void loop()
{
    ReefAngel.ShowInterface();
    if(ReefAngel.DisplayedMenu==WATERCHANGE_MODE && LastDisplayedMenu != ReefAngel.DisplayedMenu) ReefAngel.Timer[4].Start();
    LastDisplayedMenu=ReefAngel.DisplayedMenu;
    if (ReefAngel.Timer[4].IsTriggered()) ReefAngel.Relay.RelayMaskOff|=1<<(Port8-1);   
}
I just turned DisplayedMenu into public for the purposes of testing.
Roberto.
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

thanks Roberto, I'll have to try that to see if it will work with the menu!

Curt, so you're saying while this mode is running, the stats from my tank wouldn't be reported to the banner?
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Auto Water Change

Post by binder »

alexwbush wrote:thanks Roberto, I'll have to try that to see if it will work with the menu!

Curt, so you're saying while this mode is running, the stats from my tank wouldn't be reported to the banner?
If you have your own function that everything is contained in and the controller stays in it for the duration of the mode (say you have everything contained in a WaterChangeFunction()) then yes.
But if you do what Roberto showed then no.

As long as the main loop keeps running and you still encounter the code that sends your banner stats then you will be fine.

curt
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

I'm getting errors from adding in the code Roberto posted...

My code:

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (05/08/2011 17:03)
// RA_050811_1703.pde
//
// This version designed for v0.8.5 Beta 12 or later

/* The following features are enabled for this PDE File: 
#define DisplayImages - ok
#define WavemakerSetup - ok
#define DateTimeSetup - ok
#define ATOSetup - ok, but probably not needed since the ato timeouts are not used
#define MetalHalideSetup - ok
#define DirectTempSensor - ok
#define RelayExp - ok
#define SingleATOSetup - ok, but probably not needed since the single ato function isn't used
#define StandardLightSetup -ok
#define CUSTOM_MAIN - ok
#define COLORS_PDE - ok
*/

//Custom colors
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>

#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

/*
#define Box1_Port1    11    Fuge LED
#define Box1_Port2    12    Carbon Reactor
#define Box1_Port3    13    
#define Box1_Port4    14    Vortech
#define Box1_Port5    15    WC Heater
#define Box1_Port6    16    WC Pump
#define Box1_Port7    17    Actinic LED
#define Box1_Port8    18    
*/


byte LastDisplayedMenu=0;

void DrawCustomMain()
{
  // Change the 30 to adjust the horizontal position of the text on the screen, max 20-21 chars
  ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 35, 2, "Alex's Cube");
  ReefAngel.LCD.DrawDate(6, 119);
  pingSerial();
  ReefAngel.LCD.DrawMonitor(15, 63, ReefAngel.Params,
                            ReefAngel.PWM.GetDaylightValue(), 
                            ReefAngel.PWM.GetActinicValue());
  pingSerial();
  // draw main relay
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
#ifdef RelayExp
  // draw 1st expansion relay
  TempRelay = ReefAngel.Relay.RelayDataE[0];
  TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
  TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
  ReefAngel.LCD.DrawOutletBox(12, 105, TempRelay);
#endif  // RelayExp
}

void DrawCustomGraph()
{
  ReefAngel.LCD.DrawGraph(5, 10);
}

void setup()
{
    ReefAngel.Init();  //Initialize controller

    /*Need to set these up still
    //ReefAngel.FeedingModePorts = B10101000;
    //ReefAngel.WaterChangePorts = B10000010;
    //ReefAngel.WaterChangePorts = B00000001;
    //ReefAngel.OverheatShutoffPorts = B00000110;
    */

    // Ports that are always on 
    ReefAngel.Relay.On(Port8); //Fuge LED
    ReefAngel.Relay.On(Port5); //Vortech    
    ReefAngel.Relay.On(Box1_Port3); //Sump
    
    ReefAngel.PWM.SetDaylight(0);
    ReefAngel.PWM.SetActinic(0);
    
    ReefAngel.Timer[4].SetInterval(3); //start timer for water change menu
}

void loop()
{
    ReefAngel.ShowInterface();

    //water change menu
    if(ReefAngel.DisplayedMenu==WATERCHANGE_MODE && LastDisplayedMenu != ReefAngel.DisplayedMenu) 
    {
      ReefAngel.Timer[4].Start();
      LastDisplayedMenu=ReefAngel.DisplayedMenu;
    }
    if (ReefAngel.Timer[4].IsTriggered()) 
    {
        ReefAngel.Relay.RelayMaskOff|=1<<(Port8-1);   
    }

    // Have PWM on from 12p to 23p, with gradual 60 minute ramp up and down starting at the given times
    // From 12p to 1p, the Actinic PWM will slowly ramp from 15% to 50%
    // From 22p to 23p, the Actinic PWM will slowly ramp from 50% to 15%
    ReefAngel.PWM.SetActinic(PWMSlope(12,0,23,30,15,50,60,ReefAngel.PWM.GetActinicValue()));
    ReefAngel.PWM.SetDaylight(PWMSlope(13,0,22,30,15,50,60,ReefAngel.PWM.GetDaylightValue()));
/*    
    if ((NumMins(hour(now()),minute(now())) < NumMins(12,0)) || (NumMins(hour(now()),minute(now())) > NumMins(23,0)))
    {
      ReefAngel.PWM.SetDaylight(15);
      ReefAngel.PWM.SetActinic(15);
    }
*/
    // Specific functions
    // ReefAngel.SingleATOHigh(Port1);
    if(ReefAngel.HighATO.IsActive())
    {
        ReefAngel.Relay.On(Port3); //WC Pump
        ReefAngel.Relay.On(Box1_Port7); //ATO
    }
    if(ReefAngel.HighATO.IsActive()==false)
    {
        ReefAngel.Relay.Off(Port3); //WC Pump
        ReefAngel.Relay.Off(Box1_Port7); //ATO
    }
    if(ReefAngel.LowATO.IsActive())
        ReefAngel.DelayedOn(Box1_Port4, 1); //Skimmer Delayed on
    if(ReefAngel.LowATO.IsActive()==false)
        ReefAngel.Relay.Off(Box1_Port4); //Skimmer
    
    ReefAngel.StandardLights(Box1_Port8); //Fuge PC
//    ReefAngel.MHLights(Port6); //MH
    ReefAngel.StandardFan(Box1_Port2);
    ReefAngel.StandardHeater(Box1_Port1);
    
    ReefAngel.StandardLights(Port1,13,00,22,30); //Daylight
    ReefAngel.StandardLights(Port2,12,00,23,45); //Actinic
    ReefAngel.StandardLights(Port7,12,00,23,45); //LED Fan
}
Errors:

Code: Select all

C:\Documents and Settings\Webmaster\My Documents\Arduino\libraries\ReefAngel/ReefAngel.h: In function 'void loop()':
C:\Documents and Settings\Webmaster\My Documents\Arduino\libraries\ReefAngel/ReefAngel.h:191: error: 'byte ReefAngelClass::DisplayedMenu' is private
RA_050811_1703:112: error: within this context
C:\Documents and Settings\Webmaster\My Documents\Arduino\libraries\ReefAngel/ReefAngel.h:191: error: 'byte ReefAngelClass::DisplayedMenu' is private
RA_050811_1703:112: error: within this context
C:\Documents and Settings\Webmaster\My Documents\Arduino\libraries\ReefAngel/ReefAngel.h:191: error: 'byte ReefAngelClass::DisplayedMenu' is private
RA_050811_1703:115: error: within this context
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Auto Water Change

Post by rimai »

That's why I said I changed the private variable "DisplayedMenu" to public.
This was just to test, since it would require modifying libraries. Maybe Curt could give us a better way to get the DisplayedMenu variable, so others could also create custom functions that depend on the menu options, for example, custom feeding mode function.
But, if you want to test it anyways the way it is, all you have to do is open ReefAngel.h and move "byte DisplayedMenu;" from private to public section.
Roberto.
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

ah ok, sorry... completely missed over that part!

and I'm about out of memory :(
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

ok, so I got the menu to run, but as soon as I tried to do a simple "relay on" if the water change menu is selected... it shows the water change text and graphic, but no timer. When I exit the menu, the relay turns off, but when I try to reselect water change mode... text and graphic show on controller (still no timer), but the relay won't turn on.

my pde:

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (05/08/2011 17:03)
// RA_050811_1703.pde
//
// This version designed for v0.8.5 Beta 12 or later

/* The following features are enabled for this PDE File: 
#define DisplayImages - ok
#define WavemakerSetup - ok
#define DateTimeSetup - ok
#define ATOSetup - ok, but probably not needed since the ato timeouts are not used
#define MetalHalideSetup - ok
#define DirectTempSensor - ok
#define RelayExp - ok
#define SingleATOSetup - ok, but probably not needed since the single ato function isn't used
#define StandardLightSetup -ok
#define CUSTOM_MAIN - ok
#define COLORS_PDE - ok
*/

//Custom colors
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>

#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

/*
#define Box1_Port1    11    Fuge LED
#define Box1_Port2    12    Carbon Reactor
#define Box1_Port3    13    
#define Box1_Port4    14    Vortech
#define Box1_Port5    15    WC Heater
#define Box1_Port6    16    WC Pump
#define Box1_Port7    17    Actinic LED
#define Box1_Port8    18    
*/


byte LastDisplayedMenu=0;

void DrawCustomMain()
{
  // Change the 30 to adjust the horizontal position of the text on the screen, max 20-21 chars
  ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 35, 2, "Alex's Cube");
  ReefAngel.LCD.DrawDate(6, 119);
  pingSerial();
  ReefAngel.LCD.DrawMonitor(15, 63, ReefAngel.Params,
                            ReefAngel.PWM.GetDaylightValue(), 
                            ReefAngel.PWM.GetActinicValue());
  pingSerial();
  // draw main relay
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
#ifdef RelayExp
  // draw 1st expansion relay
  TempRelay = ReefAngel.Relay.RelayDataE[0];
  TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
  TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
  ReefAngel.LCD.DrawOutletBox(12, 105, TempRelay);
#endif  // RelayExp
}

void DrawCustomGraph()
{
  ReefAngel.LCD.DrawGraph(5, 10);
}

void setup()
{
    ReefAngel.Init();  //Initialize controller

    //Need to set these up still
    //ReefAngel.FeedingModePorts = B10101000;
    ReefAngel.WaterChangePorts = B00000000;
    //ReefAngel.WaterChangePorts = B00000001;
    //ReefAngel.OverheatShutoffPorts = B00000110;
    

    // Ports that are always on 
    ReefAngel.Relay.On(Port8); //Fuge LED
    ReefAngel.Relay.On(Port5); //Vortech    
    ReefAngel.Relay.On(Box1_Port3); //Sump
    
    ReefAngel.PWM.SetDaylight(0);
    ReefAngel.PWM.SetActinic(0);
    
    ReefAngel.Timer[4].SetInterval(3); //start timer for water change menu
}

void loop()
{
    ReefAngel.ShowInterface();

    //water change menu
    if(ReefAngel.DisplayedMenu==WATERCHANGE_MODE && LastDisplayedMenu != ReefAngel.DisplayedMenu) 
    {
      ReefAngel.Timer[4].Start();
      LastDisplayedMenu=ReefAngel.DisplayedMenu;
      ReefAngel.Relay.On(Port6);
      ReefAngel.Relay.Write();
    }
    if (ReefAngel.Timer[4].IsTriggered()) 
    {
        ReefAngel.Relay.RelayMaskOff|=1<<(Port8-1);   
    }
    
    ReefAngel.Relay.Off(Port6);

    // Have PWM on from 12p to 23p, with gradual 60 minute ramp up and down starting at the given times
    // From 12p to 1p, the Actinic PWM will slowly ramp from 15% to 70%
    // From 22p to 23p, the Actinic PWM will slowly ramp from 70% to 15%
    ReefAngel.PWM.SetActinic(PWMSlope(12,0,23,30,15,70,60,ReefAngel.PWM.GetActinicValue()));
    ReefAngel.PWM.SetDaylight(PWMSlope(13,0,22,30,15,75,60,ReefAngel.PWM.GetDaylightValue()));
/*    
    if ((NumMins(hour(now()),minute(now())) < NumMins(12,0)) || (NumMins(hour(now()),minute(now())) > NumMins(23,0)))
    {
      ReefAngel.PWM.SetDaylight(15);
      ReefAngel.PWM.SetActinic(15);
    }
*/
    // Specific functions
    // ReefAngel.SingleATOHigh(Port1);
    if(ReefAngel.HighATO.IsActive())
    {
        ReefAngel.Relay.On(Port3); //WC Pump
        ReefAngel.Relay.On(Box1_Port7); //ATO
    }
    if(ReefAngel.HighATO.IsActive()==false)
    {
        ReefAngel.Relay.Off(Port3); //WC Pump
        ReefAngel.Relay.Off(Box1_Port7); //ATO
    }
    if(ReefAngel.LowATO.IsActive())
        ReefAngel.DelayedOn(Box1_Port4, 1); //Skimmer Delayed on
    if(ReefAngel.LowATO.IsActive()==false)
        ReefAngel.Relay.Off(Box1_Port4); //Skimmer
    
    ReefAngel.StandardLights(Box1_Port8); //Fuge PC
//    ReefAngel.MHLights(Port6); //MH
    ReefAngel.StandardFan(Box1_Port2);
    ReefAngel.StandardHeater(Box1_Port1);
    
    ReefAngel.StandardLights(Port1,13,00,22,30); //Daylight
    ReefAngel.StandardLights(Port2,12,00,23,45); //Actinic
    ReefAngel.StandardLights(Port7,12,00,23,45); //LED Fan
}
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Auto Water Change

Post by rimai »

Hey Alex,

The timer is not being drawn in your code and that's why it does not show.
This line ReefAngel.Relay.Off(Port6); is being executed all the time as there is no if statement in front of it, so it is always turning port 6 off.
I changed you code a little and I think this is what you are trying to achieve

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (05/08/2011 17:03)
// RA_050811_1703.pde
//
// This version designed for v0.8.5 Beta 12 or later

/* The following features are enabled for this PDE File: 
 #define DisplayImages - ok
 #define WavemakerSetup - ok
 #define DateTimeSetup - ok
 #define ATOSetup - ok, but probably not needed since the ato timeouts are not used
 #define MetalHalideSetup - ok
 #define DirectTempSensor - ok
 #define RelayExp - ok
 #define SingleATOSetup - ok, but probably not needed since the single ato function isn't used
 #define StandardLightSetup -ok
 #define CUSTOM_MAIN - ok
 #define COLORS_PDE - ok
 */

//Custom colors
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>

#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

/*
#define Box1_Port1    11    Fuge LED
 #define Box1_Port2    12    Carbon Reactor
 #define Box1_Port3    13    
 #define Box1_Port4    14    Vortech
 #define Box1_Port5    15    WC Heater
 #define Box1_Port6    16    WC Pump
 #define Box1_Port7    17    Actinic LED
 #define Box1_Port8    18    
 */


byte LastDisplayedMenu=0;

void DrawCustomMain()
{
  // Change the 30 to adjust the horizontal position of the text on the screen, max 20-21 chars
  ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 35, 2, "Alex's Cube");
  ReefAngel.LCD.DrawDate(6, 119);
  pingSerial();
  ReefAngel.LCD.DrawMonitor(15, 63, ReefAngel.Params,
  ReefAngel.PWM.GetDaylightValue(), 
  ReefAngel.PWM.GetActinicValue());
  pingSerial();
  // draw main relay
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
#ifdef RelayExp
  // draw 1st expansion relay
  TempRelay = ReefAngel.Relay.RelayDataE[0];
  TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
  TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
  ReefAngel.LCD.DrawOutletBox(12, 105, TempRelay);
#endif  // RelayExp
}

void DrawCustomGraph()
{
  ReefAngel.LCD.DrawGraph(5, 10);
}

void setup()
{
  ReefAngel.Init();  //Initialize controller

  //Need to set these up still
  //ReefAngel.FeedingModePorts = B10101000;
  ReefAngel.WaterChangePorts = B00000000;
  //ReefAngel.WaterChangePorts = B00000001;
  //ReefAngel.OverheatShutoffPorts = B00000110;


  // Ports that are always on 
  ReefAngel.Relay.On(Port8); //Fuge LED
  ReefAngel.Relay.On(Port5); //Vortech    
  ReefAngel.Relay.On(Box1_Port3); //Sump

  ReefAngel.PWM.SetDaylight(0);
  ReefAngel.PWM.SetActinic(0);

  ReefAngel.Timer[4].SetInterval(3); //start timer for water change menu
}

void loop()
{
  ReefAngel.ShowInterface();

  //water change menu
  if(ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
  {
    if(LastDisplayedMenu != ReefAngel.DisplayedMenu) // If Water change mode has just been chosen, let's start the timer and turn Port 6 on
    {
      ReefAngel.Timer[4].Start();
      LastDisplayedMenu=ReefAngel.DisplayedMenu;
      ReefAngel.Relay.On(Port6);
    }
    //Draw Timer 4 in countdown mode
    int t=ReefAngel.Timer[4].Trigger-now();
    if (t>=0)
    {
      ReefAngel.LCD.Clear(255,60+(intlength(t)*5),110,100,108);
      ReefAngel.LCD.DrawText(0,255,60,110,t);
    }
    
    // draw main relay just to make it easy to see what's happening/debug purposes. comment out to save memory space
    byte TempRelay = ReefAngel.Relay.RelayData;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
    
  }
  if (ReefAngel.Timer[4].IsTriggered()) 
  {
    ReefAngel.Relay.Off(Port6);   // Turns Port 6 off when timer 4 runs out
    ButtonPress++;  // Simulate a button press to exit water change mode
    ReefAngel.DisplayedMenu=DEFAULT_MENU;
  }

  // Have PWM on from 12p to 23p, with gradual 60 minute ramp up and down starting at the given times
  // From 12p to 1p, the Actinic PWM will slowly ramp from 15% to 70%
  // From 22p to 23p, the Actinic PWM will slowly ramp from 70% to 15%
  ReefAngel.PWM.SetActinic(PWMSlope(12,0,23,30,15,70,60,ReefAngel.PWM.GetActinicValue()));
  ReefAngel.PWM.SetDaylight(PWMSlope(13,0,22,30,15,75,60,ReefAngel.PWM.GetDaylightValue()));
  /*    
   if ((NumMins(hour(now()),minute(now())) < NumMins(12,0)) || (NumMins(hour(now()),minute(now())) > NumMins(23,0)))
   {
   ReefAngel.PWM.SetDaylight(15);
   ReefAngel.PWM.SetActinic(15);
   }
   */
  // Specific functions
  // ReefAngel.SingleATOHigh(Port1);
  if(ReefAngel.HighATO.IsActive())
  {
    ReefAngel.Relay.On(Port3); //WC Pump
    ReefAngel.Relay.On(Box1_Port7); //ATO
  }
  if(ReefAngel.HighATO.IsActive()==false)
  {
    ReefAngel.Relay.Off(Port3); //WC Pump
    ReefAngel.Relay.Off(Box1_Port7); //ATO
  }
  if(ReefAngel.LowATO.IsActive())
    ReefAngel.DelayedOn(Box1_Port4, 1); //Skimmer Delayed on
  if(ReefAngel.LowATO.IsActive()==false)
    ReefAngel.Relay.Off(Box1_Port4); //Skimmer

  ReefAngel.StandardLights(Box1_Port8); //Fuge PC
  //    ReefAngel.MHLights(Port6); //MH
  ReefAngel.StandardFan(Box1_Port2);
  ReefAngel.StandardHeater(Box1_Port1);

  ReefAngel.StandardLights(Port1,13,00,22,30); //Daylight
  ReefAngel.StandardLights(Port2,12,00,23,45); //Actinic
  ReefAngel.StandardLights(Port7,12,00,23,45); //LED Fan
}
Code was edited after posting.
Roberto.
alexwbush
Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA

Re: Auto Water Change

Post by alexwbush »

wow, thanks Roberto! I'll play with this this weekend!
Post Reply