Tidal Effect Simulation

Share you PDE file with our community
User avatar
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Sat Mar 02, 2013 12:02 pm
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... 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
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Sat Mar 02, 2013 12:03 pm
So, I wanted to get this up so if anyone wants to collaborate or provide any feedback. Thanks for looking.
User avatar
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL
PostPosted: Sat Mar 02, 2013 3:07 pm
Nice work! I'll check this out later.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Sat Mar 02, 2013 10:17 pm
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 5510 times

Posts: 11845
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Sat Mar 02, 2013 10:54 pm
Cool :)
Roberto.
User avatar
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Sat Mar 02, 2013 11:14 pm
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 143 times
User avatar
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Sun Mar 03, 2013 9:07 pm
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.

Posts: 11845
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Mon Mar 04, 2013 9:48 am
Very impressive!!!
How's it working?
Roberto.
User avatar
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Mon Mar 04, 2013 10:11 am
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?

Posts: 11845
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Mon Mar 04, 2013 10:42 am
You need to quit night more. Night mode is a preset speed.
Roberto.
Next

Return to My PDE/INO file

Who is online

Users browsing this forum: No registered users and 3 guests