Adding PWM and Tuning with Internal Memory

Do you have a question on how to do something.
Ask in here.
Paulturner911
Posts: 287
Joined: Wed Jan 23, 2013 12:36 pm

Re: Adding PWM and Tuning with Internal Memory

Post by Paulturner911 »

Thank you soo much!
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Adding PWM and Tuning with Internal Memory

Post by lnevo »

No problem. Keep us posted!
Paulturner911
Posts: 287
Joined: Wed Jan 23, 2013 12:36 pm

Re: Adding PWM and Tuning with Internal Memory

Post by Paulturner911 »

Everything seems to work! I need to do a bit of dialing in as to what speed and duration do on the different modes. I did notice that on the min max, I entered min/max percentage that I wanted the pump to run 20/90, so when I had a value of 50 in the portal some would show 40/140. I had to go back and look why. Got it!

Thanks yet AGAIN
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Adding PWM and Tuning with Internal Memory

Post by lnevo »

I had a bug...here's a fix. The delay would only work the first water change.

Here's the fix

Code: Select all

//Feed Mode Delay on Pump
static boolean feeding=false;
static unsigned long feedingstarted = now();
if (ReefAngel.DisplayedMenu==FEEDING_MODE)
{
  if (!feeding)
  {
  feeding=true;
  feedingstarted = now();
  }
} else {
  feeding=false;
}
[/code

Here's the whole ino.
[code]
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

////// Place global variable code below here


////// Place global variable code above here


void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
// Ports toggled in Feeding Mode
ReefAngel.FeedingModePorts = Port1Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit;
// Ports toggled in Water Change Mode
ReefAngel.WaterChangePorts = Port1Bit | Port7Bit | Port8Bit;
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = Port2Bit | Port3Bit | Port7Bit | Port8Bit;
// Ports turned off when Overheat temperature exceeded
ReefAngel.OverheatShutoffPorts = Port3Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit;
// Use T1 probe as temperature and overheat functions
ReefAngel.TempProbe = T1_PROBE;
ReefAngel.OverheatProbe = T1_PROBE;
InternalMemory.OverheatTemp_write( 869 );


// Ports that are always on

////// Place additional initialization code below here


////// Place additional initialization code above here
}

void loop()
{
ReefAngel.Relay.On( Port1 );
ReefAngel.StandardFan( Port2 );
ReefAngel.ActinicLights( Port3 );
ReefAngel.WavemakerRandom1( Port5,180,900 );
ReefAngel.WavemakerRandom2( Port6,90,900 );
ReefAngel.DayLights( Port7 );
ReefAngel.DayLights( Port8 );
//Moonlight Phase 9pm-10am (CH4-CH5)
if ( (hour() >=10) && (hour() <21) )
ReefAngel.PWM.SetChannel( 4,(0) );
else
ReefAngel.PWM.SetChannel( 4, MoonPhase() );
if ( (hour() >=10) && (hour() <21) )
ReefAngel.PWM.SetChannel( 5,(0) );
else
ReefAngel.PWM.SetChannel( 5, MoonPhase() );
//Pump Delay and Over Flow Protection
if (ReefAngel.HighATO.IsActive())
ReefAngel.Relay.On(Port1);
else
ReefAngel.Relay.Off(Port1);
//ATO Protection
if (ReefAngel.LowATO.IsActive())
ReefAngel.Relay.On(Port4);
else
ReefAngel.Relay.Off(Port4);
//Kalk Dose 20sec @ 8pm-12pm (every 15min)
if (hour() >=20 || hour() < 12)
ReefAngel.Relay.Set(Port4, now()%900<22);
else
ReefAngel.Relay.Off(Port4);
//Feed Mode Delay on Pump
static boolean feeding=false;
static unsigned long feedingstarted = now();
if (ReefAngel.DisplayedMenu==FEEDING_MODE)
{
  if (!feeding)
  {
  feeding=true;
  feedingstarted = now();
  }
} else {
  feeding=false;
}


///// Place your custom code below here

// Read memory for RF Wave Settings and use for Tunze/Jaebo
int mode=InternalMemory.RFMode_read();
int speed=InternalMemory.RFSpeed_read();
int duration=InternalMemory.RFDuration_read();

// Change this to what you want your min/max based on vortech speed
// This is for those functions that take both, but only one memory slot.
int minOffset=5;
int maxOffset=10;

int min=speed-minOffset;
int max=speed+maxOffset;

// keep wavemakers off for first 15 minutes of feeding mode.
if (now()-feedingstarted<=900 && ReefAngel.DisplayedMenu==FEEDING_MODE) {
    ReefAngel.PWM.SetDaylight( 0 );
    ReefAngel.PWM.SetActinic( 0 );
} else if (mode==Constant) { 
  // Constant
    ReefAngel.PWM.SetDaylight( speed );
    ReefAngel.PWM.SetActinic( speed );
} else if (mode==Lagoon) { 
    // Lagoon
    ReefAngel.PWM.SetDaylight( SineMode(min,max,duration,true) );
    ReefAngel.PWM.SetActinic( SineMode(min,max,duration,false) );
} else if (mode==ReefCrest) { 
    // Reef Crest
    ReefAngel.PWM.SetDaylight( ReefCrestMode(speed,duration,true) );
    ReefAngel.PWM.SetActinic( ReefCrestMode(speed,duration,false) );
} else if (mode==ShortPulse) {  
    // Short Pulse
    ReefAngel.PWM.SetDaylight( ShortPulseMode(min,max,duration,true) );
    ReefAngel.PWM.SetActinic( ShortPulseMode(min,max,duration,false) );
} else if (mode==LongPulse) {
    // Long Pulse
    ReefAngel.PWM.SetDaylight( LongPulseMode(min,max,duration,true) );
    ReefAngel.PWM.SetActinic( LongPulseMode(min,max,duration,false) );
} else if (mode==TidalSwell) {
    // Tidal Swell
    ReefAngel.PWM.SetDaylight( TidalSwellMode(speed,true) );
    ReefAngel.PWM.SetDaylight( TidalSwellMode(speed,false) );
} else if (mode=NutrientTransport) {
    // Smart_NTM
    ReefAngel.PWM.SetDaylight( NutrientTransportMode(min,max,duration,true) );
    ReefAngel.PWM.SetActinic( NutrientTransportMode(min,max,duration,false) );
} else {
    // Default
    ReefAngel.PWM.SetDaylight( TideMode(speed,minOffset,maxOffset) );
    ReefAngel.PWM.SetActinic( TideMode(speed,minOffset,maxOffset) );
}
////// Place your custom code above here

// This should always be the last line
ReefAngel.Portal( "paulturner911" );
ReefAngel.ShowInterface();
}

void DrawCustomMain()
{
int x,y;
char text[10];
// Dimming Expansion
x = 15;
y = 2;
for ( int a=0;a<6;a++ )
{
if ( a>2 ) x = 75;
if ( a==3 ) y = 2;
ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :" );
ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
y += 10;
}
pingSerial();

// Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor( 15, 43, ReefAngel.Params,
ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor( 15, 43, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
pingSerial();

// Main Relay Box
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox( 12, 84, TempRelay );
pingSerial();

// Date and Time
ReefAngel.LCD.DrawDate( 6, 122 );
pingSerial();
}

void DrawCustomGraph()
{
}

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;
}
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;
}
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); 
}
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);
}
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;
}
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;
}
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);
}
Paulturner911
Posts: 287
Joined: Wed Jan 23, 2013 12:36 pm

Re: Adding PWM and Tuning with Internal Memory

Post by Paulturner911 »

lnevo wrote:The iOS apps don't work right in my experience changing memory modes. Try doing it from a direct http connection...

http://reefangelwifi:2000/mi214,900

Modify the above to suit your needs.

I was able to do this a month ago. what am I doing wrong?
If I type:
http://reefangelwifi:2000/mi214,900
in my browser, I get oops google could not find. Its the correct port on my router....
Please help
Image
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Adding PWM and Tuning with Internal Memory

Post by binder »

make sure you change "reefangelwifi" to whatever the IP address is of your reef angel controller. Google is giving you the error because it can't find "reefangelwifi" as a domain name.
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Adding PWM and Tuning with Internal Memory

Post by lnevo »

That will only work on your home network. If you are, then most likely your router dropped the dns name that gets assigned when it gets a dhcp address. Try disconnecting / reconnecting the module to make sure it refreshes the lease and try again. Otherwise check in your router, make sure it's also a static reservation. If it's already a static reservation, then sometimes the name you give it in the static reservation overrides the default name the device registers with.
Paulturner911
Posts: 287
Joined: Wed Jan 23, 2013 12:36 pm

Re: Adding PWM and Tuning with Internal Memory

Post by Paulturner911 »

Thanks....That was it!
Image
Post Reply