Lektion 9: Schleifen und Datentypen

  • Hallo aus Köln,


    ich war etwas faul und habe nur 3 LED's benutzt.


    Mein Sketch funktioniert, aber hübsch ist es nicht


  • Hallo Kai,
    das war der entscheidende Tipp. Auch der Hinweis für die Deklaration der for-Schleife ist sehr gut. Werde ich mir merken. Vielen Dank!
    Viele Grüße
    Marcus

  • Es liegt sehr wahrscheinlich daran, dass Du LedPin zwei mal deklariert hast. Einmal als globale Variable (erste Zeile) und einmal als "static int LedPin" lokal in der Funktion Loop(). Diese Variable ist nur in dem Anweisungsblock von der Funktion loop() bekannt/gültig. Es ist wichtig den Gültigkeitsbereich (Scope) von Variablen zu beachten.


    Wenn Du die Funktionen blinkAuf() und blinkAb() aufrufst, werden diese die globale Variable LedPin verwenden, weil sie die lokale nicht kennen.

    Die globale LedPin Variable ist nur deklariert (dem Compiler bekannt gemacht) jedoch nicht definiert (definieren = Wert zuweisen). Also passiert irgendwas, nur mit hoher Wahrscheinlichkeit nicht das, was man erwartet. Die globale Variable ist der Grund, warum sich das Programm überhaupt compilieren lässt.

    Das ist einer der Gründe, warum globale Variablen "gefährlich" sind und man ganz schön aufpassen muss.


    In der Funktion loop() wird ausschließlich die lokale LedPin Variable definiert und verändert.


    Also arbeite entweder auch in der loop Funktion mit der globalen LedPin Variable oder schreibe deine beiden Funktionen so um, dass Du den Wert der lokalen LedPin Variable zusätzlich zum "Pausen"-Wert übergibst.


    Oder evtl. so:


    Außerdem kannst Du bei deinem Konstrukt:

    static int LedPin = 2;

    for (LedPin; LedPin < 7; LedPin++) {}


    das erste LedPin in der "for" Schleife weglassen. Es hat dort keinen Sinn, weil LedPin in einer Zeile darüber mit dem Wert 2 definiert wurde =>

     for (; LedPin < 7; LedPin++) {}


    Gruß Kai

  • Hallo zusammen,
    ich habe ein Problem mit der Einbindung eigener Funktionen die jeweils einen Parameter übernehmen. Kommentiere ich die Funktion blinkAuf () oder blinkAb () aus und füge deren Inhalte direkt in die Loop ein dann funktioniert alles. Die Schleifen laufen auch sauber durch. Dies habe ich über den seriellen Monitor überprüft. Über einen Hinweis wo ich den Fehler eingebaut habe wäre ich sehr dankbar.


    int LedPin;


    void blinkAuf (int pauseAuf){

    digitalWrite (LedPin, HIGH);

    delay(pauseAuf);

    digitalWrite (LedPin, LOW);

    }


    void blinkAb (int pauseAb){

    digitalWrite (LedPin, HIGH);

    delay(pauseAb);

    digitalWrite (LedPin, LOW);

    }


    void setup() {

    pinMode(2,OUTPUT);

    pinMode(3,OUTPUT);

    pinMode(4,OUTPUT);

    pinMode(5,OUTPUT);

    pinMode(6,OUTPUT);

    pinMode(7,OUTPUT);

    }


    void loop() {

    static int LedPin = 2;

    for (LedPin; LedPin < 7; LedPin++){

    int val = analogRead (A0);

    int pauseAuf = map (val, 0, 1023, 50, 1000); //gemapter Wert um die Geschwindigkeit einstellen zu können

    //blinkAuf (pauseAuf); diese Funktion läuft nicht

    digitalWrite (LedPin, HIGH);

    delay(pauseAuf);

    digitalWrite (LedPin, LOW);

    }

    while (LedPin > 2){

    int val = analogRead (A0);

    int pauseAb = map (val, 0, 1023, 50, 1000); //gemapter Wert um die Geschwindigkeit einstellen zu können

    //blinkAb (pauseAb); diese Funktion läuft nicht

    digitalWrite (LedPin, HIGH);

    delay(pauseAb);

    digitalWrite (LedPin, LOW);

    LedPin --;

    }

    }

  • Hallo Rene,

    endlich, dank Deiner Hilfe, hat es geklappt. Als die Schleife funktioniert hat, war das Ausschalten der Led´s kein Problem mehr.
    Der zweite Code, wie von Dir vorgeschlagen mit tasterPin an Pin 2 und Led´s an den Pins 5, 6, 7, 8, 9.
    Die Änderung war kein Problem.


    Gruß
    Hans


    const int tasterPin = 7;


    void setup() {

    for ( int pin = 2; pin < 7; pin++) {

    pinMode(pin, OUTPUT);

    }


    pinMode(7, INPUT_PULLUP);

    }


    void loop() {

    if (digitalRead(tasterPin) == LOW) {

    for (int pin = 2; pin < 7; pin++) {

    digitalWrite(pin, HIGH);

    }

    }


    if (digitalRead(tasterPin)== LOW){

    for (int pin = 2; pin < 7; pin++){

    digitalWrite(pin, LOW);

    }

    }

    }




    const int tasterPin = 2;


    void setup() {

    for ( int pin = 5; pin < 10; pin++) {

    pinMode(pin, OUTPUT);

    }


    pinMode(2, INPUT_PULLUP);

    }


    void loop() {

    if (digitalRead(tasterPin) == LOW) {

    for (int pin = 5; pin < 10; pin++) {

    digitalWrite(pin, HIGH);

    }

    }


    if (digitalRead(tasterPin)== LOW){

    for (int pin = 5; pin < 10; pin++){

    digitalWrite(pin, LOW);

    }

    }

    }

  • Hallo Hans,


    Programmieren kann man nicht in der Theorie lernen. Erst mit dem Schreiben von Code erlernt man das richtig. Es ist wie mit dem Autofahren. Auch wenn du genau weisst, was Gaspedal, Lenkrad und Bremsen machen, wirst du ohne Übung im Stadtverkehr total verloren sein.

    Scheinbar wurde bei deinem Visual C++ - Kurs zu wenig Gewicht auf die Praxis gelegt. Aber eine gute Theoretische Grundlage solltest du dabei erworben haben. Jetzt gilt es nur noch, diese in der Praxis nutzbar zu machen.


    Darum kann ich dich nur dazu ermuntern, nicht aufzugeben. Ich nehme an, die beschäftigst dich mit dem Arduino aus privatem Interesse. Dann stehst du nicht unter Zeitdruck. Also lass dir Zeit und beschäftige dich nur damit, wenn du Lust hast.


    Taste dich mit sehr einfachen Übungen an die Materie heran. Versuche das umzusetzen, was ich in meinem letzten Beitrag beschrieben habe. Wenn das geklappt hat, versuche deine Schaltung zu modifizieren. Schliesse zum Beispiel den Taster an Pin 2 an und die LEDs an die Pins 5,6,7,8 und 9. Versuche dann, das Programm anzupassen.


    Gruss

    René

  • Hallo René,

    hallo Pius,


    vielen Dank für die große Unterstützung. Dies hilft mir auf alle Fälle.

    Ich möchte hier ein wenig ausholen und mein Problem zu erklären. Ich habe in meiner Vergangeneit mich schon des
    öfteren mit dem Programmieren versucht. Unter anderem habe ich 18 Monate lang einen Kurs Visual C++ belegt.
    D.h. mir sind eigentlich die meisten Begriffe bekannt. Wenn ich Code sehe (z.B. in unserer Firma), dann verstehe ich
    diesen teilweise. Ich kann nicht selbst Code schreiben. Stellt Euch vor Ihr würdet eine Fremdsprache lernen und es
    wird nur gesprochen. Dann hätte man Schwierigkeiten mit dem schreiben, wenn man das noch nie gemacht hat.
    Genau so geht es mir mit dem Programmieren. Ich weis zwar was ich machen soll aber nicht wie ich es machen soll.

    Deswegen wollte ich keine Lösungen, sondern nur Tipps. Wenn ich Lösungen sehe, denke ich immer es ist alles klar.
    Wenn ich selbst Code schreibe, dann stehe ich, wie Ihr erkannt habt, vor einem Problem.

    Ich habe schon das Gefühl, dass ich die vorherigen Lektionen verstanden habe.......


    Gruß
    Hans

  • Hallo Hans,


    das Ausschalten der LEDs haben wir gar noch nicht angeschaut. Solange das Einschalten nicht klappt, macht es keinen Sinn, sich um das Ausschalten zu kümmern.


    Noch eine Frage. Das ist ja bereits die Lektion 9. Hast du das Gefühl, dass du die ersten 8 Lektionen vollständig verstanden hast oder gibt es da noch Unsicherheiten? Falls da noch Unsicherheiten bestehen, solltest du entsprechende Fragen stellen. Die Lektionen bauen aufeinander auf und erfordern das Verständnis der vorhergehenden Lektionen.


    Du scheinst ein grundsätzliches Problem bei den Schleifen zu haben.

    Du schreibst in setup():

    Code
    1. for (int i = 0; i < leds; i++) {
    2. pinMode(leds, OUTPUT);
    3. }

    Das macht keinen Sinn. Du verwendest zwar eine Schleife mit der Laufvariablen i, die von 0 bis 4 läuft. Diese Laufvariable verwendest du dann aber nicht, statt dessen setzt du 5 Mal den pinMode von Pin 5 auf OUTPUT. Die anderen Pins sprichst du gar nicht an.

    Wir können das vereinfachen. Bisher zählst du die LEDs von LED0 bis LED4 durch und musst daraus den Pin berechnen. Das können wir auch direkt machen und so auf Konstanten verzichten.


    Code
    1. void setup() {
    2. for (int pin = 2; pin < 7; pin++) {
    3. pinMode(pin, OUTPUT);
    4. }
    5. pinMode(7, INPUT_PULLUP);
    6. }

    Damit werden die Pins 2 bis 6 auf OUTPUT gesetzt und Pin 7 auf INPUT_PULLUP.

    Dasselbe können wir in loop() machen. Auch hier können wir direkt mit Pinnummern arbeiten, anstatt die LEDs durchzuzählen.


    Code
    1.  void loop() {
    2. if (digitalRead(tasterPin) == LOW) {
    3. for ( pin i = 2; pin < 7; pin++) {
    4. digitalWrite(pin, HIGH);
    5. }
    6. }
    7. }

    Damit lassen sich alle LEDs einschalten. Das Ausschalten ist noch nicht programmiert. Versuche das Einschalten nachzuvollziehen. Sobald das läuft und du es verstanden hast, können wir uns um das Ausschalten kümmern.


    Hier nochmals als Zusammenfassung:

    - Eine for-Schleife enthält immer eine Zählvariable, die von einem Startwert zu einem Zielwert läuft.

    - Wenn ich schreibe: for (pin=2; pin<7; pin++) läuft die Variable pin von 2 bis 6, da als Endbedingung pin KLEINER 7 angegeben ist.

    - Diese Schleifenvariable wird benutzt, um im innern der Schleife eine Aktion auf jeden Wert anzuwenden.

    - Der Wert der Schleifenvariablen muss unter Umständen umgerechnet werden. Wenn wir hier direkt die Pinnummern verwenden, ist keine Umrechnung notwendig. Wenn wir durchzählen (von 0 bis 4), dann müssen wir 0 bis 4 auf 2 bis 6 umrechnen und schreiben daher i + 2.

    - Die Verwendung von Konstanten (ledPin, leds, tasterPin) ist optional. Sie sind aber sehr hilfreich, falls wir uns einmal entschliessen, die LEDs oder den Taster auf andere Pins zu legen.


    Gruss

    René

  • Lieber Hans

    so geht es mir auch immer wieder, dass ich manchmal tagelang an einem Problem suche und es einfach nicht einschränken kann.

    Und manchmal muss ich es wie Du machen und das Projekt für einen Moment beiseite schieben.

    Betrachten wir mal die for() Schlaufe kurz. Sie hat 3 Teilblöcke, oder 4 wenn man den Rumpf mit zählt:


    for( init ; ausdruck1 ; ausdruck2 ) {

    rumpf;

    }


    init: das was bei init steht, wird vor dem Starten der Schlaufe 1x ausgeführt, Das init dient zum definieren der Startbedingung.

    ausdruck1: wird als nächstes ausgewertet. Hier steht die Bedingung der Schlaufe. Solange diese Bedingung WAHR ist, wird die Schlaufe ausgeführt.


    nach dem ausdruck2 wird der Schlaufenrumpf ausgeführt


    ausdruck2: und erst jetzt wrd ausdruck2 ausgeführt und das ganze startet wieder bei ausdruck1


    Beispiel:


    for( int i = 0; i < 3; i++) {

    printf("%d",i);

    }


    1 int i=0; // i wird angelegt und mit dem Wert 0 gefüllt

    2 i<3; // i wird geprüft, ab i kleiner als 3 ist (i ist 0 das ist kleiner als 3)

    3 printf() // die Zahl i wird ausgegeben i ist 0

    4 i++; // i wird um 1 erhöht und ist danach 1

    nun wird das Ganze wieder bei Zeile 2 fortgesetzt, solange wie i<3 ist


    In diesem Beispiel wird die Ausgabe von i so aussehe:

    0

    1

    2

    fertig


    Übrigens, i ist nach der Schlaufe nicht mehr gültig, da i im init Block deklariert wurde und damit nur

    innerhalb der for() Schlaufe gültigkeit hat.



    verständnisvolle Grüsse

    Pius



  • Hallo René,

    hallo Pius,

    hallo Tom,


    nochmals Danke für die Unterstützung, aber leider konnte ich dies nicht umsetzen.
    Ich habe viele, auch unsinnige Dinge in den letzten Tagen versucht, aber es kam kein gutes Ergebnis heraus.

    1. Die Schleifen bekomme ich weiterhin nicht hin.
    2. Der Taster steuert nur LED Nr. 4 an und nicht mehrLED Nr. 5. Warum, kann ich nicht sagen
    3. Die LED´s wieder ausschalten geht nicht.

    Es macht mir gerade keinen Spass mehr und ich werde erstmal ein paar Tage Pause machen.

    Anbei mein bisheriger Code:


    //const int ledPin = 5;

    const int leds = 5;

    const int tasterPin = 7;



    void setup() {


    for (int i = 0; i < leds; i++) {

    pinMode(leds,OUTPUT);

    }

    pinMode(7, INPUT_PULLUP);

    }


    void loop() {

    if (digitalRead(tasterPin) == LOW){

    for( int i=0; i<leds; i++) {

    digitalWrite(leds, HIGH);

    }

    }

    /*if (digitalRead(tasterPin) == LOW){

    for( int i=0; i<=leds; i++) {

    digitalWrite(leds, LOW);

    }

    }*/

    }


    Gruß
    Hans

  • Hallo René,
    hallo Pius,
    hallo Tom,

    erst einmal vielen Dank für die Unterstützung. Für mich sind dies ganz schön viel Informationen.
    Ich werde versuchen diese unzusetzen und das Ergebnis mitteilen.


    Gruß
    Hans

  • Salu Hans

    Darf ich es Dir mit Kommentaren sagen, vielleicht hilft es Dir

    Gruss

    Pius


  • Hallo Hans,

    ich denke, dass ich zwei Fehler gefunden habe.

    Zum einen solltest du in der ersten Schleife mal die Variablenwerte einsetzen ( also die 5 für ledPin und für i ... ).

    Die Werte natürlich nur in Gedanken einsetzen und nicht wirklich in den Code schreiben.

    In der zweiten Schleife solltest du es genauso ausprobieren, dann solltest du die Fehler eigentlich finden.

    Ich habe jetzt aufgrund deiner früheren Bitte ( keine Lösung ) das Problem auch nur pauschal umschrieben.


    Gruß Tom

  • Hallo René,
    hallo Forum,

    ich habe an 2 Abende versucht die Tipps umzusetzen. Leider ist mir dies nicht gelungen.
    Es ist sogar noch verwirrender für mich geworden.

    1.) Keine Ahnung, ob die Schleife pinMode in Ordnung ist.
    2.) Der Taster reagiert nicht
    3.) Es leuchtet nur LED Nr. 5, ohne das der Taster betätigt wurde.

    Das einzige Positive ist, dass es keine Fehlermeldung gibt. Ich habe mir auch das Video nochmals angeschaut,
    aber ich konnte nichts finden, um meine eigene Aufgabe zu lösen. Alles ein wenig frustrierend, da dies nur
    eine Übung sein sollte.

    Anbei mein Code:


    const int ledPin = 5;

    const int leds = 5;

    const int tasterPin = 7;



    void setup() {


    for (int i = 0; i <= ledPin; i++) {

    pinMode(ledPin+i,OUTPUT);

    }

    pinMode(7, INPUT_PULLUP);

    }


    void loop() {

    if (digitalRead(tasterPin == LOW)){

    for( int i=0; i<=leds; i++) {

    digitalWrite(ledPin + 1, HIGH);

    }

    }

    }


    Hat jemand einen Tipp für mich.


    Danke und Gruß
    Hans

  • Hallo Hans,


    es ist gut, dass du momentan auf Arrays verzichtest. Da die Pins für die LEDs lückenlos hintereinander sind, benötigst du keine Arrays.


    Code
    1. const int led =5;
    2. const int tasterPin = 7;

    Diese beiden Konstanten sind vernünftig, du definierst damit die Anzahl LEDs und den Pin des Tasters. Du könntest auch noch den Startpin der LEDs (Pin 2) als Konstante definieren. Für den Moment solltest aber darauf verzichten, da es das Programm eher komplizierte machen würde.


    Code
    1. void setup() {
    2. //Schleife einsetzen
    3. pinMode(2, OUTPUT);
    4. pinMode(3, OUTPUT);
    5. pinMode(4, OUTPUT);
    6. pinMode(5, OUTPUT);
    7. pinMode(6, OUTPUT);
    8. pinMode(7, INPUT_PULLUP);

    Dieser Code ist korrekt. Du könntest das Setzen in den Output - Mode noch in eine Schleife packen. Diese läuft dann von 2 bis 6.


    Code
    1. void loop() {
    2. if (tasterPin,LOW){
    3. for(int i=0; i<led;i++) {
    4. digitalWrite(led, HIGH);
    5. }
    6. }

    Da sind diverse Dinge falsch.


    Den Taster kannst du abfragen mit (digitalRead(tasterPin) == LOW) oder mit (!digitalRead(tasterPin)).


    Die for-Schleife hast du im Prinzip richtig aufgesetzt. Du hast 5 Durchgänge, was der Anzahl der LEDs entspricht. Die Laufvariable ist i und die läuft von 0 bis 4. Um eine LED einzuschalten, musst du digitalWrite(ledPin,HIGH) aufrufen. Du musst also irgendwie aus deiner Laufvariablen i (geht von 0 bis 4) auf den ledPin (geht von 2 bis 6) kommen.


    Dann werden auf Tastendruck alle LEDs eingeschaltet. Das Ausschalten ist dann noch programmiert, aber immerhin ist es ein erster Schritt.


    Ich hoffe, dass ich nicht zu viel verraten habe.


    Gruss

    René

  • Hallo Forum,

    zum Thema Schleifen habe ich mir zur Übung eine Aufgabe gestellt, die mir nun doch größere Probleme bereitet.

    Aufgabe:
    5 LED´s mit einem Taster ein- und ausschalten. Verwendung mit Schleifen. (später über Array)


    Ich habe versucht, ohne irgendwo nachzuschauen, einen eigenen Code zu entwerfen.
    Leider ohne Erfolg. Ich bitte nur um Tipps, KEINE LÖSUNGEN.


    Anbei mein Code:

    const int led =5;

    const int tasterPin = 7;



    void setup() {

    //Schleife einsetzen

    pinMode(2, OUTPUT);

    pinMode(3, OUTPUT);

    pinMode(4, OUTPUT);

    pinMode(5, OUTPUT);

    pinMode(6, OUTPUT);


    pinMode(7, INPUT_PULLUP);

    }



    void loop() {

    if (tasterPin,LOW){

    for(int i=0; i<led;i++) {

    digitalWrite(led, HIGH);

    }

    }

    }


    Vielen Dank


    Gruß
    Hans

  • Hallo René,

    vielen Dank für die Glückwünsche und Deine Unterstützung. Ich werde natürlich versuchen, den Code zu optimieren.
    Ich bin voll motiviert besser programmieren zu lernen.


    Gruß
    Hans