Adding PWM and Tuning with Internal Memory
-
- Posts: 287
- Joined: Wed Jan 23, 2013 12:36 pm
-
- Posts: 287
- Joined: Wed Jan 23, 2013 12:36 pm
Re: Adding PWM and Tuning with Internal Memory
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
Thanks yet AGAIN
Adding PWM and Tuning with Internal Memory
I had a bug...here's a fix. The delay would only work the first water change.
Here's the fix
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);
}
-
- Posts: 287
- Joined: Wed Jan 23, 2013 12:36 pm
Re: Adding PWM and Tuning with Internal Memory
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
Re: Adding PWM and Tuning with Internal Memory
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.
Re: Adding PWM and Tuning with Internal Memory
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.
-
- Posts: 287
- Joined: Wed Jan 23, 2013 12:36 pm