Blink a LED without sleep

Dieses Lab zeigt Ihnen wie sie eine LED mit dem Microcontroller blinken lassen können, ohne sleep zu verwenden.

Vorkenntnisse:

Ziel:

  • Nicht blockierendes Blinken einer LED

Rückblick

Im Lab 6.1 habenm wir gesehen wie wir eine LED blinken lassen können.

Wir wollen nun mehrere LEDs in unterschiedlicher Geschwindigkeit blinken lassen, dazu wollen wir die Funktionalität zunächst in eine eigene Funktion namens blink kapseln. Das könnte zum Beispiel so aussehen.

import time
from machine import Pin

led1_pin = Pin(18, Pin.OUT)

def blink(led, delay_time):
  led.value(not led.value())
  time.sleep(delay_time)

while True:
  blink(led1_pin, 0.5)

Task

Fügen Sie eine weitere LED hinzu die im Takt von 700ms blinken soll.
👉 blink(led2_pin, 0.7)

Welche Beobachtung können Sie machen?

Solution

import time
from machine import Pin

def blink(led, delay_time):
  led.value(not led.value())
  time.sleep(delay_time)

led1_pin = Pin(18, Pin.OUT)
led2_pin = Pin(19, Pin.OUT)

while True:
  blink(led1_pin, 0.5)
  blink(led2_pin, 0.7)

⭐ Wokwi

Beobachtung

Wie sie vlt festgestellt haben blinken die beiden LEDs hintereinander anstatt parallel, dies liegt daran dass die Funktion sleep die MCU daran hindert in dieser Zeit weiter zu arbeiten. Man spricht hier auch von einer blockierenden Funktion.

Nicht blockierendes Blinken einer LED

Probieren Sie anstatt dessen folgendes Programm

from machine import Pin
import time

led1_pin = Pin(18, Pin.OUT)
led2_pin = Pin(19, Pin.OUT)

last_ticks_led1 = 0
last_ticks_led2 = 0

BLINK_TIME_LED1 = 500
BLINK_TIME_LED2 = 700


def blink(led, last_ticks, blink_time):
    current_ticks = time.ticks_ms()
    if time.ticks_diff(current_ticks, last_ticks) > blink_time:
        led.value(not led.value())
        last_ticks = current_ticks
    return last_ticks  # needs to be saved in last_ticks for the led


while True:
    last_ticks_led1 = blink(led1_pin, last_ticks_led1, BLINK_TIME_LED1)
    last_ticks_led2 = blink(led2_pin, last_ticks_led2, BLINK_TIME_LED2)

    # still time to do something else.

Alternative ohne Funktion

from machine import Pin
import time

led1_pin = Pin(18, Pin.OUT)
led2_pin = Pin(19, Pin.OUT)

last_ticks_led1 = 0
last_ticks_led2 = 0

BLINK_TIME_LED1 = 500
BLINK_TIME_LED2 = 700

while True:
    current_ticks = time.ticks_ms()

    # blink led 1
    if time.ticks_diff(current_ticks, last_ticks_led1) > BLINK_TIME_LED1:
        led1_pin.value(not led1_pin.value())
        last_ticks_led1 = current_ticks

    # blink led 2
    if time.ticks_diff(current_ticks, last_ticks_led2) > BLINK_TIME_LED2:
        led2_pin.value(not led2_pin.value())
        last_ticks_led2 = current_ticks

    # still time to do something else.

Task

Beschreiben Sie in eigenen Worten wie das Programm funktioniert und warum dies nicht blockierend ist.

Hinweis: eine weitere Möglichkeit für eine nicht blockierende Lösung sehen Sie im Lab Timers.

Kontrollfragen

  1. Welches Problem kann sich durch die Verwendung von sleep zum blinken ergeben?
  2. Was versteht man unter dem Begriff blockierende Funktion?
  3. Welchen Wert gibt die Funktion time.tick_ms() zurück.
  4. Mit welcher Funktion können Sie berechnen wie viel Zeit seit einem gemessenen Zeitpunkt vergangen ist?

Übungsaufgabe

  1. Schreiben Sie ein Programm welches eine LED im Intervall von 250ms blinken lässt ohne sleep zu verwenden.