Feeding coral

Do you have a question on how to do something.
Ask in here.
Post Reply
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Feeding coral

Post by sceia »

When I feed my coral, I have turn off my return(waves still on), add food, wait 5 minutes, turn off my waves, wait 5 minutes then turn waves and return back on. It's a bit different than the feeding mode. How can I program this? I was thinking I could modify the feedingmodeports, delay, then modify again then delay. I'm not sure the correct implementation...

Scott.
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Re: Feeding coral

Post by sceia »

I'm thinking something like this...

Code: Select all

void MenuEntry2() //"Feed Coral"
{
  ReefAngel.DisplayMenuEntry("Feeding Coral");
  ReefAngel.FeedingModePorts = B00010000;
  ReefAngel.FeedingModeStart();
  ReefAngel.FeedingModePorts = B10010000;
  ReefAngel.FeedingModeStart();
}
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Feeding coral

Post by binder »

a "not so elegant" way to do this. and when i say that, i mean that while this is running, the controller will not be monitoring the temperature or responding to wifi events. this could be changed and tweaked but at least it's a start...

Code: Select all

void MenuEntry2()
{
	// clear the screen
	ReefAngel.ClearScreen(DefaultBGColor);
	ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW, "Feeding Coral");
	// Turn off the return port first
	ReefAngel.Relay.Off(Port5);
	ReefAngel.Relay.Write();
	char msg[8];
	bool done = false;
	int t;
	byte row;
	// Have 2 loops / passes
	// The first pass will just wait 5 minutes (or whatever value is stored in the feeding timer)
	// The second pass will turn off the wavemaker port and wait 5 minutes
	// Then the loop will finish and we turn the ports back on
	for ( byte i = 0; i < 2; i++ )
	{
		sprintf(msg, "Phase %d", i+1);
		// leave a blank row and start on the 3rd line
		row = MENU_START_ROW*(i+3);
		ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, row, msg);
		if ( i == 1 )
		{
			// second time through, we enter phase 2, so shutoff the wavemaker now
			ReefAngel.Relay.Off(Port8);
			ReefAngel.Relay.Write();
		}
		// start the feeding timer
		ReefAngel.Timer[FEEDING_TIMER].Start();
		do
		{
			// just loop until the joystick button is pressed or the timer is triggered
			// then break out of the loop and proceed
			// update the timer on the screen
			t = ReefAngel.Timer[FEEDING_TIMER].Trigger - now();
			if ( (t >= 0) && ! ReefAngel.Timer[FEEDING_TIMER].IsTriggered() )
			{
				ReefAngel.LCD.Clear(DefaultBGColor,60+(intlength(t)*5),row,100,row+8);
				ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,60,row,t);
				delay(200);  // to keep from redraw flicker on timer
			}
			else
			{
				done = true;
			}
			if ( ReefAngel.Joystick.IsButtonPressed() )
			{
				// joystick button pressed, so we stop
				done = true;
			}
		} while ( ! done );
		// reset the variable for the inner do while loop
		done = false;
	}
	// Restore ports & return to the main screen
	ReefAngel.Relay.On(Port5);
	ReefAngel.Relay.On(Port8);
	ReefAngel.Relay.Write();
	ReefAngel.ExitMenu();
}
This code will display your "Feeding Coral" at the top of the screen. Then it will show the first phase and do the countdown for you. Then it will enter phase 2, display the phase and do the countdown. After that, it will restore the ports and return you to the main screen.

Note that if you press the joystick button, it will only cancel out of the phase that you are on. So if you are only in phase 1 and you press the joystick button, it will cancel the rest of the phase and enter into the second phase. If you press it again, it will cancel phase 2 and return to normal operation.

I know it looks a little complex but that's only because I'm trying to incorporate the countdown timers on the screen for you plus handle what you want to handle. Since you are only toggling a couple ports (2 based on your feedingmodeports variable), I opted to manually turn them on and off. You can adjust the ports appropriately (ie, change the ports if needed) or change the order that they turn off.

Give this a try and see how it works for you.

curt
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Re: Feeding coral

Post by sceia »

I get a sketch too big error when I put that in the code.... ???

Code: Select all

#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 AutoTopOff          1 
#define Refuge              2 
#define MHLight             3 
#define Actinic             4 
#define WaveController      5 
#define Heater              6 
#define Fans                7 
#define Pumps               8 


#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES 

boolean wmdelay=false;
int delay_minute;

#include <avr/pgmspace.h>
// Create the menu entries
prog_char menu1_label[] PROGMEM = "Feed Fish";
prog_char menu2_label[] PROGMEM = "Feed Coral";
prog_char menu3_label[] PROGMEM = "Water Change";
prog_char menu4_label[] PROGMEM = "All Off";
prog_char menu5_label[] PROGMEM = "Daylights";
prog_char menu6_label[] PROGMEM = "Moonights";
prog_char menu7_label[] PROGMEM = "ATO/OH Clear";
prog_char menu8_label[] PROGMEM = "PH Calibration";
prog_char menu9_label[] PROGMEM = "Date / Time";

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


void MenuEntry1() //"Feed Fish"
{
  ReefAngel.DisplayMenuEntry("Feeding Fish");
  ReefAngel.FeedingModeStart();
}
void MenuEntry2() //"Feed Coral"
{
     // clear the screen
     ReefAngel.ClearScreen(DefaultBGColor);
     ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW, "Feeding Coral");
     // Turn off the return port first
     ReefAngel.Relay.Off(Port5);
     ReefAngel.Relay.Write();
     char msg[8];
     bool done = false;
     int t;
     byte row;
     // Have 2 loops / passes
     // The first pass will just wait 5 minutes (or whatever value is stored in the feeding timer)
     // The second pass will turn off the wavemaker port and wait 5 minutes
     // Then the loop will finish and we turn the ports back on
     for ( byte i = 0; i < 2; i++ )
     {
        sprintf(msg, "Phase %d", i+1);
        // leave a blank row and start on the 3rd line
        row = MENU_START_ROW*(i+3);
        ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, row, msg);
        if ( i == 1 )
        {
           // second time through, we enter phase 2, so shutoff the wavemaker now
           ReefAngel.Relay.Off(Port8);
           ReefAngel.Relay.Write();
        }
        // start the feeding timer
        ReefAngel.Timer[FEEDING_TIMER].Start();
        do
        {
           // just loop until the joystick button is pressed or the timer is triggered
           // then break out of the loop and proceed
           // update the timer on the screen
           t = ReefAngel.Timer[FEEDING_TIMER].Trigger - now();
           if ( (t >= 0) && ! ReefAngel.Timer[FEEDING_TIMER].IsTriggered() )
           {
              ReefAngel.LCD.Clear(DefaultBGColor,60+(intlength(t)*5),row,100,row+8);
              ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,60,row,t);
              delay(200);  // to keep from redraw flicker on timer
           }
           else
           {
              done = true;
           }
           if ( ReefAngel.Joystick.IsButtonPressed() )
           {
              // joystick button pressed, so we stop
              done = true;
           }
        } while ( ! done );
        // reset the variable for the inner do while loop
        done = false;
     }
     // Restore ports & return to the main screen
     ReefAngel.Relay.On(Port5);
     ReefAngel.Relay.On(Port8);
     ReefAngel.Relay.Write();
     ReefAngel.ExitMenu();
}

void MenuEntry3() //"Water Change"
{
  ReefAngel.WaterChangeModeStart();
}
void MenuEntry4() //"All Off"
{
   ReefAngel.Relay.AllOff(); // Turn all ports off.
   ReefAngel.Relay.Write();  // Make relay changes effective
   ReefAngel.DisplayedMenu = ALT_SCREEN_MODE; 
}
void MenuEntry5() //"Toggle Daylights"
{
  ReefAngel.Relay.Toggle(MHLight);
  ReefAngel.Relay.Toggle(Actinic);
  ReefAngel.Relay.Write();
  ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()  //"Toggle Moonights"
{
  ReefAngel.Relay.Toggle(Refuge);
  ReefAngel.Relay.Write();  // Make relay changes effective 
  ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7() //"ATO/OH Clear"
{
  ReefAngel.ATOClear();
  ReefAngel.OverheatClear();
  ReefAngel.DisplayMenuEntry("Clear ATO/Overheat");
}

void MenuEntry8() //"PH Calibration"
{
  ReefAngel.SetupCalibratePH();
  ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void MenuEntry9() //"Date / Time"
{
  ReefAngel.SetupDateTime();
  ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void setup() 
{ 
  //Init and custom menus
  ReefAngel.Init();  //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));

/*
AutoTopOff          1 
Refuge              2 
MHLight             3 
Actinic             4 
WaveController      5 
Heater              6 
Fans                7 
Pumps               8 
*/
    //Menu Modes 
    ReefAngel.FeedingModePorts = B10010000;
    ReefAngel.WaterChangePorts = B10010000;
    ReefAngel.OverheatShutoffPorts = B00001110;
    ReefAngel.LightsOnPorts = B00001110;
  
  //Initialize timer
  ReefAngel.Timer[1].SetInterval(InternalMemory.WM1Timer_read());
  ReefAngel.Timer[1].Start();
  
  //Pumps and waves on
  ReefAngel.Relay.On(Pumps);  //Turn Sump/Skimmer on at startup
  ReefAngel.Relay.On(WaveController);  //Turn WaveController on at startup
}

void loop() 
{ 
  
  
  ReefAngel.LCD.SetContrast(60);  // Set contrast to 60
  
  // Wave controller controls 3 powerheads plugged into 1 RA port.  Night time (10p-8a) is a Lull
  // cycle.  Controller runs for 60s then is off for 20s.
  if (ReefAngel.Timer[1].IsTriggered() )
  {
    if ((hour() >= 22) || (hour() <= 8)) //from 10p-8a  
    {
      if (wmdelay)
      {
        ReefAngel.Timer[1].SetInterval(60);  // wm night delay
        ReefAngel.Timer[1].Start();
        ReefAngel.Relay.Off(WaveController);
        wmdelay=false;
      }
      else
      {
        ReefAngel.Timer[1].SetInterval(20);  // short wave
        ReefAngel.Timer[1].Start();
        ReefAngel.Relay.On(WaveController);
        wmdelay=true;
      }
    }
    else
    {
      //8a-10p normal wave settings
      ReefAngel.Timer[1].SetInterval(InternalMemory.WM1Timer_read());
      ReefAngel.Timer[1].Start();
      ReefAngel.Relay.On(WaveController);
    }
  }
  
  //Top Off
  ReefAngel.StandardATO(AutoTopOff,60);  //Setup AutoTopOff as Auto Top-Off function with 60s timeout
  
  //Light Schedule  
  ReefAngel.StandardLights(Refuge,22,00,6,00);  //Refugium schedule 10:00pm - 6:00am   
  ReefAngel.StandardLights(Actinic,12,00,22,00);  //Actinic schedule 12:00pm - 10:00pm
  ReefAngel.MHLights(MHLight,14,0,20,0,15);  //Daylight schedule 2:00pm - 8:00pm with 15min cool down
  
  //Heating/Cooling
  ReefAngel.StandardHeater(Heater,778,782);  // Setup Heater to turn on at 77.8F and off at 78.2F 
  ReefAngel.StandardFan(Fans,783,900);  // Setup Chiller to turn on at 78.3F and off at 90.0F 
  
  ReefAngel.ShowInterface();
  
  ReefAngel.Relay.Write();  // Make relay changes effective 
}
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Feeding coral

Post by binder »

Check out the other topic we were posting in for help. One thing you will need to make sure is that the CUSTOM_MENU defines are in ReefAngel_Features.h otherwise you can have problems.
What does your features file consist of?

curt
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Re: Feeding coral

Post by sceia »

binder wrote:Check out the other topic we were posting in for help. One thing you will need to make sure is that the CUSTOM_MENU defines are in ReefAngel_Features.h otherwise you can have problems.
What does your features file consist of?

curt
Features file:

Code: Select all


// AutoGenerated file by RAGen (v1.1.0.126), (11/18/2011 18:43)

/*
 * Copyright 2010-11 Curt Binder
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#ifndef __REEFANGEL_FEATURES_H__
#define __REEFANGEL_FEATURES_H__


#define DisplayImages
#define DateTimeSetup
#define wifi
#define SaveRelayState
#define WDT
#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES  9
#define ENABLE_ATO_LOGGING


#endif  // __REEFANGEL_FEATURES_H__
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Feeding coral

Post by binder »

I know you have a menu entry set for Date & Time, but I'd highly recommend you remove the DateTimeSetup section. Since you have wifi enabled, setting the Date & Time is super easy via the wifi interface and can save you about 2000 bytes of code. Also, remove the DisplayImages will save some code (about 300 bytes or so) as well (but not as much as DateTimeSetup).

curt
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Re: Feeding coral

Post by sceia »

binder wrote:I know you have a menu entry set for Date & Time, but I'd highly recommend you remove the DateTimeSetup section. Since you have wifi enabled, setting the Date & Time is super easy via the wifi interface and can save you about 2000 bytes of code. Also, remove the DisplayImages will save some code (about 300 bytes or so) as well (but not as much as DateTimeSetup).

curt
Ok, got rid of date/time. I loaded it up and it's not too big. However, when clicking feed coral.... it goes to the feed coral screen and seems to reboot. It comes completely out of the phase...

Scott.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Feeding coral

Post by binder »

sceia wrote: Ok, got rid of date/time. I loaded it up and it's not too big. However, when clicking feed coral.... it goes to the feed coral screen and seems to reboot. It comes completely out of the phase...
Hmmm....I just loaded the code and it's doing it for me. Lemme test things out and see what I can come up with. We may want to adjust things a little and change it around.

curt
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Re: Feeding coral

Post by sceia »

binder wrote:
sceia wrote: Ok, got rid of date/time. I loaded it up and it's not too big. However, when clicking feed coral.... it goes to the feed coral screen and seems to reboot. It comes completely out of the phase...
Hmmm....I just loaded the code and it's doing it for me. Lemme test things out and see what I can come up with. We may want to adjust things a little and change it around.

curt
Thanks a bunch! :)
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Feeding coral

Post by binder »

The solution is one of those simple things that when I found it, I was like "DOH!" (in a Homer Simpson voice). The problem is we are not resetting the watchdog timer and thus the controller is being reset. Since we are staying inside our own loop, we must reset the watchdog timer ourselves. So, we need to add this line:

Code: Select all

// Add these next 3 lines
#if defined WDT || defined WDT_FORCE
			wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
// Above this line inside the menuentry section in the DO loop
           // update the timer on the screen
           t = ReefAngel.Timer[FEEDING_TIMER].Trigger - now();
           if ( (t >= 0) && ! ReefAngel.Timer[FEEDING_TIMER].IsTriggered() )
The end result will look like this:

Code: Select all


void MenuEntry2() //"Feed Coral"
{
     // clear the screen
     ReefAngel.ClearScreen(DefaultBGColor);
     ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW, "Feeding Coral");
     // Turn off the return port first
     ReefAngel.Relay.Off(Port5);
     ReefAngel.Relay.Write();
     char msg[8];
     bool done = false;
     int t;
     byte row;
     // Have 2 loops / passes
     // The first pass will just wait 5 minutes (or whatever value is stored in the feeding timer)
     // The second pass will turn off the wavemaker port and wait 5 minutes
     // Then the loop will finish and we turn the ports back on
     for ( byte i = 0; i < 2; i++ )
     {
        sprintf(msg, "Phase %d", i+1);
        // leave a blank row and start on the 3rd line
        row = MENU_START_ROW*(i+3);
        ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, row, msg);
        if ( i == 1 )
        {
           // second time through, we enter phase 2, so shutoff the wavemaker now
           ReefAngel.Relay.Off(Port8);
           ReefAngel.Relay.Write();
        }
        // start the feeding timer
        ReefAngel.Timer[FEEDING_TIMER].Start();
        do
        {
           // just loop until the joystick button is pressed or the timer is triggered
           // then break out of the loop and proceed
#if defined WDT || defined WDT_FORCE
			wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
           // update the timer on the screen
           t = ReefAngel.Timer[FEEDING_TIMER].Trigger - now();
           if ( (t >= 0) && ! ReefAngel.Timer[FEEDING_TIMER].IsTriggered() )
           {
              ReefAngel.LCD.Clear(DefaultBGColor,60+(intlength(t)*5),row,100,row+8);
              ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,60,row,t);
              delay(200);  // to keep from redraw flicker on timer
           }
           else
           {
              done = true;
           }
           if ( ReefAngel.Joystick.IsButtonPressed() )
           {
              // joystick button pressed, so we stop
              done = true;
           }
        } while ( ! done );
        // reset the variable for the inner do while loop
        done = false;
     }
     // Restore ports & return to the main screen
     ReefAngel.Relay.On(Port5);
     ReefAngel.Relay.On(Port8);
     ReefAngel.Relay.Write();
     ReefAngel.ExitMenu();
}
Give this a shot and it should work for you now.

curt
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Feeding coral

Post by binder »

Well, it's not a complete solution. I was testing it more and after it finished Phase 1, it reset itself. Seems like we need to add more watchdog resets. I've updated the code and it appears to be working properly for me now.

Here's the new code with another wdt_reset(); added to it.

Code: Select all


void MenuEntry2() //"Feed Coral"
{
     // clear the screen
     ReefAngel.ClearScreen(DefaultBGColor);
     ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW, "Feeding Coral");
     // Turn off the return port first
     ReefAngel.Relay.Off(Port5);
     ReefAngel.Relay.Write();
     char msg[8];
     bool done = false;
     int t;
     byte row;
     // Have 2 loops / passes
     // The first pass will just wait 5 minutes (or whatever value is stored in the feeding timer)
     // The second pass will turn off the wavemaker port and wait 5 minutes
     // Then the loop will finish and we turn the ports back on
     for ( byte i = 0; i < 2; i++ )
     {
        sprintf(msg, "Phase %d", i+1);
        // leave a blank row and start on the 3rd line
        row = MENU_START_ROW*(i+3);
        ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, row, msg);
        if ( i == 1 )
        {
           // second time through, we enter phase 2, so shutoff the wavemaker now
           ReefAngel.Relay.Off(Port8);
           ReefAngel.Relay.Write();
        }
        // start the feeding timer
        ReefAngel.Timer[FEEDING_TIMER].Start();
        do
        {
           // just loop until the joystick button is pressed or the timer is triggered
           // then break out of the loop and proceed
#if defined WDT || defined WDT_FORCE
         wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
           // update the timer on the screen
           t = ReefAngel.Timer[FEEDING_TIMER].Trigger - now();
           if ( (t >= 0) && ! ReefAngel.Timer[FEEDING_TIMER].IsTriggered() )
           {
              ReefAngel.LCD.Clear(DefaultBGColor,60+(intlength(t)*5),row,100,row+8);
              ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,60,row,t);
              delay(200);  // to keep from redraw flicker on timer
           }
           else
           {
              done = true;
           }
           if ( ReefAngel.Joystick.IsButtonPressed() )
           {
              // joystick button pressed, so we stop
              done = true;
           }
        } while ( ! done );
#if defined WDT || defined WDT_FORCE
         wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
        // reset the variable for the inner do while loop
        done = false;
     }
     // Restore ports & return to the main screen
     ReefAngel.Relay.On(Port5);
     ReefAngel.Relay.On(Port8);
     ReefAngel.Relay.Write();
     ReefAngel.ExitMenu();
}
Now that should work for you.

curt
sceia
Posts: 30
Joined: Mon Nov 14, 2011 8:06 pm

Re: Feeding coral

Post by sceia »

Ports were backwards lol....but it works great!! All I got to do now it fine tune what I want the other menus to do and actually mount my ATO. Thanks!
Post Reply