Tidal Effect Simulation

Share you PDE file with our community
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

So, I've started to hack up some functions to perform some simulated tidal effects.

Basically this function will return a speed value you can pass to your WaveMaker or Vortech RF functions or whatever else you would like to do based on a tidal effect. You pass the minimum speed you want, the maximum speed you want and also the minimum gap you want between high and low tide.

Currently the wavelength is set to 12 hours so you get a high-tide and low-tide every 12 hours. The amplitude of the wave is affected by MoonPhase as well, so over the course of the lunar month, the difference between high and low tide will increase and decrease.

For future plans, I want to add some random variation to the wavelength and amplitude as well so that it's not as constant. I also plan on adding a helper function to track if current is incoming, or outgoing so I can set my pumps to switch when the current switches as well.

I have not yet tested from the Arduino yet as it will take a lot of reconfiguration for me to use it, but I've compiled the functions standalone with gcc and charted them in Excel and they do make a nice variabe wave output. I'll try and paste a screenshot of a 28 day cycle.

Anyway, here's the code:

Code: Select all

#define PI 3.141593
/*
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.
*/
this is version .0001 the most current code is on a later post... http://forum.reefangel.com/viewtopic.php?p=22049#p22049

Code: Select all

int calcTide(byte minSpeed, byte maxSpeed, byte minGap) {
  int speed;
  int range = maxSpeed-minSpeed-minGap;
  double wl=60*60*12; // wavelength (12 hours) (to be randomized..)
  
  double gap; // tide gap between high and low
  double result; // tide

  // Calculate the gap between high and low tide based on MoonPhase()
  gap=.5+(cos(((2*PI)/100)*MoonPhase())/2);
  gap=minGap+(range*gap);
  
  // Find out the current tidal height
  result=.5+(sin(((2*PI)/wl)*now())/2); 
  // Adjust the calculate speed to be in our adjusted range
  speed=minSpeed+(result*gap)+(range-(gap/2));

  return speed;
}
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

So, I wanted to get this up so if anyone wants to collaborate or provide any feedback. Thanks for looking.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

Nice work! I'll check this out later.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

Here's the chart that represents my current output. The top line is the speed returned from the function. The middle line represents the lunar effect. And finally, the small little one at the bottom represents our frequency and tidal range. I'm next going to try and turn this in to a small class as I want a bunch of helper functions and access to the variables set without having a bunch of different functions going around.

I've also added some changes, here's the current function.

Code: Select all

int calcTide(int Speed, int minOffset, int maxOffset) {
  int minSpeed=Speed-(maxOffset/2);
  int maxSpeed=Speed+(maxOffset/2);
  int range = maxOffset-minOffset;

  double wavelength=12*SECS_PER_HOUR; // wavelength (12 hours) (to be randomized..)
  double moonOffset; // tide gap between high and low
  double amplitude;  // tide

  // Calculate the gap between high and low tide based on MoonPhase()
  moonOffset=cos(((2*PI)/100)*MoonPhase());
  moonOffset=(moonOffset/2)+.5;
  moonOffset=minOffset+(range*moonOffset);

  // Find out the current tidal height
  amplitude=sin(((2*PI)/wavelength)*now()); 
  amplitude=(amplitude/2)+.5;

  // Adjust the calculate speed to be in our adjusted range
  Speed=minSpeed+(amplitude*moonOffset)+((maxOffset/2)-(moonOffset/2));
  return Speed;
}
Attachments
tidal_chart.png
tidal_chart.png (39.26 KiB) Viewed 14343 times
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Tidal Effect Simulation

Post by rimai »

Cool :)
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

Ok, I turned it into a class. So now you have an object that defines your Tide simulation. Now I have functions I can call to set the wavelength and amplitude. Amplitude is unknown to apply properly yet, but I plan to call SetWaveLength() each day and make it a random percent from 80-120% of the default. I'd like to do the same with the amplitude so there's a variation throughout the days.

The default WaveLength is set for 12 hours currently, and default speed is 50 with a range of 0 to 100.

Here is how to use the class:

Code: Select all

#include <Tide.h>

// In global declarations...
Tide tide;

// In setup()
/* 
    This will set the base speed to 50.
    Maximum range would be 40-60 at New/Full moons 
    Minimum Range of 47.5-52.5 at Quarter Moons
*/ 
tide.Init(50,5,20);
tide.SetWaveLength(12*SECS_PER_HOUR); // This is the default wavelength

// In Loop
tide.CalcSpeed(); // This returns a speed you can use in your WaveMaker or RF.SetMode() commands

tide.isIncoming(); // Returns true if tide current is incoming, false if outgoing
Let me know if you have any questions.
Attachments
Tide.zip
(1.4 KiB) Downloaded 705 times
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

So, been hacking away at my code since I have a lot of Vortech related code to make sure Portal / Memory / Menu functions are all kept in sync, so unfortunately hasn't been so drop-in to get here... but I've converted everything to keep Memory updated, but to manually ReefAngel.RF.SetMode() for me and thus I have the following snipped showing how I'm using my new Tidal code...

Code: Select all

    ReefAngel.RF.SetMode(Custom,ReefCrestMode(masterTide.CalcSpeed()),1-masterTide.isIncoming());
    ReefAngel.RF.SetMode(Custom,ReefCrestMode(slaveTide.CalcSpeed()),masterTide.isIncoming());
So, I'm using the Custom vortech mode and using the custom ReefCrestMode function that Roberto wrote. I'm passing in the speed I calculate from my tidal curve as the speed to set the ReefCrest for. So this adjusts throughout the day. I also have seperate Tide objects right now for night mode, but I need to find a better way. The last argument is how I switch the tide current. By using the calculation 1-tide.IsIncoming(), I flip the channels when the speed starts to drop rather than flipping which Tide to send to each channel.

Anyway, I have yet to test this still. I did start playing with the randomization which worked well for changing the amplitude, but did not make such a nice wave-form when changing the wavelength. I need to find a better way to manipulate the wavelength without jumping to different points in the curve.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Tidal Effect Simulation

Post by rimai »

Very impressive!!!
How's it working?
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Not yet. Lol. I still have to load it up. I've been verifying the algorithm with a standalone executable and loading the output into a spreadsheet.

The major challenge for me was to flip all my code which relied on using memory exclusively to manually using SetMode. I just finished that up last night and ready to test, hopefully. I'm still not thrilled with my night mode approach...

Quick question. Do you know If I'm in night mode, can I still adjust my speed, or do I have to break out and go back in?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Tidal Effect Simulation

Post by rimai »

You need to quit night more. Night mode is a preset speed.
Roberto.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Was afraid of that...guess I'll be writing my own night mode...
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

Code is working so far. I'll have some data after it runs for a while. In the meantime, here's the latest class all packaged up. I would love to get some testers :)
Attachments
Tide.zip
(1.42 KiB) Downloaded 472 times
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

What's the size this takes up. Poor me and my standard RA. :( sad
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

It shouldn't take up much space... it's only one large function and a few helper variables. Give it a try. Be advised I just updated it... had an error with my Ebb/Flood calculation. I need a better way, but at least it should work correctly now.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

Consider me a tester lol
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

Well isIncoming does not seem to be working right... not sure why :(
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

What's it doing? Can you post the code here. I don't have access to arduino software to open .ino
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Ino files are txt...open in any editor.

Basically comparing the amplitude of the sine wave. If its higher than the previous i return true else false...

i think i know what the problem is...the code probably runs too frequently and there may only be a blip when the amplitude is different.. It should change each second but I'm probably getting 5 or 6 checks per second...

I'll have to add a check to limit the test...
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

I mean I'm on an iPhone and it's zipped too. Lol if you figured it out. Cool.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Yeah I know what I need to do. I need to keep the status in a variable. If it changes then we can switch the variable. If it stays the same, no change. Then the function can just return the status variable. That should work. Sound right?
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

Yep. Will flow smoothly.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Tidal Effect Simulation

Post by lnevo »

Ok. New code put in place. Looks like it's working properly... we'll just have to see :)

The tidal curve is looking good. Combined with Roberto's ReefCrest function, I'm quite happy with the way my flow is changing and moving around. The PWMSlope worked great going in and out of "Night" mode.

Here's the latest version.
Attachments
Tide.zip
(1.46 KiB) Downloaded 528 times
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Tidal Effect Simulation

Post by jsclownfish »

nice work! I've been holding off on flow control for awhile to save a few bucks, but the tidal code work and the jebo prices with the RA connection seems to good to pass up,
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

The gap between high and low tide doesn't seem to be as big as it should based on current MoonPhase.. I need to look into that. I'm currently seeing a difference of 11, but it should be closer to 20 since we're close to a new moon. Oops....just realized why! :)
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Yup. The issue was the offsets need to be split in half since we only need half to affect the amplitude. But I was dividing it before I calculated the range which we need as max-min. So my range was half what it should have been. Good to know this was close to my minimum range at quarter moons. I'll post the new code later tonight.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

This post has good info, which probably should have been posted here, but since the question was asked in another thread...

http://forum.reefangel.com/viewtopic.php?p=22021#p22021
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

How would us control freaks implement this without sunlocation.h? I want to define my times really :)
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Has no dependency...it only relies on MoonPhase...

The only thing I use sun location for is to set my night mode timing...you can just as easy hard code that.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Tidal Effect Simulation

Post by DrewPalmer04 »

Just had the same thought. Thanks. Keep us updated. I'm about to "find" time to test this on the tank for you.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Tidal Effect Simulation

Post by lnevo »

Ok. Didn't have time to package it, so I'll just post the code..

Tide.h

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__
Tide.cpp

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;
  }
}
Post Reply