Think I might have found a bug in the recent library updates. Noticed that one of my tunze pumps kept running when activating either feeding or water change mode. Code is unchanged and worked prior update. Also verified that the socket is live by swapping the 2 tunze cords on the relay box (i.e. it's not something specified to the pump)
Have included my code for review just in case it's me doing something silly.
Any thoughts?
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 <ReefAngel.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
//*** Define only one mode ***
//#define TUNZE_MODE_SINE // sine wave, no pulse
#define TUNZE_MODE_LONG // no sine wave, long pulse
//#define TUNZE_MODE_SHORT // no sine wave, short pulse
//#define TUNZE_MODE_LONGSINE // sine wave, long pulse
//#define TUNZE_MODE_SHORTSINE // sine wave, short pulse
#define TUNZE_SINE_SEC 10
#define TUNZE_SINE_SYNC false
#define TUNZE_LONGPULSE_SEC 10
#define TUNZE_LONGPULSE_SYNC false
#define TUNZE_SHORTPULSE_MS 500
#define TUNZE_SHORTPULSE_SYNC false
char* TUNZE_LABEL = "Sine Wave - No Pulse";
byte PORT_TUNZE_1 = Port1;
byte PORT_TUNZE_1_BIT = Port1Bit;
byte PORT_TUNZE_2 = Port2;
byte PORT_TUNZE_2_BIT = Port2Bit;
byte PORT_HEATER = Port3;
byte PORT_HEATER_BIT = Port3Bit;
byte PORT_ATO = Port4;
byte PORT_ATO_BIT = Port4Bit;
byte PORT_RETURN = Port5;
byte PORT_RETURN_BIT = Port5Bit;
byte PORT_LED = Port6;
byte PORT_LED_BIT = Port6Bit;
byte PORT_SKIMMER = Port7;
byte PORT_SKIMMER_BIT = Port7Bit;
byte PORT_SALINITY = Port8;
byte PORT_SALINITY_BIT = Port8Bit;
byte TP_DISPLAY = T1_PROBE;
byte TP_SUMP = T2_PROBE;
/*
runTunzes
*/
void runTunzes(byte minSpeed, byte maxSpeed) {
#ifdef TUNZE_MODE_SINE
ReefAngel.PWM.SetDaylight(SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, true));
ReefAngel.PWM.SetActinic(SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, TUNZE_SINE_SYNC));
#endif
#ifdef TUNZE_MODE_LONG
ReefAngel.PWM.SetDaylight(LongPulseMode(minSpeed, maxSpeed, TUNZE_LONGPULSE_SEC, true));
ReefAngel.PWM.SetActinic(LongPulseMode(minSpeed, maxSpeed, TUNZE_LONGPULSE_SEC, TUNZE_LONGPULSE_SYNC));
#endif
#ifdef TUNZE_MODE_SHORT
ReefAngel.PWM.SetDaylight(ShortPulseMode(minSpeed, maxSpeed, TUNZE_SHORTPULSE_MS, true));
ReefAngel.PWM.SetActinic(ShortPulseMode(minSpeed, maxSpeed, TUNZE_SHORTPULSE_MS, TUNZE_SHORTPULSE_SYNC));
#endif
#ifdef TUNZE_MODE_LONGSINE
ReefAngel.PWM.SetDaylight(LongPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, true), TUNZE_LONGPULSE_SEC, true));
ReefAngel.PWM.SetActinic(LongPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, TUNZE_SINE_SYNC), TUNZE_LONGPULSE_SEC, TUNZE_LONGPULSE_SYNC));
#endif
#ifdef TUNZE_MODE_SHORTSINE
ReefAngel.PWM.SetDaylight(ShortPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, true), TUNZE_SHORTPULSE_MS, true));
ReefAngel.PWM.SetActinic(ShortPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, TUNZE_SINE_SYNC), TUNZE_SHORTPULSE_MS, TUNZE_SHORTPULSE_SYNC));
#endif
}
/*
DrawCustomMain
*/
void DrawCustomMain() {
ReefAngel.LCD.DrawDate(6, 2);
char text[7];
byte y = 10;
byte middle = 66;
y = drawSeperator(y);
byte x = 1;
int tempColor = ReefAngel.Relay.Status(PORT_HEATER) ? COLOR_NAVY : COLOR_GREEN;
// Temp Display + pH
ReefAngel.LCD.DrawText(tempColor, COLOR_WHITE, x + 1, y, "Display");
ReefAngel.LCD.DrawText(PHColor, DefaultBGColor, x + middle, y, "pH");
y += 8;
ConvertNumToString(text, ReefAngel.Params.Temp[TP_DISPLAY], 10);
ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, tempColor, x, y, text);
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, PHColor, x + middle, y, text);
y += 17;
//y = drawSeperator(y);
// Temp Sump + Salinity
ReefAngel.LCD.DrawText(tempColor, COLOR_WHITE, x + 1, y, "Sump");
ReefAngel.LCD.DrawText(PHColor, DefaultBGColor, x + middle, y, "Salinity");
y += 8;
ConvertNumToString(text, ReefAngel.Params.Temp[TP_SUMP], 10);
ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, tempColor, x, y, text);
ConvertNumToString(text, ReefAngel.Params.Salinity, 10);
ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, PHColor, x + middle, y, text);
y += 17;
y = drawSeperator(y);
/*
byte val = now() % 60;
y += 17;
ConvertNumToString(text, val, 1);
ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, PHColor, x, y, text);
*/
// TUNZE
y = drawTunzeBar(2, y, 126, false);
//drawTunzeBar(26, y, 102, false);
y = drawSeperator(y);
// Relay
byte relay = ReefAngel.Relay.RelayData;
relay &= ReefAngel.Relay.RelayMaskOff;
relay |= ReefAngel.Relay.RelayMaskOn;
drawOutletBox(13, y, relay);
//ReefAngel.LCD.DrawCircleOutletBox(60, y + 5, relay, false);
y += 14;
y = drawSeperator(y);
// ATO
x = 2;
byte radius = 5;
ReefAngel.LCD.FillCircle(x + radius, y + radius, radius, ReefAngel.LowATO.IsActive() ? COLOR_GREEN : COLOR_RED);
ReefAngel.LCD.FillCircle(x + 2 + 3 * radius, y + radius, radius, ReefAngel.HighATO.IsActive() ? COLOR_GREEN : COLOR_RED);
// Check for ATO
y = 50;
y = drawWarning(40, y, ATO_Exceed_Flag, "ATO");
y = drawWarning(5, y, Overheat_Exceed_Flag, "Overheat");
}
/*
drawWarning
*/
byte drawWarning(byte x, byte y, int location, char* message) {
if (InternalMemory.read(location)) {
byte txtColor = now() % 2 == 0 ? COLOR_RED : COLOR_WHITE;
byte bgColor = now() % 2 == 0 ? COLOR_WHITE : COLOR_RED;
ReefAngel.LCD.DrawHugeText(txtColor, bgColor, x, y, message);
y += 16;
}
return y;
}
/*
drawOutletBox
*/
byte drawOutletBox(byte x, byte y, byte relayData) {
ReefAngel.LCD.Clear(OutletBorderColor, x, y, x + 104, y);
ReefAngel.LCD.Clear(OutletBorderColor, x, y + 12, x + 104, y + 12);
for (byte a = 0; a < 8; a++) {
byte bcolor = OutletOffBGColor;
byte fcolor = OutletOffFGColor;
char temp[] = " ";
if ((relayData&(1 << a)) == 1 << a) {
bcolor = OutletOnBGColor;
fcolor = OutletOnFGColor;
}
ReefAngel.LCD.Clear(bcolor, x + (a * 13), y + 1, x + 13 + (a * 13), y + 11);
itoa(a + 1, temp, 10);
ReefAngel.LCD.DrawText(fcolor, bcolor, x + 4 + (a * 13),y + 3,temp);
}
return y;
}
/*
Draw the seperator
*/
byte SEPERATOR = 0;
byte drawSeperator(byte y) {
ReefAngel.LCD.Clear(COLOR_BLACK, 1, y, 129, y + SEPERATOR);
return y += SEPERATOR + 2;
}
/*
Draw the tunze bar
*/
byte drawTunzeBar(byte x, byte y, byte delta, boolean showLabel) {
byte bgColor = COLOR_GREEN;
byte barColor = COLOR_RED;
byte txtColor = COLOR_WHITE;
if (showLabel) {
ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, x, y, TUNZE_LABEL);
y += 9;
}
ReefAngel.LCD.Clear(bgColor, x, y, x + delta, y + 18);
float tunze1 = ReefAngel.PWM.GetDaylightValue();
float tunze2 = ReefAngel.PWM.GetActinicValue();
x++;
y++;
delta -= 2;
ReefAngel.LCD.Clear(barColor, x, y, x + (tunze1 / 100) * delta, y + 7);
char text[7];
ConvertNumToString(text, tunze1, 1);
ReefAngel.LCD.DrawText(txtColor, barColor, x, y, text);
y += 9;
ReefAngel.LCD.Clear(barColor, x, y, x + (tunze2 / 100) * delta, y + 7);
ConvertNumToString(text, tunze2, 1);
ReefAngel.LCD.DrawText(txtColor, barColor, x, y, text);
return y += 10;
}
/*
DrawCustomGraph
*/
void DrawCustomGraph() {
}
/*
Setup
*/
void setup() {
ReefAngel.Init();
ReefAngel.AddWifi();
ReefAngel.AddStandardMenu();
ReefAngel.AddDateTimeMenu();
ReefAngel.FeedingModePorts = PORT_ATO_BIT | PORT_SKIMMER_BIT | PORT_RETURN_BIT | PORT_TUNZE_1_BIT | PORT_TUNZE_2_BIT;
ReefAngel.WaterChangePorts = PORT_ATO_BIT | PORT_SKIMMER_BIT | PORT_RETURN_BIT | PORT_TUNZE_1_BIT | PORT_TUNZE_2_BIT;
ReefAngel.LightsOnPorts = PORT_LED_BIT;
// Temperature related settings
ReefAngel.SetTemperatureUnit(Celsius);
ReefAngel.OverheatProbe = TP_SUMP;
ReefAngel.OverheatShutoffPorts = PORT_HEATER_BIT;
// Relay states
ReefAngel.Relay.On(PORT_TUNZE_1);
ReefAngel.Relay.On(PORT_TUNZE_2);
ReefAngel.Relay.On(PORT_SKIMMER);
ReefAngel.Relay.On(PORT_RETURN);
ReefAngel.Relay.On(PORT_LED);
ReefAngel.Relay.On(PORT_SALINITY);
}
/*
Loop
*/
void loop() {
//ReefAngel.LCD.DrawLargeText(COLOR_STEELBLUE, COLOR_WHITE, 28, 121, "JVR Reef");
ReefAngel.StandardATO(PORT_ATO);
ReefAngel.StandardHeater(PORT_HEATER);
byte h = hour();
byte minSpeed = h > 22 || h < 7 ? 30 : 50;
byte maxSpeed = h > 22 || h < 7 ? 50 : 80;
runTunzes(minSpeed, maxSpeed);
// Skimmer waits for a minute before it's turned on
ReefAngel.Relay.DelayedOn(PORT_SKIMMER, 1);
ReefAngel.Portal("bubbles");
ReefAngel.ShowInterface();
}