{"id":41754,"date":"2021-05-11T15:30:53","date_gmt":"2021-05-11T07:30:53","guid":{"rendered":"\/blog\/?p=41754"},"modified":"2021-09-29T16:18:31","modified_gmt":"2021-09-29T08:18:31","slug":"multitasking-with-arduino-millis-rtos-more","status":"publish","type":"post","link":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/","title":{"rendered":"Multitasking with Arduino &#8211; Millis(), RTOS &#038; More!"},"content":{"rendered":"\n<p>Arduino microcontrollers are a beginner friendly and low cost platform for electronics and programming. They\u2019re great for simple control tasks like blinking an LED, but how much can we stretch the potential of a single Arduino? In other words, is multitasking with Arduino possible? If you\u2019ve learnt some basic Arduino Programming and want to take it to the next level, this article is definitely for you!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In our Multitasking with Arduino guide, we will cover:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Issues with the Age-Old Delay()<\/li><li>Keeping Time with Millis()<\/li><li>Tutorial: Achieve Arduino Multitasking with Millis()<\/li><li>How to Scale Multitasking with Object Oriented Programming<\/li><li>Introduction to RTOS (Real Time Operating Systems)<\/li><li>Tutorial: Achieve Arduino Multitasking with FreeRTOS<\/li><\/ul>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1030\" height=\"601\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/03\/Week-8--1030x601.jpg\" alt=\"\" class=\"wp-image-41779\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1030x601.jpg 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--300x175.jpg 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--768x448.jpg 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1536x896.jpg 1536w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--2048x1195.jpg 2048w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1024x597.jpg 1024w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Issues with the Age-Old Delay()<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Before we get into proper Arduino multitasking, we need to talk about different methods of keeping time, starting from the very popular <strong>delay()<\/strong> function. Let\u2019s first take a look at the definition of the function from the <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/time\/delay\/\">official Arduino documentation<\/a>.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>delay(ms)\n\/\/ Pauses the program for the amount of time (in milliseconds) specified as parameter. (There are 1000 milliseconds in a second.)\n\n\/\/ ms: the number of milliseconds to pause. Allowed data types: unsigned long.<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>An unfortunate caveat of the delay() function is that it is a <strong>blocking delay<\/strong>. Let me explain. Through the duration of a delay() function call, the CPU of our Arduino is kept busy. This means it can&#8217;t respond to sensor inputs, perform any calculations, or send any outputs.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To better explain the implications of this behaviour, let\u2019s look at an example. Taking the blinky example from the same page, our Arduino code to blink an LED at regular intervals with the use of the delay() function might look like this.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>int ledPin = 13;              \/\/ LED connected to digital pin 13\n\nvoid setup() {\n  pinMode(ledPin, OUTPUT);    \/\/ sets the digital pin as output\n}\n\nvoid loop() {\n  digitalWrite(ledPin, HIGH); \/\/ sets the LED on\n  delay(1000);                \/\/ waits for a second\n  digitalWrite(ledPin, LOW);  \/\/ sets the LED off\n  delay(1000);                \/\/ waits for a second\n}<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now, what if we wanted to blink two LEDs at different intervals? Perhaps you might try the code below.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>int ledPin1 = 13;              \/\/ LED 1 connected to digital pin 13\nint ledPin2 = 14;              \/\/ LED 2 connected to digital pin 14\n\nvoid setup() {\n  pinMode(ledPin1, OUTPUT);    \/\/ sets the digital pin as output\n  pinMode(ledPin2, OUTPUT);    \/\/ sets the digital pin as output\n}\n\nvoid loop() {\n  digitalWrite(ledPin1, HIGH); \/\/ sets LED 1 on\n  delay(1000);                 \/\/ waits for a second\n  digitalWrite(ledPin1, LOW);  \/\/ sets LED 1 off\n  delay(1000);                 \/\/ waits for a second\n  \n  digitalWrite(ledPin2, HIGH); \/\/ sets LED 2 on\n  delay(2000);                 \/\/ waits for two seconds\n  digitalWrite(ledPin2, LOW);  \/\/ sets LED 2 off\n  delay(2000);                 \/\/ waits for two seconds\n}<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>On inspecting the code line by line, we\u2019ll find that the LEDs are turned on one after another. However, it won\u2019t do it simultaneously.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is Millis()?<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The solution to the problem we encountered previously is fundamentally simple. Instead of defining the delay duration directly, we constantly check the clock to determine if enough time has passed for the next action to be executed. To do this, the <a href=\"https:\/\/www.arduino.cc\/reference\/en\/language\/functions\/time\/millis\/\">millis() function<\/a> is most commonly used.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>time = millis()\n\/\/ Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>So, what we have here is a very useful function that will mark out <strong>references in time<\/strong>, so that we are able to program timing in our Arduino sketches! Let\u2019s apply this to the blinking example by looking at the BlinkWithoutDelay sketch from Arduino.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>const int ledPin =  LED_BUILTIN;      \/\/ the number of the LED pin\nint ledState = LOW;                   \/\/ ledState used to set the LED\n\n\/\/ Generally, you should use \"unsigned long\" for variables that hold time\n\/\/ The value will quickly become too large for an int to store\n\nunsigned long previousMillis = 0;     \/\/ will store last time LED was updated\n\nconst long interval = 1000;           \/\/ interval at which to blink (milliseconds)\n\nvoid setup() {\n  pinMode(ledPin, OUTPUT);\n}\n\nvoid loop() {\n  \/\/ check to see if it's time to blink the LED; that is, if the difference\n  \/\/ between the current time and last time you blinked the LED is bigger than\n  \/\/ the interval at which you want to blink the LED.\n  unsigned long currentMillis = millis();\n\n  if (currentMillis - previousMillis &gt;= interval) {\n    \/\/ save the last time you blinked the LED\n    previousMillis = currentMillis;\n\n    \/\/ if the LED is off turn it on and vice-versa:\n    if (ledState == LOW) {\n      ledState = HIGH;\n    } else {\n      ledState = LOW;\n    }\n\n    \/\/ set the LED with the ledState of the variable:\n    digitalWrite(ledPin, ledState);\n  }\n}<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>What\u2019s so special about this sketch, you might ask? Well, the first thing you\u2019ll notice is that there are no longer any delay() function calls in our code! Yet, we\u2019re able to blink our LEDs all the same.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Our new sketch is made essentially of two continuously running parts that do the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Checks the ledState variable and writes the LED state accordingly.<\/li><li>Checks the time elapsed with millis() and toggles the ledState variable accordingly.<\/li><\/ol>\n\n\n\n<div style=\"height:14px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In fact, this structure is what is known as a <strong>State Machine<\/strong>.<strong> <\/strong>A state machine is a behaviour model where the <strong>machine<\/strong> performs predefined outputs depending on the current <strong>state<\/strong>.<\/p>\n\n\n\n<p><strong>To Summarise:<\/strong> Avoid the use of delay(), use millis() instead!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Arduino Microcontrollers: My Recommendations<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Before we dive deeper into the tutorials on how to perform more advanced multitasking with Arduino, I want to share some of the Arduino-compatible microcontrollers that we have here at Seeed. After all, in electronics, the hardware is just as important as software!<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Seeeduino XIAO<\/strong><\/h3>\n\n\n\n<p>Seeeduino XIAO is the smallest Arduino board in the Seeeduino Family. Despite its small size, the Seeeduino XIAO is equipped with the powerful SAMD21 microchip and extensive hardware interfaces, coming in at an ultra-affordable price of under five dollars.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/DfeKY0on3yOmcek1R1XSzIfV31GUmBB7cTTmdbQZZZHkBh1DMeSfCXg4oy6Gc_7ybSmUvaD4NA6vzocr1asjylePWYApXQwhu3EAKaGdR6ZdH-Rd8ZBKb94S3iK2zK7Y5OdB2eZF\" alt=\"\" width=\"400\"\/><\/figure><\/div>\n\n\n\n<p><strong>Product Features:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>ARM Cortex-M0+ 32bit 48MHz microcontroller (SAMD21G18) with 256KB Flash, 32KB SRAM<\/li><li>Compatible with Arduino IDE &amp; MicroPython<\/li><li>Easy Project Operation: Breadboard-friendly<\/li><li>Small Size: As small as a thumb(20\u00d717.5mm) for wearable devices and small projects.<\/li><li>Multiple development interfaces: 11 digital\/analog pins, 10 PWM Pins, 1 DAC output, 1 SWD Bonding pad interface, 1 I2C interface, 1 UART interface, 1 SPI interface.<\/li><\/ul>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Keen to learn more about the Seeeduino XIAO? Visit its <a href=\"https:\/\/www.seeedstudio.com\/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html\">product page<\/a> on our Seeed Online Store now!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Wio Terminal<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The Wio Terminal is a complete Arduino development platform based on the ATSAMD51, with wireless connectivity powered by Realtek RTL8720DN. As an all-in-one microcontroller, it has an onboard 2.4\u201d LCD Display, IMU, microphone, buzzer, microSD card slot, light sensor &amp; infrared emitter. It\u2019s the last Arduino you will need!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/RESYaEu09GCy3fD89eU3d5akkCt_FonKX7EDxp1RgLX8gv16sTdebmhnrykrvCJjTFVjKZdy08pWq1c1rE_0a5_ums0EK-QjaFOoLBF4oYrtnQvlJ8xPILghInz25DXlMAZdAi58\" alt=\"\" width=\"400\"\/><\/figure><\/div>\n\n\n\n<p><strong>Product Features:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Powerful MCU: Microchip ATSAMD51P19 with ARM Cortex-M4F core running at 120MHz<\/li><li>Reliable Wireless Connectivity: Equipped with Realtek RTL8720DN, dual-band 2.4GHz \/ 5GHz Wi-Fi (supported only by Arduino)<\/li><li>Highly Integrated Design: 2.4\u201d LCD Screen, IMU and more practical add-ons housed in a compact enclosure with built-in magnets &amp; mounting holes<\/li><li>Raspberry Pi 40-pin Compatible GPIO<\/li><li>Compatible with over 300 plug&amp;play Grove modules to explore with IoT<\/li><li>USB OTG Support<\/li><li>Support Arduino, CircuitPython, Micropython, ArduPy, AT Firmware, Visual Studio Code<\/li><li>TELEC Certified<\/li><\/ul>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>If you\u2019re interested to pick up a Wio Terminal, please visit its <a href=\"https:\/\/www.seeedstudio.com\/Wio-Terminal-p-4509.html\">product page<\/a> on the Seeed Online Store!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Achieve Arduino Multitasking with Millis()<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The biggest advantage of using millis() over delay() is the removal of blocking. This opens up the possibility to run multiple operations at once! To show you how this can be done, let\u2019s try to apply what we\u2019ve learnt to fix our previous (not-so-successful) attempt to blink two LEDs at different intervals.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>int ledPin1 = 13;              \/\/ LED 1 connected to digital pin 13\nint ledPin2 = 14;              \/\/ LED 2 connected to digital pin 14\n\nint ledState1 = LOW;           \/\/ LED 1 is initially set to off\nint ledState2 = LOW;           \/\/ LED 2 is initially set to off\n\nunsigned long millis1;         \/\/ initialises millis marker for LED 1\nunsigned long millis2;         \/\/ initialises millis marker for LED 2\n\nvoid setup() {\n  pinMode(ledPin1, OUTPUT);    \/\/ sets the digital pin as output\n  pinMode(ledPin2, OUTPUT);    \/\/ sets the digital pin as output\n}\n\nvoid loop() {\n\n  \/\/ Update LED States\n  digitalWrite(ledPin1, ledState1);\n  digitalWrite(ledPin2, ledState2);\n\n  \/\/ Toggle the LED states if the duration has passed\n\n  if ( (millis() - millis1) &gt; 1000) {\n    millis1 = millis();\n    if (ledState1 == LOW) {\n      ledState1 = HIGH;\n    } else if (ledState1 == HIGH) {\n      ledState1 = LOW;\n    }\n  }\n  \n  if ( (millis() - millis2) &gt; 2000) {\n    millis2 = millis();\n    if (ledState2 == LOW) {\n      ledState2 = HIGH;\n    } else if (ledState2 == HIGH) {\n      ledState2 = LOW;\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>You\u2019ll notice that this isn\u2019t too different from the previous millis() example. We\u2019ve essentially duplicated the lines of code that concern the specific LED, and adjusted the parameters so that the second LED toggles every 2 seconds &#8211; Yes, it\u2019s truly that simple!<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To provide a more practical example, I\u2019ll refer to my <a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/04\/wio-terminal-arduino-customisable-timer-with-code\/\">Wio Terminal Customisable Timer<\/a> project. In that sketch, I wanted to implement a countdown timer that essentially must do four things simultaneously.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ol class=\"wp-block-list\"><li>Display the time remaining in minutes and seconds<\/li><li>Show progress in the form of a bar that is gradually filled<\/li><li>Provide the ability to interrupt the countdown with a keypress<\/li><li>Keep the time for eventually ending the timer<\/li><\/ol>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/03\/ezgif.com-video-to-gif-2.gif\" alt=\"\" class=\"wp-image-41755\" width=\"599\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now then, let\u2019s take a look at the code.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>long start_millis = millis();\nint progress, t_min, t_sec;\nlong seconds_elapsed = 0;\nlong seconds_remain;\n\nwhile(seconds_elapsed&lt;duration &amp;&amp; clicker_state == 0) {\n    seconds_elapsed = (millis() - start_millis)\/1000;\n    seconds_remain = duration - seconds_elapsed;\n    t_min = seconds_remain\/60;\n    t_sec = seconds_remain%60;\n    \n    \n    ttext.setCursor(0, 0);\n    ttext.setTextColor(0xFFE0, 0);\n    ttext.setTextSize(3);\n    ttext.printf(\"%02d:%02d\", t_min, t_sec);\n    ttext.pushSprite(220,200);\n\n    progress = 200*seconds_elapsed\/duration;\n    tft.fillRoundRect(10, 210, progress, 10, 4, TFT_WHITE);\n\n    if (digitalRead(WIO_5S_PRESS) == LOW) {\n        clicker_state = 1;\n        skipped_timer = true;\n    }\n}\nclicker_state = 0;<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The two key things to note in the above is the use of millis() and clicker_state. While you could technically use delay(1000) and simply decrement the number of seconds remaining, the real problem comes in when you want to introduce the ability to interrupt the timer.<\/p>\n\n\n\n<p>Remember, during a delay(), we can\u2019t provide any inputs. Even if we wrote a statement to check for the button press at decrement, the exit condition would only be checked for a split second every second. In this case, it\u2019s nearly impossible for the user to break out of the loop.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Scale Arduino Multitasking with Object Oriented Programming<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In the previous section, I mentioned how the addition of another LED simply required us to duplicate some portions of the code. To add even more devices, we could simply copy and paste that code as many times as we needed. The downside is that our sketch would get fairly long, and programmers don\u2019t like long code where it can be avoided. Cleaner code also means a smaller program, which translates to more precious space saved on our Arduino!<\/p>\n\n\n\n<p>Fortunately, C++ based Arduino code supports Object Oriented Programming (OOP), which allows us to package all the code that we reuse for each LED into a paradigm or framework known as a <strong>class<\/strong>.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This is actually quite simple to do. To start write our own class, we will need:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>a class <strong>constructor<\/strong>,<\/li><li>some member <strong>variables<\/strong>,<\/li><li>and class <strong>methods<\/strong> (or functions).<\/li><\/ul>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>First, we declare a class <strong>blinkingLED<\/strong> and include some variables. These are the same as the ones that we used previously.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>class blinkingLED {\n  int ledPin;\n  int ledState = LOW;\n  long duration;\n  unsigned long millisMarker;\n};<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The next step is to create a class constructor. A constructor is a function that is called to <strong>instantiate<\/strong> or create an object of that class. It has the same name as our class, and typically carries several input parameters so that we can define some characteristics of the particular object that we are creating.<\/p>\n\n\n\n<p>In the constructor below, we are defining the PIN and the duration of our ledFlasher object, while initialising its variables.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>class blinkingLED {\n  int ledPin;\n  int ledState = LOW;\n  long duration;\n  unsigned long millisMarker;\n\n\n  public:\n  blinkingLED(int pin, long interval){\n    ledPin = pin;\n    pinMode(ledPin, OUTPUT);\n\n    duration = interval;\n    millisMarker = 0;\n  };\n};<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Still with me? Good. The next and final step of building our class is to define a method that toggles LED states and updates PIN outputs!<\/p>\n\n\n\n<p>While we\u2019re at it, we\u2019ll also update our setup() and loop() functions to take advantage of our hard work! First, we add the declarations for each LED by instantiating a class for each of them, then we\u2019ll let the Update() method for each of them run continuously in our loop!<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>class blinkingLED {\n  int ledPin;\n  int ledState = LOW;\n  long duration;\n  unsigned long millisMarker;\n\n\n  public:\n  blinkingLED(int pin, long interval){\n    ledPin = pin;\n    pinMode(ledPin, OUTPUT);\n\n    duration = interval;\n    millisMarker = 0;\n  };\n\n\n  void Update() {\n    digitalWrite(ledPin, ledState);\n\n    if ( (millis() - millisMarker) &gt; duration) {\n      millisMarker = millis();\n      if (ledState == LOW) {\n        ledState = HIGH;\n      } else if (ledState == HIGH) {\n        ledState = LOW;\n      }\n    }\n  }\n};\n\nblinkingLED LED1(12, 1000);\nblinkingLED LED2(13, 2000);\n\nvoid setup() {\n}\n\nvoid loop() {\n  LED1.Update();\n  LED2.Update();\n}<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And there we have it &#8211; code that does the exact same thing as before! Except, if we wanted to add a third, fourth or fifth LED, each of them would only require us to add <strong>just two more lines of code!<\/strong><\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Achieve Arduino Multitasking with RTOS<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Using millis() will suffice for keeping time in most Arduino programs. However, there are other options to explore as well &#8211; one being RTOS.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What is RTOS and How does It Work?<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>RTOS stands for Real Time Operating System, and is one of the most important components of today\u2019s embedded systems. RTOS is designed to provide predictable execution of programs, and is usually very lightweight.<\/p>\n\n\n\n<p>RTOS works through a kernel, which is a core component in operating systems like Linux. Each program being executed is a task (or thread) that is controlled by the operating system. If an operating system can perform multiple tasks this way, it can be said to be <strong>multitasking<\/strong>.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Multitasking &amp; Scheduling<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Traditionally, processors can only execute one task at a time, but an operating system can make each task appear to execute simultaneously by quickly switching between them.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/JarGgWCWjnCAGgKZKrgNrJFb0-mho95XBlJdUHU5-ZYiSiHYY9oP-BJEg9G3x5Z76ES4CnDgDDOT4dpdTAO3ns4t648qAoQVR3bNuKkS1EMkr_k5y5XGBbP2VH4BRVvBzgA4uiNH\" alt=\"\" width=\"600\"\/><figcaption><em>Source: FreeRTOS<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>For an operating system to decide how to switch between tasks, it uses a <strong>scheduler<\/strong>, which is responsible for deciding which tasks to execute at any given time. It is also important to note that a given task can be paused and resumed multiple times throughout its life cycle.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Tutorial: Multitasking an Arduino with FreeRTOS<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In this section, I\u2019m going to show you how you can achieve multitasking with FreeRTOS. <a href=\"https:\/\/www.freertos.org\/index.html\">FreeRTOS<\/a> is a well known operating system in the IoT RTOS scene and has been extensively developed for more than a decade. Specially developed for microcontrollers, FreeRTOS features a low memory footprint and power optimisation features.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Required Materials<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To follow along, you can use any of the microcontroller boards developed by Seeed that are based on the SAMD microchip, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.seeedstudio.com\/Wio-Terminal-p-4509.html\">Wio Terminal<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html\">Seeeduino XIAO<\/a><\/li><li>Seeeduino Zero Series:<ul><li><a href=\"https:\/\/www.seeedstudio.com\/Seeeduino-Cortex-M0-p-4070.html\">Seeeduino Cortex-M0+<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/Seeeduino-Lotus-Cortex-M0-p-2896.html\">Seeeduino Lotus Cortex-M0+<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/Wio-Lite-W600-p-4155.html\">Wio Lite W600 &#8211; ATSAMD21 Cortex-M0 Wireless Development Board<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/Wio-Lite-MG126-p-4189.html\">Wio Lite MG126 &#8211; ATSAMD21 Cortex-M0 Blue Wireless Development Board<\/a><\/li><\/ul><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/Seeeduino-LoRaWAN-p-2780.html\">Seeeduino LoRaWAN<\/a><\/li><\/ul>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Quick Start with FreeRTOS For Arduino<\/strong><\/h3>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Step 1: <\/strong>Download the <a href=\"https:\/\/github.com\/Seeed-Studio\/Seeed_Arduino_FreeRTOS\">Seeed_Arduino_FreeRTOS<\/a> repository as a ZIP file.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Step 2:<\/strong> Install the ZIP file as a library through the <a href=\"https:\/\/www.arduino.cc\/en\/software\">Arduino IDE<\/a>. Please <a href=\"https:\/\/wiki.seeedstudio.com\/How_to_install_Arduino_Library\/\">check here<\/a> for detailed instructions.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Step 3: <\/strong>Copy the following code into a new sketch and upload it to your Arduino board.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;Seeed_Arduino_FreeRTOS.h&gt;\n \nTaskHandle_t Handle_aTask;\nTaskHandle_t Handle_bTask;\n \nstatic void ThreadA(void* pvParameters) {\n    Serial.println(\"Thread A: Started\");\n \n    while (1) {\n        Serial.println(\"Hello World!\");\n        delay(1000);\n    }\n}\n \nstatic void ThreadB(void* pvParameters) {\n    Serial.println(\"Thread B: Started\");\n \n    for (int i = 0; i &lt; 10; i++) {\n        Serial.println(\"---This is Thread B---\");\n        delay(2000);\n    }\n    Serial.println(\"Thread B: Deleting\");\n    vTaskDelete(NULL);\n}\n \nvoid setup() {\n \n    Serial.begin(115200);\n \n    vNopDelayMS(1000); \/\/ prevents usb driver crash on startup, do not omit this\n    while(!Serial);  \/\/ Wait for Serial terminal to open port before starting program\n \n    Serial.println(\"\");\n    Serial.println(\"******************************\");\n    Serial.println(\"        Program start         \");\n    Serial.println(\"******************************\");\n \n    \/\/ Create the threads that will be managed by the rtos\n    \/\/ Sets the stack size and priority of each task\n    \/\/ Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks\n    xTaskCreate(ThreadA,     \"Task A\",       256, NULL, tskIDLE_PRIORITY + 2, &amp;Handle_aTask);\n    xTaskCreate(ThreadB,     \"Task B\",       256, NULL, tskIDLE_PRIORITY + 1, &amp;Handle_bTask);\n \n    \/\/ Start the RTOS, this function will never return and will schedule the tasks.\n    vTaskStartScheduler();\n}\n \nvoid loop() {\n    \/\/ NOTHING\n}<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Step 4:<\/strong> Open the Serial Monitor on the Arduino IDE and watch the magic happen!<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This Hello World Example creates two threads that print different strings to the Serial Monitor at a different rate.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li>Thread A prints \u201cHello World\u201d,<\/li><li>while Thread B prints \u201c&#8212;This is Thread B&#8212;\u201d!<\/li><\/ul>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And that concludes this quick tutorial!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>FreeRTOS For Arduino Multitasking: More Examples<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>You can also do similarly exciting Arduino multitasking with FreeRTOS, such as blinking and fading different LEDs simultaneously, or update elements on an LCD display separately! For more details on these examples, I strongly encourage you to visit the full demonstration and code on the <a href=\"https:\/\/wiki.seeedstudio.com\/Software-FreeRTOS\/\">Seeed Wiki page<\/a>!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"700\" height=\"395\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/03\/Blink.gif\" alt=\"\" class=\"wp-image-41756\"\/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"700\" height=\"408\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/03\/FreeRTOS-LCD.gif\" alt=\"\" class=\"wp-image-41757\"\/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping Up<\/strong><\/h2>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Thanks for reading this Multitasking with Arduino guide! To summarise, we\u2019ve covered the pitfalls of delay() and how multitasking can be achieved by using millis() and the concept of state machines. In addition, we\u2019ve also gotten our toes wet with a little bit of FreeRTOS!<\/p>\n\n\n\n<p>Nonetheless, these are no more than tools and methods to be used in your projects. Why not pick up an Arduino project for yourself to put your newfound skills to the test?<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>For more resources, be sure to check out the following links!<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2020\/01\/16\/20-awesome-arduino-projects-that-you-must-try-2020\/\">20 Awesome Arduino Projects That You Must Try 2021!<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/03\/10\/13-arduino-led-projects-you-need-to-try\/\">13 Arduino LED Projects you need to try!<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/01\/19\/tiny-ml-with-wio-terminal-1-intro\/\">Learn TinyML using Wio Terminal and Arduino IDE #1 Intro<\/a><\/li><li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/04\/wio-terminal-arduino-customisable-timer-with-code\/\">Wio Terminal: Arduino Customisable Timer (with Code!)<\/a><\/li><\/ul>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Arduino microcontrollers are a beginner friendly and low cost platform for electronics and programming. They\u2019re<\/p>\n","protected":false},"author":3537,"featured_media":41779,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_tribe_ticket_capacity":"0","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"iawp_total_views":0,"footnotes":""},"categories":[1],"tags":[6,1109,3755,2227,3757,1385,3753,1288,2982,3003],"class_list":["post-41754","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","tag-arduino","tag-arduino-beginner","tag-arduino-multitasking","tag-arduino-projects","tag-arduino-rtos","tag-freertos","tag-real-time-operating-system","tag-rtos","tag-seeeduino-xiao","tag-wio-terminal"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Multitasking with Arduino - Millis(), RTOS &amp; More! - Latest News from Seeed Studio<\/title>\n<meta name=\"description\" content=\"Take your microcontroller programming to the next level by achieving multitasking with Arduino. This article covers millis(), RTOS, and more!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Multitasking with Arduino - Millis(), RTOS &amp; More! - Latest News from Seeed Studio\" \/>\n<meta property=\"og:description\" content=\"Take your microcontroller programming to the next level by achieving multitasking with Arduino. This article covers millis(), RTOS, and more!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/\" \/>\n<meta property=\"og:site_name\" content=\"Latest News from Seeed Studio\" \/>\n<meta property=\"article:published_time\" content=\"2021-05-11T07:30:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-09-29T08:18:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1493\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jonathan Tan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jonathan Tan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/\",\"url\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/\",\"name\":\"Multitasking with Arduino - Millis(), RTOS & More! - Latest News from Seeed Studio\",\"isPartOf\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg\",\"datePublished\":\"2021-05-11T07:30:53+00:00\",\"dateModified\":\"2021-09-29T08:18:31+00:00\",\"author\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094\"},\"description\":\"Take your microcontroller programming to the next level by achieving multitasking with Arduino. This article covers millis(), RTOS, and more!\",\"breadcrumb\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#primaryimage\",\"url\":\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg\",\"contentUrl\":\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg\",\"width\":2560,\"height\":1493},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.seeedstudio.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Multitasking with Arduino &#8211; Millis(), RTOS &#038; More!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#website\",\"url\":\"https:\/\/www.seeedstudio.com\/blog\/\",\"name\":\"Latest News from Seeed Studio\",\"description\":\"Emerging IoT, AI and Autonomous Applications on the Edge\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.seeedstudio.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094\",\"name\":\"Jonathan Tan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g\",\"caption\":\"Jonathan Tan\"},\"url\":\"https:\/\/www.seeedstudio.com\/blog\/author\/jonathan-tan\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Multitasking with Arduino - Millis(), RTOS & More! - Latest News from Seeed Studio","description":"Take your microcontroller programming to the next level by achieving multitasking with Arduino. This article covers millis(), RTOS, and more!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/","og_locale":"en_US","og_type":"article","og_title":"Multitasking with Arduino - Millis(), RTOS & More! - Latest News from Seeed Studio","og_description":"Take your microcontroller programming to the next level by achieving multitasking with Arduino. This article covers millis(), RTOS, and more!","og_url":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/","og_site_name":"Latest News from Seeed Studio","article_published_time":"2021-05-11T07:30:53+00:00","article_modified_time":"2021-09-29T08:18:31+00:00","og_image":[{"width":2560,"height":1493,"url":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg","type":"image\/jpeg"}],"author":"Jonathan Tan","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jonathan Tan","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/","url":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/","name":"Multitasking with Arduino - Millis(), RTOS & More! - Latest News from Seeed Studio","isPartOf":{"@id":"https:\/\/www.seeedstudio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#primaryimage"},"image":{"@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#primaryimage"},"thumbnailUrl":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg","datePublished":"2021-05-11T07:30:53+00:00","dateModified":"2021-09-29T08:18:31+00:00","author":{"@id":"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094"},"description":"Take your microcontroller programming to the next level by achieving multitasking with Arduino. This article covers millis(), RTOS, and more!","breadcrumb":{"@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#primaryimage","url":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg","contentUrl":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg","width":2560,"height":1493},{"@type":"BreadcrumbList","@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/05\/11\/multitasking-with-arduino-millis-rtos-more\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.seeedstudio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Multitasking with Arduino &#8211; Millis(), RTOS &#038; More!"}]},{"@type":"WebSite","@id":"https:\/\/www.seeedstudio.com\/blog\/#website","url":"https:\/\/www.seeedstudio.com\/blog\/","name":"Latest News from Seeed Studio","description":"Emerging IoT, AI and Autonomous Applications on the Edge","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.seeedstudio.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094","name":"Jonathan Tan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g","caption":"Jonathan Tan"},"url":"https:\/\/www.seeedstudio.com\/blog\/author\/jonathan-tan\/"}]}},"modified_by":"Lily","views":34803,"featured_image_urls":{"full":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg",2560,1493,false],"thumbnail":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--80x80.jpg",80,80,true],"medium":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--300x175.jpg",300,175,true],"medium_large":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--768x448.jpg",640,373,true],"large":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1030x601.jpg",640,373,true],"1536x1536":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1536x896.jpg",1536,896,true],"2048x2048":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--2048x1195.jpg",2048,1195,true],"visody_icon":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--scaled.jpg",32,19,false],"magazine-7-slider-full":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1536x1020.jpg",1536,1020,true],"magazine-7-slider-center":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--936x897.jpg",936,897,true],"magazine-7-featured":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--1024x597.jpg",1024,597,true],"magazine-7-medium":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--720x380.jpg",720,380,true],"magazine-7-medium-square":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/03\/Week-8--675x450.jpg",675,450,true]},"author_info":{"display_name":"Jonathan Tan","author_link":"https:\/\/www.seeedstudio.com\/blog\/author\/jonathan-tan\/"},"category_info":"<a href=\"https:\/\/www.seeedstudio.com\/blog\/category\/news\/\" rel=\"category tag\">News<\/a>","tag_info":"News","comment_count":"0","_links":{"self":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts\/41754","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/users\/3537"}],"replies":[{"embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/comments?post=41754"}],"version-history":[{"count":20,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts\/41754\/revisions"}],"predecessor-version":[{"id":42754,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts\/41754\/revisions\/42754"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/media\/41779"}],"wp:attachment":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/media?parent=41754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/categories?post=41754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/tags?post=41754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}