Re: Tidal Effect Simulation
Posted: Tue Mar 12, 2013 9:37 am
Yep. Will flow smoothly.
Community discussion about Reef Angel Controllers and reefing related subjects
http://forum.reefangel.com/
Code: Select all
#ifndef __TIDE_H__
#define __TIDE_H__
#define PI 3.141593
class Tide
{
public:
Tide();
int CalcTide();
void CalcFlow();
void Init(int Speed, int minOffset, int maxOffset);
void SetOffset(int minOffset, int maxOffset);
void SetWaveLength(double WaveLength);
void SetSpeed(int Speed);
inline int GetSpeed() { return m_Speed; }
inline boolean isIncoming() { return m_Flood; }
inline boolean isOutgoing() { return m_Ebb; }
private:
int m_Speed;
int m_CurrSpeed;
int m_MinOffset;
int m_MaxOffset;
double m_Amp, m_PrevAmp;
double m_WaveLength;
boolean m_Ebb,m_Flood;
};
#endif // __TIDE_H__
Code: Select all
#include <stdlib.h>
#include <math.h>
#include <Time.h>
#include "Tide.h"
#include "Globals.h"
Tide::Tide()
{
m_WaveLength=12*SECS_PER_HOUR;
m_MaxOffset = 50;
m_MinOffset = 10;
m_Speed = 50;
m_Amp = 1;
m_CurrSpeed=m_Speed;
}
void Tide::Init(int Speed, int minOffset, int maxOffset)
{
SetSpeed(Speed);
SetOffset(minOffset,maxOffset);
}
void Tide::SetSpeed(int Speed)
{
m_Speed = Speed;
}
void Tide::SetWaveLength(double WaveLength)
{
m_WaveLength = WaveLength;
}
void Tide::SetOffset(int minOffset, int maxOffset)
{
// We want these in half since they will be multiplied by amplitude (+1/-1)
m_MinOffset = minOffset/2;
m_MaxOffset = maxOffset/2;
}
/*
Spring tides occur during the full moon and the new moon.
At these times, the high tides are very high and the low tides are very low.
Neap tides occur during quarter moons.
The result is a smaller difference between high and low tides
MoonPhase 0-25 = Spring
MoonPhase 26-74 = Neap
MoonPhase 75-100 = Spring
So, the effect of the Moon will be a cosine wave.
*/
int Tide::CalcTide() {
double moonOffset; // gap between high and low
double amplitude; // tide curve
// Calculate the gap between high and low tide based on MoonPhase()
moonOffset=cos(((2*PI)/100)*MoonPhase());
moonOffset=((moonOffset+1)/2)*100; // Comvert to percentage
moonOffset=map(moonOffset,0,100,m_MinOffset,m_MaxOffset);
// Find out the current tidal height
amplitude=sin(((2*PI)/m_WaveLength)*now());
amplitude=amplitude*moonOffset;
// Update Ebb/Flood
m_PrevAmp=m_Amp;
m_Amp=amplitude;
CalcFlow();
// Adjust the calculate speed to be in our adjusted range
m_CurrSpeed=constrain(m_Speed+amplitude,0,100);
return m_CurrSpeed;
}
void Tide::CalcFlow() {
if (m_Amp>m_PrevAmp) {
m_Flood=true;
m_Ebb=false;
} else if (m_Amp<m_PrevAmp) {
m_Flood=false;
m_Ebb=true;
}
}
HATE when that happenslnevo wrote:I think I can use the map() function to shift the range... this way I can stop banging my head and questioning myself...
Code: Select all
ReefAngel.RF.SetMode(Custom,rcSpeedAS,tide.isOutgoing());
ReefAngel.RF.SetMode(Custom,rcSpeed,tide.isIncoming());
Code: Select all
tide.SetSpeed(PWMSlope-1(sl.GetRiseHour(),sl.GetRiseMinute(),
sl.GetSetHour(),sl.GetSetMinute(),vtNightSpeed,vtSpeed,120,vtNightSpeed));
Code: Select all
int rcSpeed=ReefCrestMode(tide.CalcTide(),vtDuration,true);
Code: Select all
int rcSpeedAS=ReefCrestMode(tide.CalcTide(),vtDuration,false)*pumpOffset;
This code is more about how you use it. There is a tide mode function now in the library or you could use the class posted. The difference being that the class tracks ebb and flow of the tide effect. Using the value by itself, you would get a constant speed that varied from a max speed to a min speed with two "high tides" and two "low tides" a day. The gap between the max and min is adjusted based on MoonPhase. I use this value returned and feed it to the RA ReefCrestMode and get that effect on top of it. I'm using the custom rf function so I can control each mp40 separately so I basically flip the primary pump when the tide changes. So far I've been happy. I'm going to go back Ectotech mode for a little while just to see if there's any difference.dapg8gt wrote:Has this code been working well for you? I'm going to be tinkering and setting up my RA in the next few weeks and so far I'm really liking this option. I still need to get the RF module but I will have 4 MP10's and 2 Wp40's on my tank and was wondering if this would be sufficient for that many pumps?
Still really new to RA but I need some randomized flow and the WP's are gonna prob be running max 50-70% so I would just have to alter the speeds and implement this code? Or would I have to have different options installed as I'm running the WP's off PWM and the MP's on the RF? Maybe I should just run the MP's on this and do a seperate code for the WP's?
Sorry if I sidetracked the thread a little but I def would like to try this out and have something that is really not a recurring/looping current.. Thanks in advance for the time put into the code.
lnevo wrote:The question I always ask when someone wants this is what do you want it to do?
The class is pretty easy to use and overall pretty easy to add, but you need to do something with the data it gives you... Right now the output looks like a wave going from the min speed to the max speed 2 times a day (2 high tides and 2 low todes per 24 hours). The speed needs to get passed back to something like the other wave functions, otherwise it's just a constant speed.