Hello, I have a problem. I wrote a bit of code to control filtration and warming of my pool, but I want to run these codes separatly. Is there any way to do it? And is there way to set warming to make 5 loops and then more shorter loops?
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
}
void loop(){
filtration();
warming();
}
void filtration(){
digitalWrite(13, HIGH); // filter on
delay(50000); // wait for a second
digitalWrite(13, LOW); // filter off
delay(10000); // wait for a second
}
void warming(){
digitalWrite(12, LOW); //
delay(25000);
digitalWrite(12, HIGH);
delay(5000);
}
@martin42069 Why do users choose to ignore the advice on posting code ?
The easier you make it to read and copy your code the more likely it is that you will get help
Your post was MOVED to its current location as it is more suitable.
Could you also take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.
Please follow the advice given in the link below when posting code , use code tags and post the code here
something like this?
#define MAX 10
int cnt = 0;
#define SEC 100
void setup () {
Serial.begin (9600);
pinMode (13, OUTPUT);
pinMode (12, OUTPUT);
}
void loop (){
if (cnt++ < 5)
warming ();
else
filtration ();
if (MAX <= cnt)
cnt = 0;
}
void filtration (){
Serial.println (__func__);
digitalWrite (13, HIGH); // filter on
delay (50 * SEC);
digitalWrite (13, LOW); // filter off
delay (10 * SEC);
}
void warming (){
Serial.println (__func__);
digitalWrite (12, LOW); //
delay (25 * SEC);
digitalWrite (12, HIGH);
delay (50 * SEC);
}
why define SEC as 100? Are you just following the OP's lead or did I miss something?
-jim lee
Look at the tutorial several things at the same time It will show you how to not use delay().
A typical way to make the warming go through 5 cycles first would be to put that in setup(). You could introduce a cycle counter into each function that returns the cycle count
Something like this
enum { OFF, ON };
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
while ( warming() < 6 ) {
// do nothing
}
}
void loop() {
filtration();
warming();
}
unsigned int filtration() {
static unsigned int cycles = 0;
static bool state = OFF;
static unsigned long startTime;
static unsigned long duration;
const unsigned long onTime = 50000UL;
const unsigned long offTime = 10000UL;
if ( millis() - startTime >= duration ) {
startTime = millis(); // reset timer
if ( state == ON ) {
// time to turn off
state = OFF;
duration = offTime;
digitalWrite(13, LOW); // filter off
cycles++;
}
else {
// time to turn on
state = ON;
duration = onTime;
digitalWrite(13, HIGH); // filter on
}
}
return cycles;
}
unsigned int warming() {
static unsigned int cycles = 0;
static bool state = OFF;
static unsigned long startTime;
static unsigned long duration;
const unsigned long onTime = 5000UL;
const unsigned long offTime = 25000UL;
if ( millis() - startTime >= duration ) {
startTime = millis(); // reset timer
if ( state == ON ) {
// time to turn off
state = OFF;
duration = offTime;
digitalWrite(12, LOW); // heater off
cycles++;
}
else {
// time to turn on
state = ON;
duration = onTime;
digitalWrite(12, HIGH); // heater on
}
}
return cycles;
}
to test it within a short period of time.
should have mentioned this.
Hello
I have made a sketch using two timers.
Take a look.
const byte WarmingPin = 12;
const byte FilterPin = 13;
// specify switching times --> xxxTimes[]={OnTime,OffTime};
const unsigned long FilterTimes[] = {10000, 50000};
const unsigned long WarmingTimes[] = {25000, 5000};
unsigned long currentMillis;
unsigned long filterMillis;
unsigned long warmingMillis;
// functions
void filtration() {
if (currentMillis - filterMillis >= FilterTimes[digitalRead(FilterPin)]) {
filterMillis = currentMillis;
digitalWrite(FilterPin, digitalRead(FilterPin) ^ 1);
Serial.print(__func__), Serial.print(F(" is ")), Serial.println(digitalRead(FilterPin) ? "ON" : "OFF");
}
}
void warming() {
if (currentMillis - warmingMillis >= WarmingTimes[digitalRead(WarmingPin)]) {
warmingMillis = currentMillis;
digitalWrite(WarmingPin, digitalRead(WarmingPin) ^ 1);
Serial.print(__func__), Serial.print(F(" is ")), Serial.println(digitalRead(WarmingPin) ? "ON" : "OFF");
}
}
void setup() {
Serial.begin(9600);
Serial.println(__func__);
pinMode(WarmingPin, OUTPUT);
pinMode(FilterPin, OUTPUT);
// set start conditions
digitalWrite(WarmingPin, LOW);
digitalWrite(FilterPin, HIGH);
}
void loop() {
currentMillis = millis();
filtration();
warming();
}
What do you think?
Hi Martin,
Welcome!
A few quick things that may help ...
-
First up, congrats of getting to grips with subroutines. As your code grows it gets more important to format it correctly so you can keep track of where things are (and not make mistakes like forgetting to add closing curly braces etc). There's a tool in the IDE ("program editor") that does that for us ... just do a ctrl+T (or you can also get to it from the Tools menu).
-
Second up, it's really hard for people to read your code when it's pasted in a post like that (especially for people on mobile devices). There's a a dead easy way to sort that; when you're in the IDE you just need to select all (Edit -> select all or ctrl+A) and then copy it to the clipboard in a "forum friendly format" by selecting Edit -> copy for forum (or shift+ctrl+C). Then you can just paste it into a post and it'll appear in it's own scrollable window.
-
Your code has a little "gotcha" in it by the way; the pinModes should (need) to be inside the setup section.
I've taken the liberty of apply all three points to your code below:
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
}
void loop() {
filtration();
warming();
}
void filtration() {
digitalWrite(13, HIGH); // filter on
delay(50000); // wait for a second
digitalWrite(13, LOW); // filter off
delay(10000); // wait for a second
}
void warming() {
digitalWrite(12, LOW); //
delay(25000);
digitalWrite(12, HIGH);
delay(5000);
}
To (finally) get to the question at hand (sorry about that) in essence the way I approach "multi-tasking" like this is to not tie the processor up doing nothing with a delay(), but to instead handle events relative to a timestamp; you get a timestamp to record a point in time now - work out what time it'll be relative to that when you need to take the next action - and then just keep the loop asking "has that time passed yet?". If the answer is "no" then we just let it carry on and do other stuff.
I see that several of my learned friends have already posted some code - I'd be happy to write a sketch for you too, but I'd first like to clarify some of the numbers that you need; if this is a real project then you probably don't want to start the filter pump every 50 seconds then stop it for 10 seconds as it is now ... and you probably don't want to turn the heater on for 25 seconds and then turn it off for 5 seconds - I'm guessing that it would make far more sense to turn the filter on between certain hours and control the heater by comparing the actual temperature to the desired tempterature (both pretty easy things to do) (or are you just using this as a learning example?)
So would be fantastic if you could just give me some feedback on that before I commit "malpractice" by "prescribing before properly diagnosing" ![]()
Cheers,
Colin
Thanks a lot for your help. The right numbers are: Fitler should work for 50 minutes and has a 10 min pause. Heater should turn on every 25 minutes for 5 minutes
Why the pauses? What happens, say.. When the filter is paused? Why not run is continuously?
-jim lee
It´s not what I meant, but it hepled me too. Thanks!!
It works great. Thanks
You're very welcome.
Just remember that we're working in milliseconds here - so the filter needs to be on for 3,000,000ms then off for 600,000ms - and the heater needs to be on for 300,000ms and then off for 1,500,000ms (although personally I'd just tie it to a thermometer like this one: https://www.aliexpress.com/item/1005002356544667.html)
I would use the timeObj library written by Jim Lee:(GitHub - leftCoast/LC_baseTools: Tools to make programming Arduinos easier.).
The timeObj.h library greatly simplifies using millis().
I use this library in many of my projects.
Here is code showing how it works. Note that Seconds is defined as 100 instead of 1000 for demonstration purposes. I have LEDs on the filter and heater digital pins.
/*
Example of using the timeObj library to blink an LED asynchronously
Filter will be on for 50 minutes, then off for 10 min.
Heater will be on for 5 minutes, then off for 25 minutes.
*/
const int Seconds = 100; //ms per second
#include "timeObj.h"
//Create timer objects, don't start them.
timeObj filterOnTimer(50 * Seconds, false);
timeObj filterOffTimer(10 * Seconds, false);
timeObj heatOnTimer(5 * Seconds, false);
timeObj heatOffTimer(25 * Seconds, false);
int filterPin = D2; // The LEDs we want to blink.
int heatPin = D1;
void setup() {
pinMode(filterPin, OUTPUT); // Initialize the LED pins as an output.
pinMode(heatPin, OUTPUT);
digitalWrite(filterPin, HIGH); // Turn the filter on.
filterOnTimer.start(); // Start the filter timer.
digitalWrite(heatPin, HIGH); // Turn the heat on.
heatOnTimer.start(); // Start the hest timer.
}
void loop() {
if (filterOnTimer.ding()) filterOff(); //When the filter on timer dings, turn the filter off.
if (filterOffTimer.ding()) filterOn(); //When the filter off timer dings, turn the filter on.
if (heatOnTimer.ding()) heatOff(); //When the heat on timer dings, turn the filter off.
if (heatOffTimer.ding()) heatOn(); //When the heat off timer dings, turn the filter on.
}
void filterOff() {
filterOnTimer.stop();
digitalWrite(filterPin, LOW); // Turn the filter off.
filterOffTimer.start(); // Start the off timer
}
void filterOn() {
filterOffTimer.stop(); // Turn off the filter off timer
digitalWrite(filterPin, HIGH); // Turn the filter on.
filterOnTimer.start(); // Start the filter timer
}
void heatOff() {
heatOnTimer.stop();
digitalWrite(heatPin, LOW); // Turn the heat off.
heatOffTimer.start(); // Start the off timer
}
void heatOn() {
heatOffTimer.stop(); // Turn off the heat off timer
digitalWrite(heatPin, HIGH); // Turn the heat on.
heatOnTimer.start(); // Start the heat timer
}
@SteveMann : Err, make that..
filterOnTimer.reset();
Remember, you're using your custom version.
-jim lee
Project is complete now! Thanks to all of you!
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.