Arduino and limitations for greenhouse control

Hey guys, I am still trying to figure everything out, and I'm sure some of you have seen my previous posts...

What I need to do right now is:

control temperature via water pump on/off
control timing of lights/watering system
control co2 levels via 12vdc solenoid on a co2 tank

This is a setup I'm trying to do for a family member and also to see just how "scientific" I can make the grow environment, which is my own pet-project in this.

I'm using EventFuse library with msTimer to control the timing portion. I cannot have delays holding my code up while other things are trying to happen, which is the biggest
issue I am running in to with the thermostat setup.

I'm starting to think that I may need to use 2 or more Arduino's to do this right... 1 for timing, 1 for temp control/co2 control.

I could really use some help here, as I'm trying to learn the programming and the electronics at the same time and I'm starting to lose my mind with the more complicated items, like the thermostat setup.

If I need to use more than 1 Arduino (I have an Uno) for this, is there a more powerful MCU that would be able to do everything in one package? I'm really new to all this :frowning:

Thanks

You should be able to do it all with one Arduino. Here's a temp. tutorial: Temperature sensor tutorial - Using the TMP36 / LM35

Mmmm... Looking at the code at the end of that page, won't the delay(1000); screw with my other control code? Or am I missing the fundamentals on how to combine different types of code?

A more powerful device won't solve your problems. Try to think how you would do it as a real person and translate that into computer-speak.

For example, you wouldn't personally take a thermometer reading, and stand around doing nothing for 10 minutes would you? Even if you didn't need to read the thermometer again for 10 minutes. You would go and do something else and "keep an eye on the clock".

So write your code like that. In the main loop, get the current time (eg. with millis() ) and see if time is up to take another measurement, close a switch, open a switch or whatever.

Their example code with delay(1000) is just to demonstrate the sensor, and not blit your output window with thousands of readings. Generally speaking you don't use delay in programs that need to do lots of different things. Monitor elapsed time intervals instead.

So instead of delay() I measure the time with millis()... Mmm... Can I use an RTC instead? e.g. "check temp every minute" based off the RTC time? I had been fooling around with TimedAction/TimeAlarm library and then I discovered that because you use Alarm.delay() it stops you from being able to do multiple functions at the same time. For instance, I could make an LED stay on and have another LED flash at a set interval, but if 2 events had to happen simultaneously then I ran into the issue of the first event having to be executed then the next event would happen. Then I found EventFuse and that works wonderfully for my timed events and allows everything to keep plugging away independently.

How do I go about putting all of this into one sketch then? Is there a "proper" way or a less confusing way of packing this all in to one sketch?

I think the problem that I am really running into here is that I'm having to design all of the aspects of this greenhouse setup, from the horticulture side to the electronics control side and I'm just getting stupidly over-whelmed with all the aspects of this project.

The other thing that is really boggling my mind is what I just said, understanding how to put all of this different code into one sketch and it be organized and functional, rather than everything just copy/pasted and looking mighty confusing. Basically, just like we use library's to help simplify the code we write, is there some way of making several different sketches, a sketch for temp control, a sketch for timing control, etc, and then plop them all together?

I know I have a lot of questions and I appreciate the help and once I get my understanding sorted out better then I promise not to be such a pain :slight_smile:

thanks for the clarity

-steve

FlyingSteve:
For instance, I could make an LED stay on and have another LED flash at a set interval, but if 2 events had to happen simultaneously then I ran into the issue of the first event having to be executed then the next event would happen.

You are overthinking it. Just imagine you are at home. You have a single clock on the wall. You have to feed the cat 3 times a day, the dog twice a day, and take out the trash once.

Now you don't say "but I can't feed the cat because I need to feed the dog first" or anything like that. You glance at the clock, work out if it is time to do something, and do it.

Well you do exactly the same thing in your code. In your main loop you get the "current time" with millis(). You could use a RTC but that is only shifting the problem from a number of milliseconds to a time of day. Still the same concept.

Then in the main loop, you see if "time is up". For example, you might have to "feed the cat" in 1000 ms, but "feed the dog" in 2000 ms.

Say at home, you feed the cat every 8 hours. You note the time - it's 9 am. So the cat will get fed in 9 + 8 hours (ie. 17:00). Then we work out the dog. That gets fed every 12 hours. So you say the dog gets fed in 9 + 12 hours (ie. 21:00). Then you sit there watching TV, and glancing at the clock. When the time is up to do something you get up and do it. Then you recalculate when you next need to do it. This can be extended to lots of things with no great loss of efficiency, unless you try to do thousands of things and there isn't enough time in the day to do them.

So don't get too bogged down with alarm libraries, and multiple functions. You know how to do this in real life, translate your thought processes into a sketch.

I see what you mean, Nick, thanks. I'm going to get a lot of the greenhouse construction done tomorrow so I'll have more time to just focus on code. I'm going to tinker around with this for the next day or two and see what I can figure out and I'll report back here.

Just don't push Nick's analogy too far. It's a great illustration of what you need to do, except...

Adding variables that can roll over can cause problems. Subtracting, on the other hand is guaranteed to work. So, instead of thinking in terms of "I need to feed the cat in 8 hours, and it's 9:00 now, so I'll feed the cat at 17:00", think of it always in terms of "How long has it been since I fed the cat. If it's more than 8 hours, it's time to do it again."

Well, how do you like that! You learn something new every day.

PaulS is absolutely right. (I was going to prove him wrong, but proved myself wrong haha).

The example below shows this. (I cut it down to 3 hours because I got bored).

Both adding and subtracting work if you don't wrap around. But subtracting is the only one that works if you wrap. And it works so neatly that it is a great way of doing it.

Using addition:

F = Fed that cat     T = Time to feed (in 3 hours)
    8                      11
 
Feed when now >= T (ie. at 11):
   
Time now              When to feed it
    8                      11     no
    9                      11     no
   10                      11     no
   11                      11     yes
   
 
Using subtraction:
 
 
Fed that cat    Time since we fed it 
    8                      0
    
Feed when (now - last_fed) >= hours_to_feed (3)

Time now         Time since we fed it (now - last fed time of 8)
    8                      0     no
    9                      1     no
   10                      2     no
   11                      3     yes

Now let's assume for sake of simplicity that the millis() returns a byte, so we go up to 255, and also it is later in the day, so the time now is 254.

Using addition:

F = Fed that cat     T = Time to feed (in 3 hours)
    254                    1   (wrapped to 0x01)
 
Feed when now >= T (1):

Time now
    254                    1    yes (this is wrong)
   
   
Using subtraction:
 
 
Fed that cat     Time since we fed it
    254                    0
    
Feed when (now - last_fed) >= hours_to_feed (3)

Time now         Time since we fed it (now - last fed time of 254)
    254                    0     no
    255                    1     no  (255 - 254)
      0                    2     no  (0 - 254 = 0xFFFFFF02, truncated = 0x02)
      1                    3     yes (1 - 254 = 0xFFFFFF03, truncated = 0x03)

This is the cat, by the way ... his name is Harvey. He is a pooka.

Harvey.jpg