SERIOUSLY THIS IS AMAZING! I was dying trying to figure out multitasking on my tft computer i'm making, and this worked perfectly! I also didn't know you could read microseconds so that was helpful to!
I'm so glad to hear this helped, I'm hoping to do a new video on multitasking with many different items all at once so hopefully that one will be helpful to people as well. Thanks for the feedback, it's much appreciated.
Great video sir! Thanks a lot! Those time/lasttime/elapsedtime is just what I needed. Also I didn’t know about different functions one can make and call upon. P.s. I’ve heard that you’re planning to make a new video about this in the future. Maybe for next time, do some practice calculations to see how that system of keeping track of time works. (Why do we need to code these calculations like we do, what does it do after a few cycles/loops. Why does this little ‘keeping time’ system work so good..) I’m sure many people (like me) are quickly confused when dealing with these calculations. But for the rest, great video. It was very helpful!
Thanks for the feedback, I do plan to do more videos but unfortunately it's probably going to be a while before I'll have time. I have a lot of stuff going on in my personal life so I'm very busy lately. I will definitely write your suggestion down on my list of "to do videos", thanks for watching and commenting.
Heya.. im facing a little problem with the pid line follower...im using a diy ir sensor array of 6 the pid is working great and the library is kinda working but when i look at the values it kinda returns weird values sometimes which throws off the pid algorithm...do you think qtr library cant be used with dir sensor array?
There is a known issue with the QTR library... I don't recall if it's only on the digital IR sensors or the Analog as well but when using calibrated readings, the reading is allowed to go negative which causes rollover. Anyway, you can certainly use the QTR library with a DIY array, the concept is the same, I've done it before with no issues. Are you using my version of the QTR library? I haven't updated it for the new QTR sensors that came out last year or so but it fixes the rollover issue, I'm assuming that's the issue you are seeing.
thank you for the video, please help me i want to creat in incubator but the lcd result work with delay of servo motor not with theme delay exmp : dht11 delay (10) , and servo (500), the lcd show result of dht11 with delay (500)
This looks like a great example for an advanced multitasking video. Just so I'm clear you want to read from the DHT11 every 10ms, move a servo every 500ms and print the result of the DHT11 every 500ms?
I think nowadays it's easier to use freerts tasks, because in case you have 2 cores (like in esp32) you can even have 2 tasks running at the same time. This solution is nice, but it's really hard to manage once you have several different things going on.
Agreed, it's a lot of code (and repeated code at that) if trying to scale. I had not heard of freerts but looked at it a little and it looks promising, hopefully it is and it's easy to use, that's the whole goal, make things easy to use. Thanks for the info.
It depends on what you want to use it for. What I would probably start with is just to simply use an int, each time the button is pressed, increment that int and then you can use the BIN option of String to create a binary string output. String value = String(7, BIN) Now value should be "111". The number of bits is going to depend on the number, I believe String(1, BIN) will simply output 1 so if you have 8 LEDs you're trying to light up you're going to have to mess with the code a little to have a for-loop that iterates over 8 times but sets the LED to off if the length of "value" is less than 8. I hope that made sense, doing this over comments is difficult but I don't have time these days to do videos so this is the best I can do for now. Feel free to ask for more clarification on something though.
Hello sir, good evening, Am creating a program 20Khz PWM signal for pump. It's absolutely working fine, when I wrote 2nd millis function and upload same board but 2nd program is not properly worked. Any solution for this sir ? Am using Arduino UNO board.
I think there's still one little issue with this example. If you keep pressed the button the program will stall on the while(buttonPressed) loop, thus the led won´t blink until button is released. Perhaps adding the logic to avoid that would be great!
Good point, I had assumed a user would quickly press the button but that's not always the case so I will definitely add this to my list of videos to do.Thanks for the feedback.
@@RobotResearchLab I have written more than 300 lines of code including a function that reads button/sensor presses. If I execute the function for the sensor it works fine, if I execute the function for the button it works fine as well. However if I want to use the function for both sensors and buttons in one while loop it wont work. Do you have a fix for this? I have been dying to fix this
@@AppleFreak675 Hey, sorry that I'm just seeing this, it got lost in the mess of the holidays. If you're still having an issue can you send me your code so I can see what's going on? Just send me your contact information in my contact form and I'll email you back robotresearchlab.com/contact-me/
It depends on what you're talking about but it should still work with the way I'm doing it in the video. I'm creating a new video to answer some other questions I've had on this topic. I'll try to include something dependent but let me know if you have a specific case and I'll try to put that in there.
for the BUTTON_PIN? A couple of reasons; 1. Shorts are larger data types than char, they use 16 bits instead of char's 8 bits. Not that that's a huge deal but in embedded programming memory is scarce. 2. const ensures that the value isn't changed somewhere in the code, I could take that off but it doesn't "cost" anything, it just ensures that I get a compile error if I try to change the value somewhere else in the code. 3. For the name, I like to use BUTTON_PIN instead of BUTTON because it clearly states that this is for a pin. If I used a library which has what's called an "object" the is used for a button I would call that a button because it's an object/class. 4. For why it's BUTTON_PIN and not just button_pin, all caps indicates that it's a constant, never changing, variable. This is only for the developer's eyes, it's what's called a convention, it's standard practice but not required. If I were reading someone else's code and saw a variable named BUTTON_PIN somewhere farther down into the code, I would know they're using a constant value. It's just like Arduino's constant values like LED_BUILTIN, INPUT, HIGH, LOW, etc. those are all constants and it's obvious because they are in what is called "underscore case" format. Thanks for watching, and for the question, hopefully this clears it up for you and others down the road.
Technically, yes, since millis() does return an unsigned long. It wouldn't present an issue unless I had my Arduino running for 25 days or more. Even using unsigned long it would still have an issue of resetting after 50 days. In the end, there is always something that could be fixed or enhanced but I don't think it's necessary for the video. Good point though, I'll try to remember to use the same data type as the return type for functions in future videos.
@@RobotResearchLab Yes, you're right most control systems won't use some delay that is more than seconds, I think an int even should do in most cases. So yeah we won't need unsigned long unless we need something to be triggered within days, there are more suitable ways to daily timings. But in case of working to time things that is working in range of seconds, then even an int is enough. Thanks for clarifying that :)
Good question, for that I would probably add a counter that increases by one every time the button is pressed. Then I would check if it's even or odd and print depending on that. Here are some snippets of code that might help. // Global variable unsigned int btnPressCnt = 0; // In the button press code btnPressCnt++; if (btnPressCnt % 2 == 0) { Serial.println(" world!"); } else { Serial.print("Hello"); } If you haven't used it, this is a great opportunity to learn about the modulo operator (%). It provides you with the remainder after division so, in this case the remainder is 0 when the btnPressCnt is divisible by 2 (even number). Otherwise it will be 1 (in this case). This also works if you want something to occur every n times so it's very handy in that regard.
@@AussieTrucking The 2 represents that you want that to print every 2 times the button is pressed. You can add more `else if` statements to have something print every 5th time the button is pressed or every 9th time by changing that number or adding the `else if` with a new value, like this: ... else if (btnPressCount % 5 ==0) { Serial.println("This prints every 5th time the btn is pressed"); } else if (btnPressCount % 9 == 0) { Serial.println("This prints every 9th time the btn is pressed"); } If you're going to have a lot of cases, it would be a good opportunity to check out a switch statement instead of if as it's much cleaner looking when you have many different cases.
I think you are referring to the delay functions. Arduino doc states that delayMicroseconds() is only reliable up to 16383 microseconds and that anything over a few thousand should just simply use delay(). www.arduino.cc/reference/en/language/functions/time/delaymicroseconds/ I have not seen any issues with the accuracy of time other than the obvious being that Arduino is only fast enough to be accurate within 4 microseconds but any time you call micros() it should always be within 4 microseconds of the actual time.
I know, I hate that I had to put multithreading in the title but as I mentioned to someone else, the ONLY reason I did is because every time a student (or someone new to Arduino) asks me how to multthread, they really mean multitask so I wanted people looking for multithreading to be able to find this if they were really looking for multitasking. This is also why the thumbnail only says multitasking, I'm not one for clickbait so that's definitely not what I was trying to do here. I thought I mentioned in the video that it wasn't multithreading so that's my fault if I forgot to do that.
Correct, I believe I mentioned that in the video but if not that was my mistake. I titled the video this way because many people do not understand the difference between multithreading and hyperthreading. Most times when students ask me for multithreading what they really want is just simply to be able to do multiple things at the same time, they don't really want multithreading. To truly multithread you would need more than one microcontroller.
@@akknaodinden This technically is not multithreading either, it is more of a scheduler. Multithreading would be running two tasks at the same time. With only one core (microcontroller in this case) it is impossible to multithread, the best that can be done is simulating multithreading which is technically hyperthreading. The library you are referring to does this, you ultimately create tasks and they are executed by priority and timers.
Great tips. One thing to keep in mind is that if you stay in a while loop, the particular code you wrote will not allow the LED to continue blinking.
This looks like the code I’ve been looking for to run 3 stepper motors simultaneously or at least as near to simultaneous as possible. Thank you!
SERIOUSLY THIS IS AMAZING! I was dying trying to figure out multitasking on my tft computer i'm making, and this worked perfectly! I also didn't know you could read microseconds so that was helpful to!
I'm so glad to hear this helped, I'm hoping to do a new video on multitasking with many different items all at once so hopefully that one will be helpful to people as well. Thanks for the feedback, it's much appreciated.
@Sam Darwin scam
Thank you for THIS! Have been sharing this video when people ask me about Millis.. Also you have a good programming sense..
Thank you for your feedback and thanks for sharing with others. Hopefully I'll be back soon with some new content!
Great video sir! Thanks a lot! Those time/lasttime/elapsedtime is just what I needed. Also I didn’t know about different functions one can make and call upon.
P.s. I’ve heard that you’re planning to make a new video about this in the future. Maybe for next time, do some practice calculations to see how that system of keeping track of time works. (Why do we need to code these calculations like we do, what does it do after a few cycles/loops. Why does this little ‘keeping time’ system work so good..) I’m sure many people (like me) are quickly confused when dealing with these calculations. But for the rest, great video. It was very helpful!
Thanks for the feedback, I do plan to do more videos but unfortunately it's probably going to be a while before I'll have time. I have a lot of stuff going on in my personal life so I'm very busy lately. I will definitely write your suggestion down on my list of "to do videos", thanks for watching and commenting.
I was using it to read button input too. Thank you!
Glad it helped, thanks.
Really helpful. Thank you so much. Subscribed. Cheers J
Thanks so much, I am glad to hear it helped. Hoping to have more content soon.
Heya.. im facing a little problem with the pid line follower...im using a diy ir sensor array of 6 the pid is working great and the library is kinda working but when i look at the values it kinda returns weird values sometimes which throws off the pid algorithm...do you think qtr library cant be used with dir sensor array?
There is a known issue with the QTR library... I don't recall if it's only on the digital IR sensors or the Analog as well but when using calibrated readings, the reading is allowed to go negative which causes rollover. Anyway, you can certainly use the QTR library with a DIY array, the concept is the same, I've done it before with no issues.
Are you using my version of the QTR library? I haven't updated it for the new QTR sensors that came out last year or so but it fixes the rollover issue, I'm assuming that's the issue you are seeing.
thank you for the video, please help me i want to creat in incubator but the lcd result work with delay of servo motor not with theme delay exmp : dht11 delay (10) , and servo (500), the lcd show result of dht11 with delay (500)
This looks like a great example for an advanced multitasking video. Just so I'm clear you want to read from the DHT11 every 10ms, move a servo every 500ms and print the result of the DHT11 every 500ms?
I think nowadays it's easier to use freerts tasks, because in case you have 2 cores (like in esp32) you can even have 2 tasks running at the same time. This solution is nice, but it's really hard to manage once you have several different things going on.
Agreed, it's a lot of code (and repeated code at that) if trying to scale. I had not heard of freerts but looked at it a little and it looks promising, hopefully it is and it's easy to use, that's the whole goal, make things easy to use. Thanks for the info.
How would you program button that create 8 or so binary code. For example 1 push. 0001. 2 push 0011 e.t.c?
It depends on what you want to use it for. What I would probably start with is just to simply use an int, each time the button is pressed, increment that int and then you can use the BIN option of String to create a binary string output.
String value = String(7, BIN)
Now value should be "111". The number of bits is going to depend on the number, I believe String(1, BIN) will simply output 1 so if you have 8 LEDs you're trying to light up you're going to have to mess with the code a little to have a for-loop that iterates over 8 times but sets the LED to off if the length of "value" is less than 8.
I hope that made sense, doing this over comments is difficult but I don't have time these days to do videos so this is the best I can do for now. Feel free to ask for more clarification on something though.
Hello sir, good evening,
Am creating a program 20Khz PWM signal for pump. It's absolutely working fine, when I wrote 2nd millis function and upload same board but 2nd program is not properly worked. Any solution for this sir ? Am using Arduino UNO board.
I think there's still one little issue with this example. If you keep pressed the button the program will stall on the while(buttonPressed) loop, thus the led won´t blink until button is released. Perhaps adding the logic to avoid that would be great!
Good point, I had assumed a user would quickly press the button but that's not always the case so I will definitely add this to my list of videos to do.Thanks for the feedback.
@@RobotResearchLab I have written more than 300 lines of code including a function that reads button/sensor presses. If I execute the function for the sensor it works fine, if I execute the function for the button it works fine as well. However if I want to use the function for both sensors and buttons in one while loop it wont work. Do you have a fix for this? I have been dying to fix this
@@AppleFreak675 Hey, sorry that I'm just seeing this, it got lost in the mess of the holidays. If you're still having an issue can you send me your code so I can see what's going on? Just send me your contact information in my contact form and I'll email you back robotresearchlab.com/contact-me/
what if the two tasks are dependent to each other? at that time how to handle to events simultaneously
It depends on what you're talking about but it should still work with the way I'm doing it in the video. I'm creating a new video to answer some other questions I've had on this topic. I'll try to include something dependent but let me know if you have a specific case and I'll try to put that in there.
In the end you used all 3 of them in the title XD
Why not the short int button = 8? Yours is much longer
for the BUTTON_PIN? A couple of reasons;
1. Shorts are larger data types than char, they use 16 bits instead of char's 8 bits. Not that that's a huge deal but in embedded programming memory is scarce.
2. const ensures that the value isn't changed somewhere in the code, I could take that off but it doesn't "cost" anything, it just ensures that I get a compile error if I try to change the value somewhere else in the code.
3. For the name, I like to use BUTTON_PIN instead of BUTTON because it clearly states that this is for a pin. If I used a library which has what's called an "object" the is used for a button I would call that a button because it's an object/class.
4. For why it's BUTTON_PIN and not just button_pin, all caps indicates that it's a constant, never changing, variable. This is only for the developer's eyes, it's what's called a convention, it's standard practice but not required. If I were reading someone else's code and saw a variable named BUTTON_PIN somewhere farther down into the code, I would know they're using a constant value. It's just like Arduino's constant values like LED_BUILTIN, INPUT, HIGH, LOW, etc. those are all constants and it's obvious because they are in what is called "underscore case" format.
Thanks for watching, and for the question, hopefully this clears it up for you and others down the road.
shouldn't you use unsigned long ?
Technically, yes, since millis() does return an unsigned long. It wouldn't present an issue unless I had my Arduino running for 25 days or more. Even using unsigned long it would still have an issue of resetting after 50 days. In the end, there is always something that could be fixed or enhanced but I don't think it's necessary for the video. Good point though, I'll try to remember to use the same data type as the return type for functions in future videos.
@@RobotResearchLab Yes, you're right most control systems won't use some delay that is more than seconds, I think an int even should do in most cases. So yeah we won't need unsigned long unless we need something to be triggered within days, there are more suitable ways to daily timings. But in case of working to time things that is working in range of seconds, then even an int is enough.
Thanks for clarifying that :)
so how to write something after 'hello'? so 1 press 'hello' 2nd press 'world' then back to 'hello'
Good question, for that I would probably add a counter that increases by one every time the button is pressed. Then I would check if it's even or odd and print depending on that. Here are some snippets of code that might help.
// Global variable
unsigned int btnPressCnt = 0;
// In the button press code
btnPressCnt++;
if (btnPressCnt % 2 == 0) {
Serial.println(" world!");
} else {
Serial.print("Hello");
}
If you haven't used it, this is a great opportunity to learn about the modulo operator (%). It provides you with the remainder after division so, in this case the remainder is 0 when the btnPressCnt is divisible by 2 (even number). Otherwise it will be 1 (in this case). This also works if you want something to occur every n times so it's very handy in that regard.
@@RobotResearchLab Thank you for that. And If I understand to have words change the 2 to how ever many I need?
@@AussieTrucking The 2 represents that you want that to print every 2 times the button is pressed. You can add more `else if` statements to have something print every 5th time the button is pressed or every 9th time by changing that number or adding the `else if` with a new value, like this:
...
else if (btnPressCount % 5 ==0) {
Serial.println("This prints every 5th time the btn is pressed");
} else if (btnPressCount % 9 == 0) {
Serial.println("This prints every 9th time the btn is pressed");
}
If you're going to have a lot of cases, it would be a good opportunity to check out a switch statement instead of if as it's much cleaner looking when you have many different cases.
'Anytime more than 16ms, you should then use millis();'
I think you are referring to the delay functions. Arduino doc states that delayMicroseconds() is only reliable up to 16383 microseconds and that anything over a few thousand should just simply use delay().
www.arduino.cc/reference/en/language/functions/time/delaymicroseconds/
I have not seen any issues with the accuracy of time other than the obvious being that Arduino is only fast enough to be accurate within 4 microseconds but any time you call micros() it should always be within 4 microseconds of the actual time.
Bro its not multithreading..i can say multitask using time base...any way explanation is nice good work...but change heading 😎
I know, I hate that I had to put multithreading in the title but as I mentioned to someone else, the ONLY reason I did is because every time a student (or someone new to Arduino) asks me how to multthread, they really mean multitask so I wanted people looking for multithreading to be able to find this if they were really looking for multitasking. This is also why the thumbnail only says multitasking, I'm not one for clickbait so that's definitely not what I was trying to do here.
I thought I mentioned in the video that it wasn't multithreading so that's my fault if I forgot to do that.
This is not real Threading
Correct, I believe I mentioned that in the video but if not that was my mistake. I titled the video this way because many people do not understand the difference between multithreading and hyperthreading. Most times when students ask me for multithreading what they really want is just simply to be able to do multiple things at the same time, they don't really want multithreading. To truly multithread you would need more than one microcontroller.
@@RobotResearchLab As I know arduino supports up to 57 threads via CreateThread()
@@akknaodinden This technically is not multithreading either, it is more of a scheduler. Multithreading would be running two tasks at the same time. With only one core (microcontroller in this case) it is impossible to multithread, the best that can be done is simulating multithreading which is technically hyperthreading. The library you are referring to does this, you ultimately create tasks and they are executed by priority and timers.