Feeding coral
Feeding coral
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.
Scott.
Re: Feeding coral
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();
}
Re: Feeding coral
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...
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
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();
}
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
Re: Feeding coral
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
}
Re: Feeding coral
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
What does your features file consist of?
curt
Re: Feeding coral
Features file: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
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__
Re: Feeding coral
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
curt
Re: Feeding coral
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...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
Scott.
Re: Feeding coral
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.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...
curt
Re: Feeding coral
Thanks a bunch!binder wrote: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.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...
curt
Re: Feeding coral
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:
The end result will look like this:
Give this a shot and it should work for you now.
curt
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() )
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();
}
curt
Re: Feeding coral
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.
Now that should work for you.
curt
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();
}
curt
Re: Feeding coral
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!