{"id":8960,"date":"2025-02-06T15:29:56","date_gmt":"2025-02-06T15:29:56","guid":{"rendered":"https:\/\/sites.hslu.ch\/werkstatt\/?p=8960"},"modified":"2025-02-07T16:49:46","modified_gmt":"2025-02-07T16:49:46","slug":"arduino-basics-delay-vs-millis","status":"publish","type":"post","link":"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/","title":{"rendered":"Arduino Basics: Delay vs. Millis"},"content":{"rendered":"<div class=\"wpb-content-wrapper\"><p>[vc_section el_class=&#187;dkw-section-lead&#187;][vc_row][vc_column width=&#187;2\/3&#8243; offset=&#187;vc_col-sm-offset-2&#8243;][vc_column_text css=&#187;&#187;]Wenn du mit einem Arduino erste Programme schreibst ist dir delay() wohl ein Begriff. Manchmal ist diese Pause f\u00fcr ein Programm aber nicht sehr f\u00f6rderlich. An dem Beispiel eines studentischen Projekts erkl\u00e4ren wir dir kurz was der Unterschied des Pausierens in einem Programm durchlauf ist und weshalb diese Art des Pause machens hilfreich sein kann.[\/vc_column_text][\/vc_column][\/vc_row][\/vc_section][vc_section el_class=&#187;dkw-section-content&#187;][vc_row][vc_column width=&#187;1\/3&#8243; el_class=&#187;dkw-col-toc&#187; offset=&#187;vc_col-lg-3&#8243;][vc_column_text]<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Kurz_erklaert_delay\" >Kurz erkl\u00e4rt: delay()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Kurz_erklaert_millis\" >Kurz erkl\u00e4rt: millis()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Videotutorial\" >Videotutorial<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Ein_praktisches_Beispiel\" >Ein praktisches Beispiel<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Beispiel_delay\" >Beispiel delay()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Beispiel_millis\" >Beispiel millis()<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/sites.hslu.ch\/werkstatt\/arduino-basics-delay-vs-millis\/#Fazit\" >Fazit<\/a><\/li><\/ul><\/nav><\/div>\n[\/vc_column_text][\/vc_column][vc_column width=&#187;2\/3&#8243; el_class=&#187;dkw-col-content&#187; offset=&#187;vc_col-lg-6&#8243;][vc_column_text css=&#187;&#187;]<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Kurz_erklaert_delay\"><\/span>Kurz erkl\u00e4rt: delay()<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><a href=\"https:\/\/reference.arduino.cc\/reference\/en\/language\/functions\/time\/delay\/\">Arduino Reference delay()<\/a><\/p>\n<p>Wenn wir einen Arduino programmieren, verwenden wir oft delay() f\u00fcr kurze Pausen. Das delay() h\u00e4lt das Programm an einem bestimmten Punkt an und setzt es fort, wenn die Zeit abgelaufen ist. Dies kann sehr n\u00fctzlich und gut genug f\u00fcr einfache Skizzen sein. Zum Beispiel in dem bekannten Blink Sketch:<\/p>\n<pre>void setup() {\r\n\/\/ initialize digital pin LED_BUILTIN as an output.\r\npinMode(LED_BUILTIN, OUTPUT);\r\n}\r\n\r\nvoid loop() {\r\ndigitalWrite(LED_BUILTIN, HIGH); \/\/ turn the LED on (HIGH is the voltage level)\r\ndelay(1000); \/\/ wait for a second\r\ndigitalWrite(LED_BUILTIN, LOW); \/\/ turn the LED off by making the voltage LOW\r\ndelay(1000); \/\/ wait for a second\r\n}<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Kurz_erklaert_millis\"><\/span>Kurz erkl\u00e4rt: millis()<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><a href=\"https:\/\/reference.arduino.cc\/reference\/en\/language\/functions\/time\/millis\/\">Arduino Reference millis()<\/a><\/p>\n<p><a href=\"https:\/\/docs.arduino.cc\/built-in-examples\/digital\/BlinkWithoutDelay\/\">Arduino Example Blink without delay()<\/a><\/p>\n<p>Manchmal m\u00f6chte man das Programm aktiv halten und kann nicht warten, bis ein delay() seine Pause beendet hat. Zum Beispiel kann man eine LED blinken lassen, w\u00e4hrend man einen Tastendruck ausliest. In diesem Fall kann man delay() nicht verwenden, da Arduino das Programm w\u00e4hrend delay() pausiert. Wenn der Knopf gedr\u00fcckt wird, w\u00e4hrend Arduino pausiert und auf das Ende von delay() wartet, verpasst das Programm den Knopfdruck.<\/p>\n<p>Derselbe Blinksketch sieht mit millis() etwas komplizierter aus, f\u00fchrt aber von aussen betrachtet zum selben Verhalten wie der delay() Blinksketch: Er l\u00e4sst die LED 1x pro Sekunde blinken. Aber der Sketch pausiert nicht und der Loop bietet die M\u00f6glichkeit, weitere Befehle auszuf\u00fchren. Im folgenden Beispiel haben wir einen Loopcounter eingef\u00fcgt, der die Loops z\u00e4hlt und alle 100 Loops einen Serialprint ausgibt:<\/p>\n<pre>\/\/ constants won't change. Used here to set a pin number:\r\nconst int ledPin = LED_BUILTIN; \/\/ the number of the LED pin\r\n\r\n\/\/ Variables will change:\r\nint ledState = LOW; \/\/ ledState used to set the LED\r\nunsigned long loopCounter = 0; \/\/ counter for loop iterations\r\n\r\n\/\/ Generally, you should use \"unsigned long\" for variables that hold time\r\n\/\/ The value will quickly become too large for an int to store\r\nunsigned long previousMillis = 0; \/\/ will store last time LED was updated\r\n\r\n\/\/ constants won't change:\r\nconst long interval = 1000; \/\/ interval at which to blink (milliseconds)\r\n\r\nvoid setup() {\r\n\/\/ set the digital pin as output:\r\npinMode(ledPin, OUTPUT);\r\n\/\/ Initialize serial communication at 9600 baud:\r\nSerial.begin(9600);\r\n}\r\n\r\nvoid loop() {\r\n\/\/ Increment the loop counter\r\nloopCounter++;\r\n\r\n\/\/ Print the counter every 100 iterations to avoid flooding the serial monitor\r\nif (loopCounter % 100 == 0) {\r\nSerial.print(\"Loop count: \");\r\nSerial.println(loopCounter);\r\n}\r\n\r\n\/\/ here is where you'd put code that needs to be running all the time.\r\nunsigned long currentMillis = millis();\r\n\r\nif (currentMillis - previousMillis &gt;= interval) {\r\n\/\/ save the last time you blinked the LED\r\npreviousMillis = currentMillis;\r\n\r\n\/\/ if the LED is off turn it on and vice-versa:\r\nif (ledState == LOW) {\r\nledState = HIGH;\r\n} else {\r\nledState = LOW;\r\n}\r\n\r\n\/\/ set the LED with the ledState of the variable:\r\ndigitalWrite(ledPin, ledState);\r\n}\r\n}<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Videotutorial\"><\/span>Videotutorial<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Es gibt viele Video-Tutorials, die das ganze Verfahren im Detail erkl\u00e4ren, ein guter Einstieg ist diese Serie hier:[\/vc_column_text][vc_video link=&#187;<a href=\"https:\/\/youtu.be\/BYKQ9rk0FEQ&#038;#187\" rel=\"nofollow\">https:\/\/youtu.be\/BYKQ9rk0FEQ&#038;#187<\/a>; css=&#187;&#187;][vc_column_text css=&#187;&#187;]<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Ein_praktisches_Beispiel\"><\/span>Ein praktisches Beispiel<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><a href=\"https:\/\/github.com\/MediaDock\/delay-vs.-millis\">Github Code Download<\/a><\/p>\n<p>In einer studentischen Arbeit haben wir 3 Ultraschall-Distanzsensoren verwendet, um 3 Events auszul\u00f6sen. Wenn ein Sensor ausgel\u00f6st wird, leuchtet eine LED f\u00fcr eine bestimmte Zeit und \u00fcber die keyboard() Funktion wird ein Befehl an Touchdesigner gesendet um eine Sounddatei auszul\u00f6sen. Im beigef\u00fcgten Beispiel wollten wir die Sensoren aktiv halten, um eventuell andere Events parallel ausl\u00f6sen zu k\u00f6nnen.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8973\" src=\"https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-1000x576.png\" alt=\"\" width=\"1000\" height=\"576\" srcset=\"https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-1000x576.png 1000w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-768x442.png 768w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-1536x885.png 1536w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-2048x1180.png 2048w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-848x488.png 848w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-1140x657.png 1140w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-1170x674.png 1170w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-1920x1106.png 1920w, https:\/\/sites.hslu.ch\/werkstatt\/wp-content\/uploads\/sites\/13\/2025\/02\/ArduinoMicroPro_3UltrasonicSensors-600x346.png 600w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<h4><span class=\"ez-toc-section\" id=\"Beispiel_delay\"><\/span>Beispiel delay()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>In Codebeispiel <a class=\"Link--primary\" title=\"Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Delay.ino\" href=\"https:\/\/github.com\/MediaDock\/delay-vs.-millis\/blob\/main\/Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Delay\/Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Delay.ino\" aria-label=\"Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Delay.ino, (File)\">Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Delay.ino<\/a> wird ein Sensor nach dem anderen ausgelesen. Wenn ein Sensor den Abstand eines Sensors unterschreitet, wird der entsprechende Prozess ausgel\u00f6st:<\/p>\n<ul>\n<li>Messzyklus beginnt<\/li>\n<li>Ein Sensorwert wird unterschritten:\n<ul>\n<li>ein Tastaturbefehl wird ausgel\u00f6st und das LED aktiviert<\/li>\n<li>eine Pause wird eingeleitet und das Programm stoppt f\u00fcr 10 Sekunden<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li>Ein neuer Messzyklus beginnt.<\/li>\n<\/ul>\n<h4><span class=\"ez-toc-section\" id=\"Beispiel_millis\"><\/span>Beispiel millis()<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>Im Codebeispiel <a class=\"Link--primary\" title=\"Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Millis.ino\" href=\"https:\/\/github.com\/MediaDock\/delay-vs.-millis\/blob\/main\/Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Millis\/Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Millis.ino\" aria-label=\"Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Millis.ino, (File)\">Arduino_Ultrasonic_Distance_Trigger_MultiSensor_Millis.ino<\/a> werden die Sensoren auch kurz aufeinander folgend ausgelesen. Wir haben aber mehr Steuerm\u00f6glichkeiten:<\/p>\n<ul>\n<li>Sensor 1 wird nur ausgelesen wenn <em>kein<\/em> Sensor-Event aktiv ist:<\/li>\n<li>Sensor 2 kann <em>auch<\/em> ausgelesen werden wenn Sensor 1 bereits ausgel\u00f6st hat aber <em>nicht<\/em> wenn Sensor 3 aktiv ist.<\/li>\n<li>Sensor 3 kann immer aktiviert werden ausser der eigene Sensor-Event 3 aktiv ist.<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Fazit\"><\/span>Fazit<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Delay() ist eine &#171;quick and dirty&#187; Variante um ein Programm zu schreiben und Pausen in Loops einzuf\u00fcgen. Wenn du einen etwas komplexeren Controller ben\u00f6tigst, der mehrere Dinge gleichzeitig tun kann, solltest du millis() verwenden. F\u00fcr gr\u00f6ssere und komplexere Arduino Projekte ist diese Variante ideal um mehrere zeitgesteuerte Events hintereinander und parallel laufen zu lassen, ohne dass dein ganzes Programm ins Stocken ger\u00e4t.[\/vc_column_text][\/vc_column][vc_column width=&#187;1\/3&#8243; el_class=&#187;dkw-col-micro&#187; offset=&#187;vc_col-lg-3&#8243;][\/vc_column][\/vc_row][\/vc_section][vc_section el_class=&#187;dkw-dontprint&#187;][vc_row disable_element=&#187;yes&#187;][vc_column][vc_column_text]\u2014 \u2014 \u2014 INFO: In beiden nachfolgenden Post Grids die passenden Recipies und die passenden Talks\u00a0 ausw\u00e4hlen \u2014 \u2014 \u2014<br \/>\n[\/vc_column_text][\/vc_column][\/vc_row][vc_row][vc_column][vc_column_text]<\/p>\n<h2>Passende Tools<\/h2>\n<p>[\/vc_column_text][vc_basic_grid post_type=&#187;ids&#187; element_width=&#187;2&#8243; gap=&#187;10&#8243; item=&#187;517&#8243; css=&#187;&#187; grid_id=&#187;vc_gid:1738946623515-20cc0f1f-064d-9&#8243; include=&#187;5175, 6538, 3514, 5329, 551, 6784, 6775, 6780&#8243;][\/vc_column][\/vc_row][\/vc_section]<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>[vc_section el_class=&#187;dkw-section-lead&#187;][vc_row][vc_column width=&#187;2\/3&#8243; offset=&#187;vc_col-sm-offset-2&#8243;][vc_column_text css=&#187;&#187;]Wenn du mit einem Arduino erste Programme schreibst ist dir delay() wohl ein Begriff. Manchmal ist diese Pause f\u00fcr ein [&hellip;]<\/p>\n","protected":false},"author":50,"featured_media":8995,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[15,11],"tags":[],"class_list":["post-8960","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mediadock","category-recipies"],"acf":[],"_links":{"self":[{"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/posts\/8960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/users\/50"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/comments?post=8960"}],"version-history":[{"count":13,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/posts\/8960\/revisions"}],"predecessor-version":[{"id":9009,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/posts\/8960\/revisions\/9009"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/media\/8995"}],"wp:attachment":[{"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/media?parent=8960"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/categories?post=8960"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sites.hslu.ch\/werkstatt\/wp-json\/wp\/v2\/tags?post=8960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}