Tunze Control
Posted: Mon Jan 07, 2013 1:25 pm
I have a pair of Tunze Stream 6105's. I will likely do something more complex later, but this is what I put together for now. I found rimai's tunze pulsing functions but I wanted a little more, so I wrote a quick sine wave function to control them. Basically it does this:

Then I added on the pulsing code to pulse from the minimum up to the sine wave flow.
I just set up the #defines and call RunTunzes from in the loop.

Then I added on the pulsing code to pulse from the minimum up to the sine wave flow.
Code: Select all
//*** 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 2
#define TUNZE_LONGPULSE_SYNC true
#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)
{
byte tspeed=0;
PulseMinSpeed=constrain(PulseMinSpeed,30,100);
PulseMaxSpeed=constrain(PulseMaxSpeed,30,100);
tspeed=(millis()%(PulseDuration*2)<PulseDuration?PulseMinSpeed:PulseMaxSpeed);
if (PulseSync)
return tspeed;
else
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)
{
byte tspeed=0;
PulseMinSpeed=constrain(PulseMinSpeed,30,100);
PulseMaxSpeed=constrain(PulseMaxSpeed,30,100);
tspeed=(now()%(PulseDuration*2)<PulseDuration?PulseMinSpeed:PulseMaxSpeed);
if (PulseSync)
return tspeed;
else
return (tspeed==PulseMinSpeed)?PulseMaxSpeed:PulseMinSpeed;
}
byte TunzeSineWave(boolean isleftpump, byte minspeed, byte maxspeed, int period_sec) {
double x,y;
x=double(now()%(period_sec));
x/=period_sec;
x*=2.0*PI;
if (!isleftpump) x+=PI; // shift the sine wave for the right pump
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);
}
void RunTunzes() {
#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
}