Arduino UNO R4 Lesson12 - millis Function | Handling Multiple Tasks | Non-Blocking Code

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone Welcome Back to educationist Life your go-to channel for unlocking the wonders of learning it is me joed go and today we're on Lesson 12 of the arduin Uno R4 ultimate training series focusing on implementing n blocking code using mes for today's lesson you'll understand why using mes instead of delay is the proper way to implement timing events in your Arduino code you'll learn how to properly Branch your code using many different references to time in order to perform several tasks simultaneously this means that you can create projects involving several components without blocking each other's time of execution at the end of this lesson you'll be controlling a Servo motor while performing a traffic light operation and still be able to receive a signal from a sensor without having to wait for the previous task to complete before performing succeeding task as always before we start I'd like to extend my sincere gratitude to Sounder for is sponsoring this course and enabling everyone especially beginners to embark on this comprehensive educational Adventure throughout this series I'll be using this amazing Sounder Arduino Uno R4 Minima ultimate sensor kit this kit is packed with everything you need to build amazing Arduino iot projects so if you're still looking for a learning kit I encourage you so please check this one out this is available on the sanf founder website as well as on Amazon the links are provided below so now let's begin for this session you need the following materials an sg90 micro servo motor a normally open momentary push button switch or the Sounder button module three LEDs with three current limiting resistors or simply the Sounder traffic light module and of course a breadboard some connecting wires in your arduin Uno R4 Minima in most of our previous lessons we usually call the delay function to accomplish various tasks like making an LED blink at a certain frequency or positioning a Servo motor at a certain angle at a specified speed well using the delay function is actually good if you intend to pause the execution of your Arduino program for a specified period of time and there are some suitable applications as to why you would want to pause your program execution for a certain period like when performing sensor initialization or perhaps your program needs to pause for a while due to human interaction however you need to understand that the delay function is a blocking function that prevents your Arduino program from doing anything else until the specified time has elapsed so if you have several lines of code and you have delay function calls somewhere in between these codes the succeeding code execution will be put on hold until the delay is finished so what's wrong with that well the problem arises when your program needs to perform multiple task or events at the same time you simply cannot do that using the delay function now just a reminder since I mentioned multiple tasks some of our Advanced viewers here especially programmers might compare this topic on how multitasking is done in their computer's operating system please bear in mind that arduin Uno R4 is not similar to your desktop computer or your smartphone which allow running multiple programs on top of an operating system however there is a way we can run operating system on your Arduino Uno to support multitasking and this is called Os or realtime operating system but still technically Aros simply creates an illusion of multitasking by executing paralled instructions one at a time for now we're not going to discuss that so just to make things clear we're not going to run multiple programs at the same time however although we can only run one program at a time that doesn't mean we can't manage multiple task task like blinking an LED reading sensor data controlling Motors and others in Arduino we just need to change our perspective on doing things since we're not going to use an operating system to help us we we have to do things ourselves through our code we're going to write non-blocking codes to handle several task simultaneously creating an illusion of multitasking making our program stay responsive to illustrate this concept let's hook up the simple circuit diagram here we have the green yellow and red LEDs connected to pins 5 6 and 7 respectively then an sg90 Sur tur motor signal wire is connected to pin 9 and finally a botton module is connected to pin 2 if you want to refresh your memory on how these components work please check the links to the previous lessons below let's start the concept by creating a simple blinking LED program say we'll make this yellow LED blink at an interval of 250 milliseconds so to do that I'll Define yellow lead at Pin X and then set its mode as output and finally in the loop function I'll turn it on delay for 250 milliseconds and then turn it off and then another delay of 250 milliseconds before looping back to repeat the process and we know that this is going to work because we've done this a dozen times now to illustrate the point of why we don't use blocking functions like this delay function call when we try to perform many different things simultaneously let's also control the servo motor at the same time when I say at the same time let's make a program that positions the servo motor from 0° up to 180° say at a speed of 15 milliseconds per degree while the yellow LED is blinking at an interval of 250 milliseconds so one LED blink meaning one onoff cycle will consume 500 milliseconds and for the servo motor 15 milliseconds per degree for 180° gives us 2,700 milliseconds that's roughly about 5 1 12 LED blinks for the servo motor to position from 0 to 180° well this can only happen if both task are going to be executed at the same time however with this current code structure it it is not possible to show you first let's include the servo library or you can use the pwm servo library for a much smoother shaft movement please refer to the previous lesson on controlling Servo Motors however please note that when using this pwm Servo Library make sure to check if the version of your arduin Uno R4 boards installed is version 1.0.5 it will not work with the recent update of version 1.1.0 then I'll Define the servo motor pin at Pin 9 and then create an object of this Servo I'll call Servo one in the setup function I'll attach the servo pin to the servo object and then set the initial position of the servo motor at 0° finally I'll just put a 1second delay before the loop starts now inside the loop function just after this delay function call I'll create a for Loop to position the servo motor from 0 to 180° incrementing 1° every 15 millisecond delay so I'll upload this code and see what happens as you noticed it only blinks once and then followed by a Servo motor rotating from 0 to 180° and then the process repeats however this is not what we want the two task the blinking LED and the servo motor rotation do not execute in parallel but rather in sequence this is because we're using the delay function call all over the place during program execution the delay function literally blocks the succeeding codes from executing until the specified time delay is finished so to illustrate how to write nonblocking codes I'll delete this entire code and let's just focus on a single task in the meantime the blinking LED we'll write a program to make this led blink at a certain interval without using any delay function call and to do that we need to understand how mes function works the Millis function Returns the number of milliseconds that have passed since the Arduino board been running the current program so essentially it is a timer for how long the current program has been running the return type of the Millis function is unsigned long so I'll create a variable I'll call current time and store the return value of this Millis function call and then let's print this value to our serial monitor of course we need to set up this serial communication first now let's upload the code and see what happens as you can see these are the number of milliseconds that have passed since the program began running please note that this is independent of the number of times the void Loop has iterated so how long can it count well technically since the return type of this function is unsigned long which is 4 bytes that's 32 bits it means that it can store numbers from 0 up to 4 b294 m967 295 and if each count is roughly 1 millisecond long then it will take almost 50 days before this variable overflows meaning almost 50 days before the 32-bit container resets to zero now the question is how can we make use of this mes function that continuously Returns the number of milliseconds that have passed since the program began running the answer is that we can make use of these values to check how long a certain portion of our code has been running for example if the code that turns on the Leed starts at about 1,000 milliseconds and what we want is to turn it off after 250 milliseconds then we can keep on reading this return mes value in check if 250 millisecond have already passed and if so we can execute the code to turn off the LED so how do we check if 250 milliseconds have passed well simply subtract the start time when the code that turns on the LED is executed which is 1,000 milliseconds from the current time and then check if it is already greater than or equal to 2050 milliseconds which is the time elapsed if this condition turns through then then we know that 250 milliseconds have passed so it is time to execute the next code which is to turn off the LED Now using the same approach we need to mark this current time as the new start time when the LED is turned off we need to do this so that we can use the same condition to check if another 250 milliseconds have passed so that we can turn on the LED again and then Mark this current time as the new start time and the process repeats let's try implementing this in our code first we need to declare an unsigned long variable I'll call start time also I'll declare an unsigned int variable called interval this is our elapse time which is 250 Mills now before going to the loop function I'll initialize the start time variable by getting the current milliseconds this marks the starting time just before we turn on the LED so inside the loop function I'll turn on the [Music] LED now the question is how do we turn this off after 250 milliseconds have passed and then turn it back on after another 250 milliseconds have passed and so on so this is where the trick begins inside this Loop function we need to continuously get the current mes to know the current time and then ask if 250 milliseconds have already passed since this code was last executed so we enclose this code inside an if block so that it doesn't execute after every Loop it only executes when it reaches a specified interval of 250 milliseconds to do that we simply subtract the start time from the current time and compare if the elapse time is already 250 milliseconds if so the code inside the if block gets executed which is to turn off the LED but how do we do that well there are several ways to accomplish this but one of the easiest ways to do this without having to declare another variable is to Simply use the digital read function to read the current state of our LED pin this should return high or low depending on the current state and then apply a logical knot operator to invert the current state that is if the current LED state is high it becomes low and if for the next cycle inverting the current LED state of low becomes high now there's one thing that you must not forget you need to set or Mark the new start time which is is the current time so that we can use the same condition to check if another 250 milliseconds have passed so that we can turn on the LED again so let's upload the code and see if it works and as you can see we were able to make the yellow LED blink at an interval of 250 milliseconds without using any delay function call now this code is n blocking which means we can have other codes after the if block and they will be executed right away without having to wait for 250 monds so let's try controlling the servo motor to set the position from 0 to 180° at a speed of 15 milliseconds per degree but without using any delay function call and to do this we need to create another set of variables to hold different time references for the the servo motor operation so I'll duplicate these variables and change them to start time Servo and interval Servo but the interval Servo is only 15 milliseconds I'll also add another variable pause and set it to zero this will serve as the angle position of the servo motor that gets updated every 15 milliseconds so in the setup function I'll set the initial position of the servo motor to 0° then I'll initialize the start time Servo as well then just after this if block I'll declare another unsigned long current time Servo and get the current mes before moving the servo now similar to the previous if block I'll check whether 15 milliseconds have passed so that I can update the position of my Servo that is 1° from the previous position if current time Servo minus start time Servo this is the elapse time is greater than or equal to 15 milliseconds which is the interval Servo if so I'll set or Mark the new start time Servo which is the current time just before updating the new position of the servo motor here I'll type Plus plus POS which means increment the post value by one before writing to set the new Servo position now this code is not yet Complete because if we try to simulate the value of the post variable it will exceed the maximum degrees of 180 after 180 Loops so I'll create another condition here that sets the new value of the PO variable once it reaches 180° I'll set it to -1 instead of zero because of this codee servvo one that WR Plus+ PA which means increment first before setting the new position so after reaching 180° the next post value to be written after 15 millisecs is zero so this is fast from 180° down to Zer is only going to take 15 milliseconds however from 0 to 180° it is going to take 2, 700 milliseconds that's 15 milliseconds per degree now let's try uploading our sketch and see what happens so as you can see it works the yellow LED continuously blinks at an interval of 250 milliseconds while the servo motor rotates at a rate of 15 millisecond per degree it takes about five and a half blinks for the servo motor to cover 0 to 180° so by Computing the time differences for each task we can benefit from the use of non-blocking codes to have an illusion of multitasking here if we want to adjust the time interval say instead of 250 milliseconds for Blink rate I'll change it 100 milliseconds also say I want the servo motor to range only from 90° up to 180° at a speed of 30 millisecond per Dee so I'll upload this code and see what [Music] happens and as you can see it works perfectly now let's add one more component to this program a button module and let's say what we want is when the button is pushed regardless of the current position of the servo motor the servo will position to 90° and the red LED turns on now with this current setup this functionality is not that hard to add first we Define the red LED at Pin 7 and the botton pin at Pin two then set the pin mode of the red LED to Output set the pin mode of the button pin to input and finally Implement a condition that checks if the button is pushed and if so turn on the red LED and set the servo position to 90° otherwise turn off the red LED now I'll upload this code and see if it works so the previous functionality works as before but now when I push this button the red LED turns on and the servo position is reset to 90° for your challenge activity try to improve this program to imitate a simple traffic light system with a barrier represented by a Servo motor when the servo is positioned at 90° the green LED is turned on this will last for 10 seconds then the yellow LED blinks as the servo positions to 180° this will last for about 3 seconds before turning on the red LED after 7 Seconds the servo again repositions to 90° while the red LED remains on for another 3 seconds before turning on the green LED and the process repeats now the button here acts as an emergency button for pedestrian once it is pushed regardless of the current state of the traffic light it puts the traffic light into a warning State the warning state is when the yellow LED is blinking while the barrier positions to [Music] 180° [Music] again thank you so much for joining me in this lesson on implementing non-blocking codes using mes if you found this lesson enlightening don't forget to hit the like button subscribe for more knowledge pack sessions and ring the bell to stay updated so keep learning keep experimenting and always remember education is life see you in our next lesson happy coding
Info
Channel: Education is Life
Views: 3,203
Rating: undefined out of 5
Keywords: servo motor, servos, arduino, sunfounder, button module, traffic light, delay, millis, multitasking, multiple tasks, time sharing, blink without delay, servo, non-blocking, uno r4, minima, time references
Id: zq6tkXCn-j4
Channel Id: undefined
Length: 23min 38sec (1418 seconds)
Published: Fri Mar 01 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.