Statistical Climate Modeling and RandomSeed

I have been building and coding arduino for a few years now using mostly copy&paste but, I have what I think is a pretty good grasp of all the basics. This is my first post. Please forgive any etiquette offenses I may commit while I am still reading "Read Before Posting" threads and respectfully learning how to use this community resource.

In the near future I hope to start a project thread in the appropriate area to define the project I am working on which I sure will require assistance in multiple smaller threads related to specific libraries, functions, etc. This would be an awesome change from the `357 tabs I have open in my browser trying to understand advanced functions of one library while taking in the basics of another.

This thread was chosen because I would like to discuss options or paths that might best (or simplest) accomplish the goal. Two toddlers prevent me from spending lots of time running and experimenting with code directly so I am presenting an idea. The code tag is used for respect to etiquette but, as you will see my syntax and structure is extremely rough! Comments are used to explain what I think I am doing and block comments are used to explain expected results.

Thanks for reading and I look forward to any feedback!

*/
====================================
Environmental Controller v3
  (Reptile, Fish, Amphibian, Aquarium, Terrarium, Greenhouse, etc.)

Beyond other light/heat/timer based projects I have found, I want to create
more of a complete climate simulator.  Consider it a weather station and data
logger in reverse.  I insert some average climate data and allow the code to
do hourly, daily and monthly calculated (psuedo-random) adjustments or moving
target parameter changes. 
 
What fabricated pieces I have, libraries, modules, relays connections or outputs
I attach is secondary IMO to discussing "how & why" I am headed down this 
code pathway.

====================================================
/*

//#includes - known: FastLED, Wire & undecided: RTC, TimeLord, DHT22, Stepper

//#define and constants - necessary as needed for things that need to be global unchanged
#define JANrainDays 8   //average monthly days with rainfall 
#define JANtempHI 78  //average monthly temperature high
#define JANtempLO  57  //average monthly overnight low temp
#define JANhumidityHI 80   //average monthly humidity high 
#define JANhumidityLO 50  //average monthly humidity low

#define FEBrainDays 8
#define FEBtempHI 78
#define FEBtempLO  57
#define FEBhumidityHI 80
#define FEBhumidityLO 50
// ....continues through the year based on google data

*/
Why?  Quick access to changes at the top of the code.  These could be const any
type like byte as they only hold numbers to use compare later.  I am sure there are
better ways to get this data like serialRead or Upload to SD but it works for what I am
presenting below.
/*

//Variables - Things that will change established here to be globally updated
byte RainDaysRemaining   //updated by when month changes and will count down (hopefully to 0 by the end of the month if my ChanceOfRain numbers are right
byte CurrentMonth  //quick way to avoid running update code sections un-necessarily, same as CurrentDay
byte CurrentDay
byte ChanceOfRain  //experimental number to set probability of a random TRUE/FALSE outcome.  I make this lower in the beginning of the month and higher at the end to try and reach RainDaysRemaining == 0 by the end of each month without clumping up missed rain days
bool StormBrewing  //TRUE when a given day is chosen for rain.  This will trigger other code such as lighting changes to make it overcast, overriding humidity controls while rain is falling, the relays turning on the water pumps etc.
byte TodaysForecast  //simplified for this example but becomes the setpoint to use for temperature control later.  Each 24hour will have slowly moving temperatures setpoints that also fluctuate day by day within a season.

Void Setup() {
// start serial monitor for testing and adjusting defined values
// start i2c as master    - because of some blocking motor and led code I may off load some functions to other arduinos and/or i2c devices
// numerous initiation setups go here for LEDs and others things and I (THINK) this is the best place to establish my own loop functions
}

*/ 
establishing functions...
I see a lot of example code where the compiler gets to a custom function AFTER it 
sees it called in void Loop.  Where is the proper place to layout a function that will 
be called in the loop that repeats each day over and over?
/*

DailyForecast(); 
  if (Day) != CurrentDay; {       //check and see if CurrentDay is the same as RTC (Day) 
    CurrentDay = (Day)          //set current day to (Day) data from RTC
      switch (Month)                  //begin switch case based on the value of CurrentMonth
         case 0 JAN
            // TodaysForecast = (RandomSeed((JANtempHI -4) + (JANtempHI +3))
         break;

        case 1 FEB
           // TodaysForecast = (RandomSeed((JANtempHI -4) + (JANtempHI +3))
 
         break;

// 12 cases where the forecast will be set based on the month, the break should break the current if statement and continue with the next without leaving the DailyForecast function

 if RainDaysRemaing >= 0;{
   
    if (RandomSeed 0, 101) >50; {
          StormBrewing = TRUE;
          RainDaysRemaing - 1;
          }
    else StormBrewing = FALSE; {
         }

//  As a function called later this should make more sense with those comments

void LOOP();
{

   if (Month) != CurrentMonth; && (Day) == 1;
       CurrentMonth = (Month);
          switch (CurrentMonth);
              case 0 = JAN
                  RainDaysRemaing = (JANrainDays);
              break;

              case 1 = FEB
                  RainDaysRemaing = (FEBrainDays);
              break;

//  12 cases that I hope will update RainDaysRemaining ONLY the first time that CurrentMonth is found to not be the same as RTC month.  I do the same thing later with Day which sets up each day at 1microsecond after midnight when != happens.  

}

That code while it looks like my toddlers wrote it, was written by me over the course of an hour just now in 15 second intervals between chasing toddlers. A compiler would catch on fire if I checked it but my goals of typing it out were to ask these questions:

Each month has an average number of rainy days. I want to randomly distribute these over the full month. These are average days so if my assumptions are off slightly and I have 13 instead of 15 rains in a month it wont be the end of the world and is reason we average this data. Is my way of using RandomSeed fundamentally sound?

  • look at the number of outcomes needed
  • do a end number excluded randomseed to produce 0-100 and compare to a threshold which may be weighted if 50/50 gives me unwanted outcomes
  • when the random generated number is over the threshold, record the TRUE in a bool and reduce the value of remaining outcomes by 1
  • test this with serial monitor with lots of SerialPrint. I imagine months with higher starting values for RainDaysRemaining may need to be considered at some point but this is a base

Read more about random numbers and the syntax and meaning of conditional statements, compound statements, random() and randomSeed().

Use the average distance between rainy days of each month for generating random numbers. In a more complicated model you also randomize the number of rainy days in sequence.

Look at structs and arrays of them. Hard coding your month data in sixty #define statements will likely prove rather repetitive and painful.

@DrDiettrich

Thank you for your reply. Yes, I certainly will continue to read up on various topics and I appreciate you calling out specifics for me. I have a notebook of scribbles, code snippets and example sketch information (along with other project related considerations) and I was attempting to narrow down and concentrate on one piece. I felt my basic understanding of the things you listed was fairly sound but, if my presented idea is that far off then I should go back and re-evaluate.

DrDiettrich:
Use the average distance between rainy days of each month for generating random numbers.

If I am understanding your solution here I should divide days in a month by average rainfall days. So if a month with 30 days has 10 days of rainfall, that tells me that on average it should rain every 3 days. I do not understand exactly how a generated 0-3 would benefit me, though maybe after rereading Random() and RandomSeed() I may. My approach was intended to give a probability for rain on a given day and keep track of how many days I actually made rain happen. This approach would also be used for other "random within a range" areas such as temperature fluctuations, the amount of pink in a sunrise and as my code gets more advanced for experimental purposes like changing barometric pressure within a terrarium prior to weather effects.

@wildbill

I agree that getting the data into the sketch is extremely clunky and I typed out JAN & FEB just to show how I would be doing comparisons. Outside of importing or serial reading this data, I have also considered looking at the month to month charts and doing a for loop which increments values in an array based on the difference. ie. It is 5 degrees warmer on average in FEB than it is in JAN.

This sounds like a project that would be much easier to implement on a PC (or Raspberry Pi) using Python - which is widely used for scientific projects and has a large number of libraries.

Is there a particular reason for using an Arduino?

...R

@Robin2

Thank you as well for the suggestion. I actually came to controllers such as the arduino after I started running into limitations of my projects. My first forays into control where diode and relay logic after which I drifted into several home automation control systems like x-10, Zwave. Cost and function limitations working with those protocols brought me to arduino and the idea that I could start from scratch and make something do exactly what I wanted.

It has been a challenging learning curve and although I have been able to piece together code from example sketches and make things move, turn on, etc. I have not created the underlying code that I have been wanting to that is sound and expandable because of it's structure.

Raspberry Pi was a consideration but I basically looked at two well documented communities with support for each and flipped a coin on learning Python or going with Arduino and C which I had some familiarity with. I still think the things I am trying to accomplish with this project are within the scope of Arduino and its' loop programing. In fact one challenge thus far has been NOT getting too far into interupts or alarm signals from my RTC etc, that would take me away from simple logical coding that I want to lay down first.

  • prioritize when things are checked and updated
  • weigh sensor data against other sensor data and/or program data
  • perform a function or take action considering the above
  • live with the results (in testing of course, given the ultimate goal is housing living creatures) because that is how I designed it to work
  • redesign and modify as necessary

If you have a button or other input that's unpredictable on a millisecond scale then every time it detects a change in state, use the low 8 bits of (micros() >> 2) for a random seed.

You could feed talk radio babble into a circuit that 1) never goes -V, 2) never goes > VCC, 3) averages about 1/3rd VCC so that loud forces HIGH and quiet forces LOW. The talk radio sounds may be monotonous but they should not be so at the sub-millis level. The noise on an empty channel will have less range than the random lunacy put out by the likes of Rush Limpbag.

One rainy day out of 3 means a distance of about 3 between rainy days. random(1,6) delivers random numbers of that average and indicates with every call how many days away is the next rainy day.

rainyDay = rainyDay + random(1,6);

More general the distance is (untested!)

rainyDay += random(1, daysPerMonth*2) / rainyPerMonth;

I do follow the idea of using an analog pin input that is floating and I like the very creative idea of using a radio signal that doesn't rely on happenstance putting unpredictability in my psuedo-random output.

All replies have been helpful and I appreciate the time everyone has taken however I would like to concentrate on the method of setting a value and decreasing it x times in y loop iterations with some random appearing dispersion. They would be total times through a loop theoretically because that section of code only runs once per day.

Earlier, there was a suggestion to use days between which I now see could be as simple as divide days in a month by rain days and make it rain that often regardless of day/night. Cleaver, and may be enough for the animals to not detect a pattern!

I will try to run some samples tonight through the serial monitor and will post some results.

I once had a housemate who believed that by studying past lottery drawings for number frequencies he could "tell when a 3 will come up". When he couldn't pay his share of the rent for 2 months, I kicked him out when he showed up with a used car he bought when he finally "won" enough to not just buy another small pile of tickets and repeat until no tickets hit.

added: but I see that you're creating a pseudo-random pattern, not predicting reality.

If every day you have X-many + random points and when the total is > threshold, rain and set points = 0.
The threshold is bigger for less days a month and maybe a 3 day month rains 2 or 4 days?

GoForSmoke:
studying past lottery drawings for number frequencies

I am very familiar with the "gambler's fallacy" and other statistical areas and theory of probability. That is why I thought that I may have to ultimately "load the dice" near the end of the month because I there is nothing that prevents a true random probability from making it never rain the way I wrote it.

The complexity of the calculation does not scare me away and I have no problem going with a better system that meets the goal. I just want to understand these functions better and then make that decision. No shortage of other things to learn about on this project, lol!

For example, my daily high and low temperature set points do not follow a simple scale. Looked at a graph of daily temperature and humidity levels there will be some complex math I'll need to understand before I can then try to understand how to code it.

That's why X-many plus random, X-many is the forcing.

The real temperature and humidity and change driver is the polar cyclone, good luck with simulating weather fronts.

How about simply using data from past years since you're creating an environment anyway? Put it on SD and use an SD module (make sure it does not have shortcut voltage leveling, you can DIY better than that) to read.

Years ago I did something similar with home automation devices and a dedicated server. After hundreds of hours of work and amounts of money I will never divulge, I could do with hours of scene settings and tinkering exactly what someone with fingers could do with a rheostat and an analog wall timer. I also had a much more complex system with silly amounts of failure potential in multiple areas.

At that point it was hard to continue development vs. an off the shelf solution. Today some LED aquarium light kits have some type of sunrise/sunset functionality built in and I can buy incubator equipment from farming supply stores to do humidity and temperature control with 2 stage equipment!

The desire to keep trying to improve on those systems is however unchanged. In reptiles, removing even the slightest bit of environmental stress from an animal could be life or death for them. When it comes to encouraging captive breeding in some species, there are many yet-unknown environmental conditions that trigger mating behaviour. Experimentation is how these things are learned and shared and I like being part of that effort.

Australian Water Dragons for example need to be put in a refrigerator for a month to hibernate in the cold before they show any interest in mating. Using something like fan and vent control to alter air pressure (like done in electrical panels in dusty locations) could be the one missing trigger that nobody has discovered yet. With the variety of example sketches available I can set sunrise and sunset times for a given lat/long, turn on and off relays for heat/humidity and even log or chart this on cheap touchscreens. I want to try and do all of those things and more but I don't want to copy/paste code that I don't understand at a line by line fundamental level.

**Edit, I believe I recognize the name in your signature "GoForSmoke. If so, I am grateful for the various sketches you have shared. I am using or have plans to use a lot of your code!

Each month has an average number of rainy days. I want to randomly distribute these over the full month.

Not a good model for the weather.

The prediction "the weather tomorrow will be the same as the weather today" is accurate 60 to 70% of the time.

Predicting or forecasting weather is not part of this project's scope. I am using recorded and easily available data to simulate or approximate conditions for a given location. Specifically, East Timor where varanus timorensis is native to. Though if functional, it could be shared with someone who is housing animals from a completely different area of the world.

While it is technically correct to say randomly selecting 5 days where rain falls in the month of May is not accurate. I can pull climate and weather data for 2018, 2019 and 2020 and find that there were 5, 3 and 7 days respectively. Looking at average annual charts also shows me obvious transition months between dry and wet seasons where I may choose to stack rainfall to one end of the month or the other. More important is the change from 4-5 days per month to months with say 20 days of rainfall. The way I process "should I simulate rain today?" should be the same code.

Reading over suggestions from this thread I think time between rain is a functional solution and if there is more need for custom distribution then I can split months in half and stack RaindaysRemaining into AUGpart2 from AUGpart1. Humidity levels and soil moisture will also be controlled by rolling set points throughout each day, month and year. The rain heads and pump will be on different relays than the mist system, the fog system and the irrigation drippers so having a state change in my code is important.

The guidance requested was on performing a check at the very start of a new month in order to reset a count of days it should rain and then allowing for the appearance of randomness while deincrementing a count each time the bool is TRUE. That type of structure is how I plan to do many of these controls so that different functions can run as needed without checking everything every time through the loop.

jeremymcdiarmid:
**Edit, I believe I recognize the name in your signature "GoForSmoke. If so, I am grateful for the various sketches you have shared. I am using or have plans to use a lot of your code!

How many do you have? Are they Add-a-sketch series and if so do you have the loop counter (sketch health meter) sketch?

Heck, you may have an example of the parse&lex word match sketch which takes a bit of experience to grok. However it can make text & data files a lot easier to process.

As far as rain on any day, you might want to get inches/centimeters in each month and if possible temperature and rain for every day if possible. In nature there's often a breeze or wind with some water smell before it rains and millibars density change all through the event.

Whatever environment the reptiles evolved to fit, it was cooler than since the industrial revolution and especially since 1970. I don't need to look that up, I saw and recognized weather change since 1972 and I well remember how it was before just in my time. My parents talked about winters up home (north edge of the US) in the 20's and 30's being colder than in the 60's with the post-WWII years being worse for all the dust and smoke kicked up.

Your reptiles survived all that change including rising CO2 levels and for all I know they like it more now.

If you use a fan to increase or decrease air density in a box, a good plenum will stabilize the buffeting of the fan.

jeremymcdiarmid:
Looking at average annual charts also shows me obvious transition months between dry and wet seasons where I may choose to stack rainfall to one end of the month or the other. More important is the change from 4-5 days per month to months with say 20 days of rainfall. The way I process "should I simulate rain today?" should be the same code.

What seems to be completely missing from this thread is the purpose of this use of random.

Why do you consider it necessary to allocate rain days randomly?
What would go wrong if you just allocated the rain days evenly throughout the month?

Please describe the project you are trying to create.

...R

@GoForSmoke

I have done and still do a LOT of research and google searching to find answers to my questions or to see example code. I jot down notes, leave tabs open or copy paste code pieces or structure into various folders on my PC. I will sometimes delete commented lines that I know I won't need (fastled examples are a good example) but I never delete comments or author credits. I am not sure what aspect of this project I saw your work but I believe it had to do with solar tracking. Another element of this project is a motorized "sun" going across the top of the tank in an arc. The "sun" would be the primary UVB source bulb. Original idea was to do that with a tilting arc ystem to have the sun higher above in the summer but I was forced to abandon that due to PAR limitations of the bulbs. ie unless I built a tilting 3axis system I cant have the sun track differently according to earth's tilt. I will just be doing a curved from "east to west" movement which should look great for shadows and plant health. Precise sunup and sundown times are going to be critical for controlling that movement with microsteps all day but that math is yet another piece of making this come together.

Did you share some sunrise or tardis calculations with rtc323x?

@Robin2

The purpose of using random was to create seeming natural conditions. Early in the thread an alternative was presented that simply used calculated days between rain which is very appealing. Rain would still "feel" periodic as no humans other than I knows it has a predictable pattern and I doubt the reptile are keeping track. Included with the thought to use random to 'pick' the days it would rain, I added a way to month by month reset a countdown of events I think still has merit here and other functions of this code. Random appearing will be a goal wherever possible and I do want to attempt to include it wherever I can. I gave the example earlier about how much pink or orange is in my sunsets and sunrises. Random, RandomSeed or using unpredictable analog inputs along with comparisons (weighted or not) will help me achieve that and I will learn better code as a result.

For your final question, I am sorry if this is at all offensive or rude as I know everyone is trying to help but my replies have been quite wordy and I think describing the project would take way too much description and would not be forum etiquette. I will find the right forum, condense my phrasing and post the working portions of the code soon. Tomorrow I will finish doing some serial monitor testing of removing the random comparison and replace it with time between math and can mark this thread solved.

Final thoughts: A few cool benefits to dividing to get time between rain is that I won't have to further plan for when on that day the rain will fall like I would with bool as an output. If the math says it rains every 37 hours and 12 minutes this month then I get what appears ike sporadic events to an observer, i can change the bool to a time in the future and get to experience some night time storms where the lightning flashes will really show!

Using total amount of rainfall was considered but I could not resolve how to begin converting a half inch of rain (typical data unit) to amount in an enclosed area. Duration problems already exist for keeping the rain going for longer than I have to because it has to be purified water or it leaves a mess on the glass, it has to all be drained and collected and I can't flood out the plants or isopods and other critters living in the substrate. There will be drip irrigation down in the substrate already which is fed into the substrate and monitored by TE215 moisture sensors. The majority of the rain needs to be angled, aimed or otherwise diverted with care onto furnishings like rocks and wide branches to run off as close to the drains as possible.

jeremymcdiarmid:
The purpose of using random was to create seeming natural conditions.

[.....]

For your final question, I am sorry if this is at all offensive or rude as I know everyone is trying to help but my replies have been quite wordy and I think describing the project would take way too much description and would not be forum etiquette.

Why is it necessary to simulate natural conditions?

And surely you can describe the project in one or two lines of text?

...R

Purified water won't have the minerals the reptiles may need.

UVB? Even in the tropics not much solar UVB gets through.

Did you share some sunrise or tardis calculations with rtc323x?

That was years ago but I did show some to somebody. I would prefer to use light sensors to detect sunrise and use shadow and light to get the collector pointed at the sun.

And then there's the whole thing about how much off the panel can be and lose less than 5% of power. In 182.5 days the sun appears to raise or lower 46 degrees. One tracking axis (elevation) can be moved about once a week and still be efficient. If you use parabolic trough collection, that's the only axis you have.

What latitude are your reptiles from? Sun angle might be part of their seasonal cues or not. You would need a different terrarium to angle "sunlight" anyway. Why not cluster RGB leds with UVA leds for a "sun"? Your sun can change colors then.

Would missing environmental stress include not seeing predators nor signs of any? Maybe make a simulated hawk and see if they duck under cover?