Weather Library Beta

Related to the development libraries, released by Curt Binder
Post Reply
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Weather Library Beta

Post by thekameleon »

I have taken the weather code done by others and converted it to a library. This will hopefully make it easier to just use without having to sift through the code to understand it. you can find it here:
https://github.com/thekameleon/RA_Weather

and its attached. Add them into the folder of your sketch and add the following include in your sketch after the rest of your includes.

Code: Select all

#include "RA_Weather.h"
Below is a brief set of documentation of its usage

Reference:

Code: Select all

 byte CloudsEveryXDays; //How often clouds can happen
 byte CloudChancePerDay; //Chances that a cloud will happen per day. Specifying 1 is every day, 2 every other day, 3 every 3rd day, etc...
 byte MinCloudDuration; //Minimium duration a cloud will happen in minutes
 byte MaxCloudDuration; //Maximum duration a cloud will happen in minutes
 byte MinCloudTransition; //Minimium transition time to and from a cloud in seconds
 byte MaxCloudTransition; //Maximum transition time to and from a cloud in seconds
 byte MinCloudsPerDay; //Minimium number of clouds in a day
 byte MaxCloudsPerDay; //Mamimum number of clouds in a day
 int StartCloudAfter; //Specifies a time of day that clouds can start occuring in minutes since midnight
 int EndCloudBefore;//Specifies a time of day that clouds will end occuring in minutes since midnight
 byte LightningChancePerCloud; //odds that lightning could happen per cloud
 byte LightningElapseMin; //minimum seconds between lightning strikes
 byte LightningElapseMax; //maximum seconds between strikes
 int LightningStrikeDuration; //lightning strike duration... set to what works best for your drivers
 byte LightningFrequency; //how frequent lightning will occur within the cloud 0% to 100%

 byte CloudChannels; //specifies which channels in bits (e.g. 11000000 would be daylight and actinic only, 00110000 would be PWM Expansion 0 and 1)
 byte LightningChannels; //specifies which channels in bits (e.g. 11000000 would be daylight and actinic only, 00110000 would be PWM Expansion 0 and 1)

 void Init(); //Sets initial values. Must be called
 void Execute(); //Executes weather logic.  Typically called on each iteration of loop function
 void InitDaylight(); //initializes min and max values for Daylight PWM from memory
 void InitDaylight(byte min, byte max); //specify min and max values for Daylight
 void InitActinic(); //initializes min and max values for Actinic PWM from memory
 void InitActinic(byte min, byte max); //specify min and max values for Actinic
 void InitPWMChannel(byte channel); //initializes min and max values for PWM Expansion channel from memory
 void InitPWMChannel(byte channel, byte min, byte max); //specify min and max values for PWM Expansion channel
 void RefreshPWMValues(); //Refreshes PWM values with values from weather... Must be called in loop() before ShowInterface call
 void ForceStart(byte duration, bool withLightning); //forces start of weather
 byte GetStatus(); //get weather status.  Either shows 0 for no clouds, 1 - 100 to cloud chance, 101 cloud start, 102 cloudy, 103 cloud ending, 104 lightning occurring
 byte GetCloudStartHour(); //Gets hour that cloud will start
 byte GetCloudStartMinute(); //Gets minute that cloud will start
 byte GetCloudDuration(); //Get duration in minutes that cloud will last
 byte GetLightningChance(); //percentage that lightning could occur
 byte GetCloudChance(); //percentage that clouds could occur
 byte GetNumClouds(); //number of clouds today.
Usage Example:

Code: Select all

setup()
{
  Weather.Init();
  Weather.CloudsEveryXDays = 1; //How often clouds can happen
  Weather.CloudChancePerDay = 20; //odds in percentage 0 to 100% chance
  Weather.CloudChannels = 255; //specifies which channels in bits (e.g. 11000000 would be daylight and actinic only, 00110000 would be PWM Expansion 0 and 1)
  Weather.LightningChannels = 255; //specifies which channels in bits (e.g. 11000000 would be daylight and actinic only, 00110000 would be PWM Expansion 0 and 1)
}

loop()
{
  Weather.InitActinic(); //initializes the min and max values based on memory values
  Weather.InitDaylight(); //initializes the min and max values based on memory values
  Weather.InitPWMChannel(0); //initializes the min and max values based on memory values
  Weather.InitPWMChannel(1); //initializes the min and max values based on memory values
  Weather.InitPWMChannel(2); //initializes the min and max values based on memory values
  Weather.InitPWMChannel(3); //initializes the min and max values based on memory values
  Weather.InitPWMChannel(4); //initializes the min and max values based on memory values
  Weather.InitPWMChannel(5); //initializes the min and max values based on memory values

  Weather.Execute(); //executes the weather

  Weather.RefreshPWMValues(); //sets the PWM values for your lights.
}
Please let me know how this worked for you. It is still in beta so there maybe bugs here or there.
Attachments
RA_Weather.h
(1.88 KiB) Downloaded 477 times
RA_Weather.cpp
(12.04 KiB) Downloaded 501 times
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Weather Library Beta

Post by rimai »

Awesome!!!
Roberto.
User avatar
Rodasphoto
Posts: 187
Joined: Wed Apr 10, 2013 2:48 pm
Location: Athens, Ga
Contact:

Re: Weather Library Beta

Post by Rodasphoto »

This is awesome. Is anybody currently running this and have there been any bugs?
Image
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Weather Library Beta

Post by DrewPalmer04 »

Very nice of you! Thanks!!!
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

It seems the clouds are working as expected, I am not sure if the lightning is working yet. I have been super busy the last few months. My next step is to add this to an all-up climate library that includes sun rise/sun set and moon phases. All based on others great work. Just making it into one package. From there I will include "templates" which you simply could apply a template that sets up all the parameters. This makes it so, if you are not a developer at heart, there isn't much code for you to write.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Weather Library Beta

Post by lnevo »

When you say moon phases, do you also mean the moon rise/set code that I posted?
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

Yep the same
User avatar
Rodasphoto
Posts: 187
Joined: Wed Apr 10, 2013 2:48 pm
Location: Athens, Ga
Contact:

Re: Weather Library Beta

Post by Rodasphoto »

thekameleon wrote:It seems the clouds are working as expected, I am not sure if the lightning is working yet. I have been super busy the last few months. My next step is to add this to an all-up climate library that includes sun rise/sun set and moon phases. All based on others great work. Just making it into one package. From there I will include "templates" which you simply could apply a template that sets up all the parameters. This makes it so, if you are not a developer at heart, there isn't much code for you to write.
I can't wait. Many thanks in advance for doing this
Image
avionixx
Posts: 20
Joined: Thu Apr 25, 2013 10:12 pm

Re: Weather Library Beta

Post by avionixx »

Can anyone help me get this code running? I have everything set up like the usage guide says but I've yet to see any cloud or lightning effects. Here's my code:

Code: Select all

#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>
#include "RA_Weather.h"

////// Place global variable code below here
boolean ForceStart=false;

#include <avr/pgmspace.h>
prog_char menu0_label[] PROGMEM = "Feeding";
prog_char menu1_label[] PROGMEM = "Water Change";
prog_char menu2_label[] PROGMEM = "ATO Clear";
prog_char menu3_label[] PROGMEM = "Overheat Clear";
prog_char menu4_label[] PROGMEM = "PH Calibration";
prog_char menu5_label[] PROGMEM = "Date / Time";
prog_char menu6_label[] PROGMEM = "Force Start Weather";
PROGMEM const char *menu_items[] = {
menu0_label, menu1_label, menu2_label,
menu3_label, menu4_label, menu5_label,
menu6_label//, menu7_label, menu8_label
};

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ReefAngel.ATOClear();
ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}
void MenuEntry4()
{
ReefAngel.OverheatClear();
ReefAngel.DisplayMenuEntry("Clear Overheat");
}
void MenuEntry5()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()
{
ReefAngel.SetupDateTime();

ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
ForceStart=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
////// Place global variable code above here


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


    // Ports that are always on
    ReefAngel.Relay.On( Port2 );
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port6 );

    ////// Place additional initialization code below here
    Weather.Init();
    Weather.CloudsEveryXDays = 1; //How often clouds can happen
    Weather.CloudChancePerDay = 100; //odds in percentage 0 to 100% chance
    Weather.CloudChannels = 00111110; //specifies which channels in bits (e.g. 11000000 would be daylight and actinic only, 00110000 would be PWM Expansion 0 and 1)
    Weather.LightningChancePerCloud = 25; //odds that lightning could happen per cloud
    Weather.LightningElapseMin = 3; //minimum seconds between lightning strikes
    Weather.LightningElapseMax = 15; //maximum seconds between strikes
    Weather.LightningStrikeDuration = 800; //lightning strike duration... set to what works best for your drivers
    Weather.LightningFrequency = 10;
    Weather.LightningChannels = 00001010; //specifies which channels in bits (e.g. 11000000 would be daylight and actinic only, 00110000 would be PWM Expansion 0 and 1)
    Weather.MinCloudDuration = 10; //Minimium duration a cloud will happen in minutes
    Weather.MaxCloudDuration = 40; //Maximum duration a cloud will happen in minutes
    Weather.MinCloudTransition = 3; //Minimium transition time to and from a cloud in seconds
    Weather.MaxCloudTransition = 10; //Maximum transition time to and from a cloud in seconds
    Weather.MinCloudsPerDay = 60; //Minimium number of clouds in a day
    Weather.MaxCloudsPerDay = 90; //Mamimum number of clouds in a day
    Weather.StartCloudAfter = NumMins(00, 00);
    Weather.EndCloudBefore = NumMins(17, 00);
    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.StandardHeater( Port1,770,795 );
    ReefAngel.StandardLights( Port4,4,40,20,0 );
    ReefAngel.StandardATO( Port7,60 );
    ReefAngel.StandardLights( Port8,7,0,17,0 );
    ////// Place your custom code below here
    ReefAngel.PWM.SetChannel( 0, PWMSlope(5,0,19,0,1,60,60,1) );
    ReefAngel.PWM.SetChannel( 1, PWMSlope(5,0,19,0,1,60,60,1) );
    ReefAngel.PWM.SetChannel( 2, PWMSlope(5,0,18,0,1,45,100,1) );
    ReefAngel.PWM.SetChannel( 3, PWMSlope(5,0,18,0,1,35,80,1) );
    ReefAngel.PWM.SetChannel( 4, PWMSlope(5,0,18,0,1,55,110,1) );
    ReefAngel.PWM.SetChannel( 5, PWMSlope(19,0,5,0,1,90,20,1) );
    ReefAngel.PWM.SetDaylight( ReefCrestMode(50,20,true) ); // ReefCrest at 60% +/- 20% on sync mode
    ReefAngel.PWM.SetActinic( ReefCrestMode(40,20,false) ); // ReefCrest at 60% +/- 20% on anti-sync mode
    
    Weather.InitPWMChannel(0); //initializes the min and max values based on memory values
    Weather.InitPWMChannel(1); //initializes the min and max values based on memory values
    Weather.InitPWMChannel(2); //initializes the min and max values based on memory values
    Weather.InitPWMChannel(3); //initializes the min and max values based on memory values
    Weather.InitPWMChannel(4); //initializes the min and max values based on memory values
    Weather.InitPWMChannel(5); //initializes the min and max values based on memory values

    Weather.Execute(); //executes the weather
  
    Weather.RefreshPWMValues(); //sets the PWM values for your lights.
    ////// Place your custom code above here

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

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 11, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 11, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Water Level
    ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,75,48, "WL:" );
    ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,99,48, ReefAngel.WaterLevel.GetLevel() );
    pingSerial();

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

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

void DrawCustomGraph()
{
}
I also added a Force Start menu item but that isn't doing anything either.
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

I think it is where you specify the CloudChannels and LightningChannels. These values are bytes that can range from 0 to 255. This allows for any one or combination of possible PWM channels to be used as cloud values. You don't specify "11101110" directly, you need to specifying the corresponding byte value 0 - 255. Just try using 255 so all your PWM channels are effected. It should work. With that do you think it would be better to just a function that allows you to specify a channel and whether to set it as a cloud/lightning channel?
avionixx
Posts: 20
Joined: Thu Apr 25, 2013 10:12 pm

Re: Weather Library Beta

Post by avionixx »

Thanks for the reply and the clarification! I was confused on what to put there, however, even after I've changed it to the proper value (initially 62 for the clouds, and then I tried 255) I'm still not seeing the effect.

Personally, I think the current implementation for specifying which channels should be used for clouds and lightning is pretty standard, I tried rufessor's weather sim previously so there wasn't much of a learning curve.

EDIT: After setting both channels to 255, did notice all of the lights dim suddenly and then after a few minutes, the intensity ramped up (kinda choppily) to full brightness. Was that the cloud effect or something else?
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

Sounds like it... not sure on the choppily part. I will have to look at the transitions. I am using a reverse PWM slope and varying the time the transition between cloud and sun occur. The code is based off of rufessor's code, but I tried simplifying some of it, while adding the ability to have greater control of certain aspects such as transitions.

You said setting both channels to 255. do you mean the LightningChannel and CloudChannel properties?
avionixx
Posts: 20
Joined: Thu Apr 25, 2013 10:12 pm

Re: Weather Library Beta

Post by avionixx »

Yes, I set both the LightningChannel and CloudChannel to 255. I tried setting them to their appropriate values to my setup: PWM 0-4 for the clouds (byte value 62) and 2+4 for lightning (byte value 10) but never saw any effects with it.
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

Correct me if I am wrong but should the values be 31 and 20... For the clouds 1 + 2 + 4 + 8 + 16 for 0- 4 and 0 + 0 + 4 + 0 + 16 for lightning 2 and 4?... In my next release, I will make the Init<channel> functions automatically define the channels so we don't have to play with the binary values.

EDIT: OK just relooked at the code the actually does the cloud and it is similar to this:

Code: Select all

if (CloudChannels & 1 == 1 && WeatherPWM.DaylightPWMValue >= MinPWM.DaylightPWMValue) WeatherPWM.DaylightPWMValue = 
			ReversePWMSlope(cloudStart, cloudStart + cloudDuration, WeatherPWM.DaylightPWMValue, MinPWM.DaylightPWMValue, cloudTransition);
So Daylight and Actinic are the first and seconf bits then come the PWM Expansion modules. So PWM Channel 0 is actually the 3rd bit or byte 4.

Now someone please check this:

Code: Select all

CloudChannels & 8 == 8
Will that statement return true if the fourth bit is 1? I think it does, but please correct me if I am wrong.
avionixx
Posts: 20
Joined: Thu Apr 25, 2013 10:12 pm

Re: Weather Library Beta

Post by avionixx »

How do you test that? lol
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

In C# it works fine. I am still learning C++ though. It's not so much about testing it, as making sure I am trying to do the thing for the platform.
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

I would like some ideas on something... One of the challenges with the Weather Library is trying to figure out when clouds should happen and when they shouldn't.. For instance, if it is suppose to be 40% cloudy how do you distribute the clouds through out the day. It shouldn't be predictable, because nature is not (like 30 minutes for each hour), however it should be evenly distributed so all the cloud cover does not happen at once.

One idea, I had was to create a "pool" of minutes so if 20% of clouds are to happen that day there would be a pool of 288 minutes (24 hours x 60 minutes x 20%). Then when a cloud ended, I would subtract the amount of time the cloud occurred from the pool. Based on the duration of the cloud that just ended and the probability of clouds in this case 20%. I would slowly increase a number over time (subtracting 20% from 100% and then multiplying that by the last cloud duration, so if the duration was 10 minutes, it would be 4 times 10 or 40 minutes) Over this 40 minutes I would start from zero and slowly work back to 20. All along retesting to see if clouds should occur. I think this would allow for evenness and yet look natural

Thoughts? Or other ideas.
Amos Poh
Posts: 107
Joined: Sun Jul 22, 2012 4:51 am
Location: Singapore

Re: Weather Library Beta

Post by Amos Poh »

thekameleon wrote:Correct me if I am wrong but should the values be 31 and 20... For the clouds 1 + 2 + 4 + 8 + 16 for 0- 4 and 0 + 0 + 4 + 0 + 16 for lightning 2 and 4?... In my next release, I will make the Init<channel> functions automatically define the channels so we don't have to play with the binary values.

EDIT: OK just relooked at the code the actually does the cloud and it is similar to this:

Code: Select all

if (CloudChannels & 1 == 1 && WeatherPWM.DaylightPWMValue >= MinPWM.DaylightPWMValue) WeatherPWM.DaylightPWMValue = 
			ReversePWMSlope(cloudStart, cloudStart + cloudDuration, WeatherPWM.DaylightPWMValue, MinPWM.DaylightPWMValue, cloudTransition);
So Daylight and Actinic are the first and seconf bits then come the PWM Expansion modules. So PWM Channel 0 is actually the 3rd bit or byte 4.

Now someone please check this:

Code: Select all

CloudChannels & 8 == 8
Will that statement return true if the fourth bit is 1? I think it does, but please correct me if I am wrong.

Thank You so much for this! Question, do I have to manually add this to the library or will it be automatically updated when I startup my arduino ?
thekameleon
Posts: 137
Joined: Sat Feb 16, 2013 7:44 am

Re: Weather Library Beta

Post by thekameleon »

You have to add it manually, but it should be no more than copy and paste
Post Reply