Anleitung: Von der blinkenden LED zur Zugsteuerung

Übungen für @schorsch55 und wer sonst noch Lust hat.

Motivation: Im Thema Modellbahn-Basteleien Teil2 kam der Wunsch nach zielgerichteten Übungen auf. Ich habe sowas noch nicht gemacht, aber wer es nicht versucht, findet nicht heraus, ob es funktioniert. Ich möchte bewußt im öffentlichen Teil schreiben, eventuell gibt es ja noch mehr Nutznießer.

Lernziele: Blockadearme Programmierung; blinkende LEDs; Schrittkette; Zeitsteuerung mit millis; Strukturen und ein Datenfeld aus Strukturen. Änderungen sind möglich!


Übung 1:

Lernziele: Lokale Variablen.

Aufgabe: Laß eine LED blinken, ohne delay() zu verwenden. Ergänze das folgende Programm nur im markierten Bereich:

const uint8_t ledPin = 13;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blinken();
}

void blinken()
{
  // bitte nur hier ergänzen
}

Auf geht's, viel Spaß!

2 Likes

Laß eine LED blinken, ohne delay() zu verwenden. Ergänze das folgende Programm nur im markierten Bereich

erfindest du das Rad neu?

Die Übung heißt "Lernziele: Lokale Variablen" und sollte daher evtl. den Begriff static verwenden.

Nein, aber es hilft, Blink Without Delay zu kennen und verstanden zu haben.

Leider habe ich überhaupt keine Ahnung von Modellbahnen und dem zugehörigen Hobby.

Aber über statische Variablen könne ich evtl. einen Grundlagen Absatz liefern....

Die Analogie zwischen einer aufblendenden LED und einer beschleunigenden Lok bekommst Du schon noch hin :slightly_smiling_face:

Eine theoretische Nachbereitung, auch ne Idee, ich pinge Dich an :thinking:

OK.. nicht so sicher über den Mehrwert.

https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/scope/

https://www.arduino.cc/reference/en/language/variables/variable-scope-qualifiers/static/

ich finde die Übung auf Basis von BlinkWithoutDelay gut.
Das ist etwas was ein Anfänger verstehen und anwenden kann.

Jetzt bräuchte es nur noch einen Anfänger der die Übung auch ausführt.
@schorsch55 - wie läuft es?

bitte nur hier ergänzen = digitalWrite(ledPin, millis() / 500 % 2); :nerd_face:

oder schneller zu berechnen (512 statt 500)

digitalWrite(ledPin, (millis() & 0x200)>>9);

oder für Puristen
digitalWrite(ledPin, (millis() & 0x200) ? HIGH : LOW );
:innocent: :grimacing:

1 Like

Leute, hier geht's los. Ich fange dann mal mit meinen Versuchen an, Lachen und positive Kritik sind erlaubt.

const uint8_t ledPin = 13;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blinken2();
}

void blinken()
{
  // die klassische Version
  digitalWrite(ledPin, HIGH);
  delay(300);
  digitalWrite(ledPin, LOW);
  delay(300);
}
void blinken2()
// mit ohne delay
{
  unsigned long anfang = 0;
  const unsigned long warte = 100;
  anfang = millis();
  digitalWrite(ledPin, HIGH);
  while (millis() - anfang <= warte);
  digitalWrite(ledPin, LOW);
}

Sollte besonders elegant werden, schon gehts nicht, irgendwo ein Denkfehler. Bei den Motoren gings???

schau dir mal den orginalen "BlinkWithoutDelay" an. Hast da ein While? Nein.

Schau dir an, was dort an "globalen" Variablen verbraucht wird, und überlege dir, welche dieser Variablen du nur in der Funktion blinken3() brauchen würdest...

Lies die beiden Links in Beitrag #7

Persönliche Betreuung :innocent:


Sehr spannend, darauf war ich nicht vorbereitet:
while (millis() - anfang <= warte);
Daher habe ich bei den Lernzielen noch blockadearme Programmierung ergänzt. Also kein delay, kein blockierendes while oder for. Doch dazu später :grinning:

Wenn ich die beiden Funktionen vergleiche, so blockiert delay zweimal, while aber nur einmal. Da fehlt also noch was, oder?

1 Like

Du hast es erfasst. Also Sinn der Übung schon von Erfolg gekrönt.
Nu hab ich ein wenig Angst, das ich @agmue reinfummel...
Das schon angesprochene blink-without-delay-Beispiel mag geeignet sein um das blinken hinzubekommen.
Auch die - sicher gut gemeinten - Abkürzungen machen das blinken, aber das ist ja nicht Ziel der Übung:

Und das Blockadefrei.
Kein delay() - oder die Alternative while() - bis die Zeit abgelaufen ist...

Damit hast Du wunderbar das nachgebaut, was delay() macht.

Hier noch ein kleiner Schubs hoffentlich in die richtige Richtung (@agmue bitte pfeif mich zurück wenn es nicht ins Konzept passt). Außerhalb Deines Codes sieht es sinngemäß so aus:

setup();
while(1) {
  loop();
}

Gut, ich schreibe immer, wie ich es verstehe. Globale Variablen werden noch vor dem Setup deklariert und gelten überall, also auch in eigenen Funktionen etc. Lokale werden im loop oder in einer eigenen Funktion deklariert und gelten nur dort. Static legt an, bleibt am Ende vom Loop erhalten. Sollte ich schon mal nehmen?
while hatte ich schon benutzt, deshalb...
Habe jetzt umgeschrieben, geht mit blinken3

Wie jetzt, bin ich nicht genial :shushing_face: Und ich war so froh, dass ich es bei meinen Motoren hingekriegt habe, dazu später
@J-M-L und @paulpaulson , das ist noch (noch) zu hoch, da will ich erst noch hin. Hier Lösung 2 (habe bewusst den "Müll" drin gelassen)


[code]
const uint8_t ledPin = 13;
int ledStatus = LOW;
unsigned long anfang = 0;
const unsigned long warte = 100;
void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blinken3();
}

void blinken()
{
  // die klassische Version
  digitalWrite(ledPin, HIGH);
  delay(300);
  digitalWrite(ledPin, LOW);
  delay(300);
}
void blinken2()
// mit ohne delay
{
  unsigned long anfang = 0;
  const unsigned long warte = 100;
  anfang = millis();
  digitalWrite(ledPin, HIGH);
  while (millis() - anfang <= warte);
  digitalWrite(ledPin, LOW);
}
void blinken3()
{
  unsigned long currentMillis = millis();
  if (currentMillis - anfang >= warte)
  {
    anfang = currentMillis;
    if (ledStatus == LOW)
    {
      ledStatus = HIGH;
    }
    else
    {
      ledStatus = LOW;
    }
    digitalWrite(ledPin, ledStatus);
  }
}
[/code]

1 Like

Hier gibt es einen passenderen Typ.

Das dann bitte noch mit lokalen Variablen/Konstanten realisieren.

Ja :slightly_smiling_face:

Find ich gut.
Hab ich auch schon gemacht.
Damit kommen Nachfolgende evtl. auch darauf, wie sich Code und somit das Ergebnis entwickelt hat.

dafür static bool ledStatus?? Zumindest gehts.
Das mit lokal, mmmh. Ich habe die Deklaration in den loop genommen, nix blinkt. Lesen der Grundsätze lokal7global hat mir nichts Neues gebracht