Yes it does which is good but also the problem. Both times I checked the tank for something unrelated and noticed the temp was in the low twenties.
I only have 1 temp probe and in my code also use it as the overheat probe. I'm assuming this is ok? Here's my sketch just in case it helps.
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>
//*** 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_MIN 30
#define TUNZE_MAX 75
#define TUNZE_SINE_SEC 23400
#define TUNZE_SINE_SYNC false
#define TUNZE_LONGPULSE_SEC 5
#define TUNZE_LONGPULSE_SYNC false
#define TUNZE_SHORTPULSE_MS 500
#define TUNZE_SHORTPULSE_SYNC true
/*
pulseMinSpeed - % for minimal speed
pulseMaxSpeed - % for maximum speed
pulseDuration - Duration (milliseconds) in which each pulse will be held. The pump will stay at minimal speed for pulseDuration and will stay at maximum speed for pulseDuration.
pulseSync - true if you want to sync pumps to same cycle. one false and one true if you want to anti-sync pumps.
*/
byte tunzeShortPulse(byte pulseMinSpeed, byte pulseMaxSpeed, int pulseDuration, boolean pulseSync) {
pulseMinSpeed = constrain(pulseMinSpeed, 30, 100);
pulseMaxSpeed = constrain(pulseMaxSpeed, 30, 100);
byte tspeed = (millis() % (pulseDuration * 2) < pulseDuration ? pulseMinSpeed : pulseMaxSpeed);
if (pulseSync) {
return tspeed;
}
return (tspeed == pulseMinSpeed) ? pulseMaxSpeed : pulseMinSpeed;
}
/*
pulseMinSpeed - % for minimal speed
pulseMaxSpeed - % for maximum speed
pulseDuration - Duration (seconds) in which each pulse will be held. The pump will stay at minimal speed for pulseDuration and will stay at maximum speed for pulseDuration.
pulseSync - true if you want to sync pumps to same cycle. one false and one true if you want to anti-sync pumps.
*/
byte tunzeLongPulse(byte pulseMinSpeed, byte pulseMaxSpeed, int pulseDuration, boolean pulseSync) {
pulseMinSpeed = constrain(pulseMinSpeed, 30, 100);
pulseMaxSpeed = constrain(pulseMaxSpeed, 30, 100);
byte tspeed = (now() % (pulseDuration * 2) < pulseDuration ? pulseMinSpeed : pulseMaxSpeed);
if (pulseSync) {
return tspeed;
}
return (tspeed == pulseMinSpeed) ? pulseMaxSpeed : pulseMinSpeed;
}
/*
tunzeSineWave
*/
byte tunzeSineWave(boolean isleftpump, byte minspeed, byte maxspeed, int periodSec) {
double x = double(now() % periodSec);
x /= periodSec;
x *= 2.0 * PI;
if (!isleftpump) {
x += PI; // shift the sine wave for the right pump
}
double y = sin(x);// y is now between -1 and 1
y += 1.0; // y is now between 0 and 2
y /= 2.0; // y is now between 0 and 1
// now compute the tunze speed
y *= double(maxspeed - minspeed);
y += double(minspeed);
y += 0.5; // for proper rounding
// y is now between minspeed and maxspeed, constrain for safety
return constrain(byte(y), 30, 100);
}
/*
runTunzes
*/
void runTunzes(byte minSpeed, byte maxSpeed) {
#ifdef TUNZE_MODE_SINE
ReefAngel.PWM.SetDaylight(tunzeSineWave(true, TUNZE_MIN, TUNZE_MAX, TUNZE_SINE_SEC)); // left tunze
ReefAngel.PWM.SetActinic(tunzeSineWave(TUNZE_SINE_SYNC, TUNZE_MIN, TUNZE_MAX, TUNZE_SINE_SEC)); // right tunze
#endif
#ifdef TUNZE_MODE_LONG
ReefAngel.PWM.SetDaylight(tunzeLongPulse(TUNZE_MIN, TUNZE_MAX, TUNZE_LONGPULSE_SEC, true)); // left tunze
ReefAngel.PWM.SetActinic(tunzeLongPulse(TUNZE_MIN, TUNZE_MAX, TUNZE_LONGPULSE_SEC, TUNZE_LONGPULSE_SYNC)); // right tunze
#endif
#ifdef TUNZE_MODE_SHORT
ReefAngel.PWM.SetDaylight(tunzeShortPulse(TUNZE_MIN, TUNZE_MAX, TUNZE_SHORTPULSE_MS, true)); // left tunze
ReefAngel.PWM.SetActinic(tunzeShortPulse(TUNZE_MIN, TUNZE_MAX, TUNZE_SHORTPULSE_MS, TUNZE_SHORTPULSE_SYNC)); // right tunze
#endif
#ifdef TUNZE_MODE_LONGSINE
ReefAngel.PWM.SetDaylight(tunzeLongPulse(TUNZE_MIN, tunzeSineWave(true, TUNZE_MIN, TUNZE_MAX, TUNZE_SINE_SEC), TUNZE_LONGPULSE_SEC, true)); // left tunze
ReefAngel.PWM.SetActinic(tunzeLongPulse(TUNZE_MIN, tunzeSineWave(TUNZE_SINE_SYNC, TUNZE_MIN, TUNZE_MAX, TUNZE_SINE_SEC), TUNZE_LONGPULSE_SEC, TUNZE_LONGPULSE_SYNC)); // right tunze
#endif
#ifdef TUNZE_MODE_SHORTSINE
ReefAngel.PWM.SetDaylight(tunzeShortPulse(TUNZE_MIN, tunzeSineWave(true, TUNZE_MIN, TUNZE_MAX, TUNZE_SINE_SEC), TUNZE_SHORTPULSE_MS, true)); // left tunze
ReefAngel.PWM.SetActinic(tunzeShortPulse(TUNZE_MIN, tunzeSineWave(TUNZE_SINE_SYNC, TUNZE_MIN, TUNZE_MAX, TUNZE_SINE_SEC), TUNZE_SHORTPULSE_MS, TUNZE_SHORTPULSE_SYNC)); // right tunze
#endif
}
byte PORT_TUNZE_1 = Port1;
byte PORT_TUNZE_1_BIT = Port1Bit;
byte PORT_TUNZE_2 = Port2;
byte PORT_TUNZE_2_BIT = Port2Bit;
byte PORT_SKIMMER = Port3;
byte PORT_SKIMMER_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_HEATER = Port7;
byte PORT_HEATER_BIT = Port7Bit;
byte PORT_DOSING = Port8;
byte PORT_DOSING_BIT = Port8Bit;
/*
Setup
*/
void setup() {
ReefAngel.Init(); // Initialize Controller
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.OverheatShutoffPorts = PORT_HEATER_BIT;
ReefAngel.LightsOnPorts = PORT_LED_BIT;
ReefAngel.OverheatProbe = T1_PROBE; // Use Temperature probe 1 to check for overheat
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_DOSING);
ReefAngel.SetTemperatureUnit(Celsius);
}
/*
Loop
*/
void loop() {
ReefAngel.LCD.DrawLargeText(COLOR_STEELBLUE, COLOR_WHITE, 28, 121, "JVR Reef"); // Display Reef Angel banner
ReefAngel.StandardATO(PORT_ATO);
ReefAngel.StandardHeater(PORT_HEATER);
long h = hour();
byte minSpeed = h > 20 || h < 8 ? 30 : 50;
byte maxSpeed = h > 20 || h < 8 ? 75 : 100;
runTunzes(minSpeed, maxSpeed);
ReefAngel.Portal("bubbles");
ReefAngel.ShowInterface();
}