Is it possible to do something like this with Arduino?

Hey everyone. I know that writing what I want my code to do is somewhat illegal without any code from my side, but I am in need of keywords.

I currently have developed a system that uses a temperature sensor and a zero cross detection circuit to control the temperature of a water supply with a PID controller. However, now, I would like to write a flow like this;

1-If the temperature of water is colder or hotter than the setpoint, let it converge to the setpoint by natural cooling or turning on the heaters.

2-As soon as the temperature is between an upper and lower threshold of my setpoint, take an analog measurement from a conductivity sensor and record it to be used as a reference point throughout the code.

3-Every 10ish seconds, compare the current value of the conductivity sensor to the reference value

4- If the difference between the current sensor value and the reference value is greater than a threshold, raise a flag and wait t seconds.

5-After t seconds have passed, raise another flag.

While doing all this, the PID controller MUST run, maintaining a steady temperature of the water bath.

I do not need the exact code for this solution obviously, I just need some programming keywords or hopefully structures because my coding experience revolved around the void setup and void loop since this point, I think this application will require me to move out of these. Just trying to step out of my comfort zone.

Any help is greatly appreciated.

Start by installing the PID library and looking at the examples. Test the use of the temperature sensor (what is it ?) independently of the PID then use the sensor and PID to control the water temperature within a given range. Test the conductivity tester (what is it ?) separately before trying to integrate it into your project

Do not expect to find code already written that does what you want

Thank you for your input. As I said, I am not looking for code. I just don't know if this is doable with an Arduino. Every component works separately and while combined. I need to improve my general coding abilities I guess.

It all sounds possible using an Arduino

1 Like

You will have two separate processes going on. One maintaining the temperature of the water bath, and a second measuring and monitoring the conductivity. But most Arduino have only a single core processor and no real time operating system to share resources between processes. So you must code your 2 processes using "non-blocking code" which means no use of delay() (except perhaps the occasional very short delay) and no code loops which take long periods to run, or which wait for particular external conditions before they stop looping.

So read up on techniques to write non-blocking code, using millis() for timing and generally getting Arduinos to do more than one thing at the same time.

See Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

Thank you guys, will definitely check upon these concepts!

My tutorials on How to write Timers and Delays in Arduino and
Multi-tasking in Arduino will help with doing multiple tasks 'at the same time'

Hello
in this case a smart task scheduler is needed and essential.

No need for a "smart task scheduler" when you can do it easily with millis().

1 Like

Whenever I hear that somebody wants to do temperature control with a PID, my first question is: WHY?

A simple Bang-Bang controller with a degree or two of hysteresis around the setpoint will almost always do the job with a much simpler implementation. No coefficient tuning. Stable. Simple.

This is how the thermostat in your home's HVAC system works. I'm sure that keeps you quite comfortable.

2 Likes

PID (when done properly) can hold the temperature steadier than a thermostat. Whether this is necessary or not depends on the application.

My last job involved testing equipment in large thermal chambers, and those were PID controlled not simple thermostats. There's a time and a place for everything.

You do have a good point though, it is good to question if such a complicated method is necessary. That is something only the OP can answer right now, since we don't know what the water is being used for.

This looks like a really thorough guide. Will sure give it a check!

At this point, I shall not provide any further information about the details. The PID controller is not the main focus of this post anyway. Creating timed events and conditions while the PID controller is running can be the focus. As you guys said, I need to explore more what can millis() do, and possibly study how to raise flags to indicate certain conditions maybe.

millis() works completely different than delay()
Trying to see a "delay-similar-thing" in millis() makes it hard to understand milis().

If you see milis() as something really new it is quite easy to understand.

as an allday example with easy to follow numbers
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()
You have to understand the difference first and then look into the code.
otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to understand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.

imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes

You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02 (snapshot of time)
You start reading the newspaper and from time to time looking onto your watch
watch 13:02 not yet time
watch 13:03 not yet time
watch 13:04 not yet time 13:04 - 13:02 = 2 minutes is less than 3 minutes
watch 13:05 when did I start 13:02? OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven

New basetime 13:05 (the snapshot of time)
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time (13:08 - 13:05 = 3 minutes is less than 10 minutes
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time (13:14 - 13:05 = 9 minutes is less than 10 minutes
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)

You did a repeated comparing how much time has passed by
This is what non-blocking timing does

In the code looking at "How much time has passed by" is done

currentTime - startTime >= bakingTime

bakingTime is 10 minutes

13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!

if (currentTime - previousTime >= period) {

it has to be coded exactly this way because in this way it manages the rollover from Max back to zero
of the function millis() automatically

baldengineer.com has a very good tutorial about timing with function millis() too .

There is one paragraph that nails down the difference between function delay() and millis() down to the point:

The millis() function is one of the most powerful functions of the Arduino library. This function returns the number of milliseconds the current sketch has been running since the last reset. At first, you might be thinking, well that’s not every useful! But consider how you tell time during the day. Effectively, you look at how many minutes have elapsed since midnight. That’s the idea behind millis()!

Instead of “waiting a certain amount of time” like you do with delay(), you can use millis() to ask “how much time has passed”?

best regards Stefan

1 Like

Thank you for the intuitive examples =)

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.