Page 1 of 5

Wave patterns

Posted: Thu Mar 21, 2013 12:38 pm
by rimai
I'd like to start a thread to collect all the efforts of creating wave patterns for controllable pumps.
These functions can be used for either Tunzes or Jebao pumps.
This list will keep being updated as we code more and more functions.

Short Pulse
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.

Code: Select all

byte ShortPulseMode(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;
}
Long Pulse
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.

Code: Select all

byte LongPulseMode(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;
}
Sine
Contribution of Discocarp
http://forum.reefangel.com/viewtopic.ph ... 86&p=18240
PulseMinSpeed - % for minimal speed
PulseMaxSpeed - % for maximum speed
PulseDuration - Duration (seconds) in which the entire sine wave will take to complete.
PulseSync - true if you want to sync pumps to same cycle. one false and one true if you want to anti-sync pumps.

Code: Select all

byte SineMode(byte PulseMinSpeed, byte PulseMaxSpeed, int PulseDuration, boolean PulseSync) {
  double x,y;

  x=double(now()%(PulseDuration));
  x/=PulseDuration;
  x*=2.0*PI;
  if (!PulseSync) 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(PulseMaxSpeed-PulseMinSpeed);
  y+=double(PulseMinSpeed); 
  
  y+=0.5; // for proper rounding
  
  // y is now between PulseMinSpeed and PulseMaxSpeed, constrain for safety  
  return constrain(byte(y),30,100); 
}
ReefCrest
WaveSpeed - % for average speed
WaveOffset - Max offset of speed in which the mode will go up/down from average speed
PulseSync - true if you want to sync pumps to same cycle. one false and one true if you want to anti-sync pumps.

Code: Select all

byte ReefCrestMode(byte WaveSpeed, byte WaveOffset, boolean PulseSync)
{
  static unsigned long lastwavemillis=millis();
  static int newspeed=WaveSpeed;
  if ((millis()-lastwavemillis) > 5000)
  {
    if (random(100)<50) newspeed--; else newspeed++;
    newspeed=constrain(newspeed,WaveSpeed-WaveOffset,WaveSpeed+WaveOffset);
    newspeed=constrain(newspeed,0,100);
    lastwavemillis=millis();
  }  
  if (PulseSync)
    return newspeed;
  else
    return WaveSpeed-(newspeed-WaveSpeed);
}
Nutrient Transport
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.

Code: Select all

byte NutrientTransportMode(byte PulseMinSpeed, byte PulseMaxSpeed, int PulseDuration, boolean PulseSync)
{
  static unsigned long lastwavemillis=millis();
  static byte WavePhase=0;
  static time_t WaveStart=0;
  static byte speed=PulseMinSpeed;
  static byte anti_speed=PulseMinSpeed;

  if (WavePhase==0)
  {
    WavePhase++;
    WaveStart=now();
  }
  else if (WavePhase==1)
  {
    if (now()-WaveStart>2700)
    {
      WavePhase++;
    }
    if ((millis()-lastwavemillis) > PulseDuration)
    {
      if (speed==PulseMinSpeed)
      {  
        speed=PulseMaxSpeed;
        anti_speed=PulseMinSpeed;
      }
      else
      {
        speed=PulseMinSpeed;
        anti_speed=PulseMaxSpeed;
      }
      lastwavemillis=millis();
    }
  }
  else if (WavePhase==2)
  {
    if (now()-WaveStart>4500) WavePhase++;
    if (now()-WaveStart<=2760)
      speed=PulseMinSpeed; 
    else
      speed=PulseMaxSpeed;
    if (now()-WaveStart<=3300)
      anti_speed=PulseMinSpeed;
    else
      anti_speed=PulseMaxSpeed*sin(radians(map(now()-WaveStart,3300,4500,0,180)));
  }
  else if (WavePhase==3)
  {
    if (now()-WaveStart>7200) WavePhase++;
    if ((millis()-lastwavemillis) > PulseDuration)
    {
      if (speed==PulseMinSpeed)
      {  
        speed=PulseMaxSpeed;
        anti_speed=PulseMinSpeed;
      }
      else
      {
        speed=PulseMinSpeed;
        anti_speed=PulseMaxSpeed;
      }
      lastwavemillis=millis();
    }
  }
  else if (WavePhase==4)
  {
    if (now()-WaveStart>9000) WavePhase=0;
    if (now()-WaveStart<=7260) 
      speed=PulseMinSpeed; 
    else
      speed=PulseMaxSpeed;
    if (now()-WaveStart<=8400)
      anti_speed=PulseMaxSpeed*sin(radians(map(now()-WaveStart,7200,8400,0,180)));
    else
      anti_speed=0;
  }
  if (PulseSync)
    return speed;
  else
    return anti_speed;
}
Tidal Swell Mode
WaveMaxSpeed - % for maximum speed
PulseSync - true if you want to sync pumps to same cycle. one false and one true if you want to anti-sync pumps.

Code: Select all

byte TidalSwellMode(byte WaveMaxSpeed, boolean PulseSync)
{
  static unsigned long lastwavemillis=millis();
  static byte WavePhase=0;
  static time_t WaveStart=0;
  static byte speed=0;
  static byte anti_speed=0;

  if (WavePhase==0)
  {
    WavePhase++;
    WaveStart=now();
  }
  else if (WavePhase==1)
  {
    if (now()-WaveStart>900) WavePhase++;
    speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,0,900,0,90))))/10;
    speed+=WaveMaxSpeed/2;

    anti_speed=(WaveMaxSpeed*2*sin(radians(map(now()-WaveStart,0,900,0,90))))/5;
    anti_speed+=WaveMaxSpeed/2;
  }
  else if (WavePhase==2)
  {
    if (now()-WaveStart>1800) WavePhase++;
    speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,900,1800,90,180))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=WaveMaxSpeed/20;

    anti_speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,900,1800,90,180))))/20;
    anti_speed+=WaveMaxSpeed/2;
    anti_speed+=WaveMaxSpeed/4;

  }
  else if (WavePhase==3)
  {
    if (now()-WaveStart>2700) WavePhase++;
    speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,1800,2700,0,90))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=WaveMaxSpeed/20;

    anti_speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,1800,2700,0,90))))/20;
    anti_speed+=WaveMaxSpeed/2;
    anti_speed+=WaveMaxSpeed/4;
  }
  else if (WavePhase==4)
  {
    if (now()-WaveStart>3600) WavePhase++;
    speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,2700,3600,90,180))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=(WaveMaxSpeed*3)/20;

    anti_speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,2700,3600,90,180))))/20;
    anti_speed+=WaveMaxSpeed/2;
    anti_speed+=(WaveMaxSpeed*3)/20;
  }
  else if (WavePhase==5)
  {
    if (now()-WaveStart>4500) WavePhase++;
    speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,3600,4500,0,90))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=(WaveMaxSpeed*3)/20;

    anti_speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,3600,4500,0,90))))/20;
    anti_speed+=WaveMaxSpeed/2;
    anti_speed+=(WaveMaxSpeed*3)/20;
  }
  else if (WavePhase==6)
  {
    if (now()-WaveStart>5400) WavePhase++;
    speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,4500,5400,90,180))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=(WaveMaxSpeed*5)/20;

    anti_speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,4500,5400,90,180))))/20;
    anti_speed+=WaveMaxSpeed/2;
    anti_speed+=WaveMaxSpeed/20;
  }
  else if (WavePhase==7)
  {
    if (now()-WaveStart>6300) WavePhase++;
    speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,5400,6300,0,90))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=(WaveMaxSpeed*5)/20;

    anti_speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,5400,6300,0,90))))/20;
    anti_speed+=WaveMaxSpeed/2;
    anti_speed+=WaveMaxSpeed/20;
  }
  else if (WavePhase==8)
  {
    if (now()-WaveStart>7200) WavePhase++;
    speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,6300,7200,90,180))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=(WaveMaxSpeed*7)/20;

    anti_speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,6300,7200,90,180))))/10;
    anti_speed+=WaveMaxSpeed/2;
  }
  else if (WavePhase==9)
  {
    if (now()-WaveStart>8100) WavePhase++;
    speed=(WaveMaxSpeed*3*sin(radians(map(now()-WaveStart,7200,8100,0,90))))/20;
    speed+=WaveMaxSpeed/2;
    speed+=(WaveMaxSpeed*7)/20;

    anti_speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,7200,8100,0,90))))/2;
    anti_speed+=WaveMaxSpeed/2;
  }
  else if (WavePhase==10)
  {
    if (now()-WaveStart>9000) WavePhase=0;
    speed=(WaveMaxSpeed*sin(radians(map(now()-WaveStart,8100,9000,90,180))))/2;
    speed+=WaveMaxSpeed/2;

    anti_speed=speed;
  }

  if (PulseSync)
    return speed;
  else
    return anti_speed;
}
Tide Mode
Contribution of lnevo
http://forum.reefangel.com/viewtopic.php?f=11&t=2708
WaveSpeed - % for average speed
minOffset - minimum offset between high/low tide
maxOffset - maximum offset between high/low tide

Code: Select all

byte TideMode(byte WaveSpeed, byte minOffset, byte maxOffset)
{
  // Contribution of lnevo
  double moonOffset; // gap between high and low
  double amplitude;  // tide curve
  double wavelength=12*SECS_PER_HOUR;

  // Calculate the gap between high and low tide based on MoonPhase()
  moonOffset=cos(((2*PI)/100)*MoonPhase());
  moonOffset=((moonOffset+1)/2)*100; // Convert to percentage

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

  moonOffset=map(moonOffset,0,100,minOffset,maxOffset);
  amplitude=amplitude*moonOffset; 

  // Adjust the calculate speed to be in our adjusted range
  return constrain(WaveSpeed+amplitude,0,100);
}

Wave patterns

Posted: Thu Mar 21, 2013 12:46 pm
by lnevo
The tide simulation class could be counted as a "constant" wave pattern similar to the Sine wave function above. It returns a constant speed that gives a high tide and low tide effect every 12 hours. The minOffset is the difference between high and low tide during quarter moons and the maxOffset is the difference at new and full moon.

Tide mode:
Speed - base midline speed for wave
minOffset - minimum gap between high/low tide
maxOffset - maximum gap between high/low tide

Code: Select all

#define PI 3.141593

byte TideMode(byte Speed, byte minOffset, byte maxOffset) {
  double moonOffset; // gap between high and low
  double amplitude;  // tide curve
  double wavelength=12*SECS_PER_HOUR;

  // Calculate the gap between high and low tide based on MoonPhase()
  moonOffset=cos(((2*PI)/100)*MoonPhase());
  moonOffset=((moonOffset+1)/2)*100; // Convert to percentage

  // Find out the current tidal height
  amplitude=sin(((2*PI)/waveLength)*now()); 

  moonOffset=map(moonOffset,0,100,minOffset,maxOffset);
  amplitude=amplitude*moonOffset; 
  
  // Adjust the calculate speed to be in our adjusted range
  return constrain(Speed+amplitude,0,100);
}
Also should note that these functions could also be used with the Vortech custom mode :)

Edit: Updated to fix the broken map (did not like 0-1)..

Re: Wave patterns

Posted: Thu Mar 21, 2013 1:33 pm
by DrewPalmer04
fantastic! I like info on one page!

Re: Wave patterns

Posted: Thu Mar 21, 2013 2:35 pm
by Piper
Very nice! Thanks, Roberto!!

Re: Wave patterns

Posted: Thu Mar 21, 2013 5:08 pm
by treetopflyn
Awesome. Thank you.

Wave patterns

Posted: Fri Mar 22, 2013 7:10 am
by VSpeck
Thanks this is awesome.

Re: Wave patterns

Posted: Fri Mar 22, 2013 12:38 pm
by mudcat1
Roberto, this is a great idea! You are really going to save new Reef Angel users a lot of time with this post. Thinking back on the countless hours that I spent researching this information in various threads when I got my Tunze powerhead.

Re: Wave patterns

Posted: Sun Mar 31, 2013 4:58 am
by Smotz
excellent resource

Re: Wave patterns

Posted: Sun Mar 31, 2013 1:08 pm
by Seedlessone
So does anyone have a favorite yet?

Re: Wave patterns

Posted: Mon Apr 01, 2013 5:54 pm
by Seedlessone
So is reef crest just a slow ramp up and down to the predefined range?

Seems to slow for me. Would like it to change values up and down faster.

Are there any aggressive modes? I loved the else mode.

Re: Wave patterns

Posted: Mon Apr 01, 2013 6:45 pm
by DrewPalmer04
Seedlessone wrote:So is reef crest just a slow ramp up and down to the predefined range?

Seems to slow for me. Would like it to change values up and down faster.

Are there any aggressive modes? I loved the else mode.

Change   if ((millis()-lastwavemillis) > 5000) to any value >5000 so 4000, 3000 etc

That'll speed you up on how often it checks for random -- else ++

Re: Wave patterns

Posted: Mon Apr 01, 2013 8:40 pm
by rimai
You can do short pulse mode with random range. Would that work?

Re: Wave patterns

Posted: Sun Apr 14, 2013 5:04 am
by Smotz
rimai wrote:You can do short pulse mode with random range. Would that work?

Can you give me an example of this code?

Re: Wave patterns

Posted: Sun Apr 14, 2013 8:57 am
by rimai

Code: Select all

ReefAngel.PWM.SetActinic(ShortPulseMode(0, 100, random(500,1500), true));

Re: Wave patterns

Posted: Sun Apr 14, 2013 4:04 pm
by Smotz
As always, much appreciated.

I know the 0 to 100 means between 0 and 100% power - I would want to limit that to 70% max so I would make mine 70.

The 500,1500 is duration in milliseconds?

Re: Wave patterns

Posted: Sun Apr 14, 2013 8:01 pm
by rimai
Correct :)
You can also change the duration to whatever range you prefer.

Re: Wave patterns

Posted: Mon Apr 15, 2013 12:30 pm
by Smotz
So I set this code but it's not giving me the desired effect:

ReefAngel.PWM.SetDaylight( LongPulseMode(random(35,70),70,5,true));

what is does is quickly go through a bunch of random numbers, then it stays at 70% for 5 seconds.

What I wanted is for it to choose a random strength between 35 and 70% for 5 seconds.

Thoughts?

Re: Wave patterns

Posted: Mon Apr 15, 2013 1:16 pm
by rimai
I see now that this solution will not work.
Try this:

Code: Select all

byte random_speed=35;
if (now()%5==1) random_speed=random(35,70);
ReefAngel.PWM.SetDaylight( LongPulseMode(random_speed,70,5,true)); 

Re: Wave patterns

Posted: Mon Apr 15, 2013 4:52 pm
by Smotz
rimai wrote:I see now that this solution will not work.
Try this:

Code: Select all

byte random_speed=35;
if (now()%5==1) random_speed=random(35,70);
ReefAngel.PWM.SetDaylight( LongPulseMode(random_speed,70,5,true)); 

Any way to incorporate a pause (1 second) before the next pulse?

Re: Wave patterns

Posted: Mon Apr 15, 2013 5:01 pm
by rimai
Not with this function.
You will need to use another custom function with whatever wave pattern you want.
Let me see if I understand...
The wave is going to be random between 35% and 70% for 5 seconds, 70% for 5 seconds and 0% for 1 second?
Weird one :roll: , but we can definitely do it... :mrgreen:

Re: Wave patterns

Posted: Mon Apr 15, 2013 5:33 pm
by Smotz
rimai wrote:Not with this function.
You will need to use another custom function with whatever wave pattern you want.
Let me see if I understand...
The wave is going to be random between 35% and 70% for 5 seconds, 70% for 5 seconds and 0% for 1 second?
Weird one :roll: , but we can definitely do it... :mrgreen:

I guess. I am just trying to (logically) figure out a wave pattern with just 1 pump (and the return pump)

Re: Wave patterns

Posted: Tue Apr 16, 2013 9:12 am
by rimai
Add this to the end of your code:

Code: Select all

byte MyCustomWave(byte maxspeed)
{
  static byte randomspeed=0;
  if (now()%11<5)
  {
    return randomspeed;
  }
  else if (now()%11>=5 && now()%11<10)
  {
    return maxspeed;
  }
  else
  {
    randomspeed=random(35,maxspeed);
    return 0;
  }
}
And call your function like this:

Code: Select all

  ReefAngel.PWM.SetActinic(MyCustomWave(70));

Re: Wave patterns

Posted: Wed Apr 17, 2013 1:01 pm
by Smotz
rimai wrote:Add this to the end of your code:

Code: Select all

byte MyCustomWave(byte maxspeed)
{
  static byte randomspeed=0;
  if (now()%11<5)
  {
    return randomspeed;
  }
  else if (now()%11>=5 && now()%11<10)
  {
    return maxspeed;
  }
  else
  {
    randomspeed=random(35,maxspeed);
    return 0;
  }
}
And call your function like this:

Code: Select all

  ReefAngel.PWM.SetActinic(MyCustomWave(70));

Wow man, Thanks!

Can I ask you to help me understand this a bit? - Teach a man to fish sort of thing?

Can you explain what the %11 is? I assume it's the variable for the duration but I don't understand how it got defined..?

How would I alter this to Random wave, pause for 1 sec, etc ?

would this do it? (but it looks to me like it waits for 5 seconds?)


byte MyCustomWave(byte maxspeed)
{
static byte randomspeed=0;
if (now()%11<5)
{
return randomspeed;
}
else
{
randomspeed=random(35,maxspeed);

return 0;
}
}

Re: Wave patterns

Posted: Wed Apr 17, 2013 4:05 pm
by binder
The %11 is a mathematical computation. The % is actually called modulus. It takes the remainder of the division operation. When he is using the %11, he is taking the number of seconds (now()) and breaking it down into 11 segments with each segment being 1 second. The first part of his code, now()%11<5 is checking for seconds 0-4 inclusive (which is 5 seconds). The second part, now()%11>=5 && now()%11<10, is checking for seconds 5-9 inclusive (which is 5 seconds) and then the last scenario is simply 1 second.

What ends up happening is the first IF runs for 5 seconds, the next IF runs for 5 seconds and the last IF runs for 1 second then the whole process repeats over and over again every 11 seconds no matter what time of day it is.

Your code you put down:

Code: Select all

if ( now()%11 < 5 )
{
return randomspeed;
} else {
randomspeed=random(35,maxspeed);
return 0;
}
Will run the first part for 5 seconds and the second part for 6 seconds. So run for 5 seconds, pause for 6 seconds, repeat.

Re: Wave patterns

Posted: Wed Apr 17, 2013 4:58 pm
by Smotz
thanks curt. Much appreciated. I kinda get it - doing will really teach me. I am so glad i went reef angel. I am learning a lot.

Wave patterns

Posted: Wed Apr 17, 2013 5:09 pm
by lnevo
Smotz wrote:thanks curt. Much appreciated. I kinda get it - doing will really teach me. I am so glad i went reef angel. I am learning a lot.
+1 try doing any of this with an apex! Not possible!

Re: Wave patterns

Posted: Thu Apr 18, 2013 4:26 am
by Smotz
binder wrote:The %11 is a mathematical computation. The % is actually called modulus. It takes the remainder of the division operation. When he is using the %11, he is taking the number of seconds (now()) and breaking it down into 11 segments with each segment being 1 second. The first part of his code, now()%11<5 is checking for seconds 0-4 inclusive (which is 5 seconds). The second part, now()%11>=5 && now()%11<10, is checking for seconds 5-9 inclusive (which is 5 seconds) and then the last scenario is simply 1 second.

What ends up happening is the first IF runs for 5 seconds, the next IF runs for 5 seconds and the last IF runs for 1 second then the whole process repeats over and over again every 11 seconds no matter what time of day it is.

Your code you put down:

Code: Select all

if ( now()%11 < 5 )
{
return randomspeed;
} else {
randomspeed=random(35,maxspeed);
return 0;
}
Will run the first part for 5 seconds and the second part for 6 seconds. So run for 5 seconds, pause for 6 seconds, repeat.

SOOO. If I change the 11 to a 7 - the first part will run for 5 seconds and the second for 2?

Re: Wave patterns

Posted: Thu Apr 18, 2013 4:14 pm
by binder
that is correct.

Re: Wave patterns

Posted: Wed May 01, 2013 11:45 pm
by Robert1969
ok Im a little lost. have had my WP40 cable for about a week and thought I would try to get my Jabao pump set up.
If I understand it correctly all I have to do is add a code from page 1, of this topic, between the lines "Place your custom code below/above here" on my sketch.
I can add this code from page 2 and it works fine:
   byte random_speed=35;
if (now()%5==1) random_speed=random(35,70);
ReefAngel.PWM.SetDaylight( LongPulseMode(random_speed,70,5,true));
But if I add lets say the "Reefcrest" code from page 1:
    byte ReefCrestMode(byte WaveSpeed, byte WaveOffset, boolean PulseSync)
{
  static unsigned long lastwavemillis=millis();
  static int newspeed=WaveSpeed;
  if ((millis()-lastwavemillis) > 5000)
  {
    if (random(100)<50) newspeed--; else newspeed++;
    newspeed=constrain(newspeed,WaveSpeed-WaveOffset,WaveSpeed+WaveOffset);
    newspeed=constrain(newspeed,0,100);
    lastwavemillis=millis();
  }  
  if (PulseSync)
    return newspeed;
  else
    return WaveSpeed-(newspeed-WaveSpeed);
}
I get the following error from Arduino: a function-definition is not allowed here before{token
Do I need to do something to the code before adding it to my sketch?
Thanks for any help

Re: Wave patterns

Posted: Thu May 02, 2013 3:59 am
by Smotz
The definition (the latter part) is longer needed in the updated libraries