Probleme mit Unterfunktionen

Hallo zusammen,

nachdem ich mit einem Arduino Nano angefangen hatte habe ich mir ein Arduino Uno Rev3 geholt.
Nun wollte ich mich mal an Funktionen versuchen und leider scheitere ich total. In der Vergangenheit habe ich im Studium MicroController-Technik gehabt, aber hier komme ich einfach nicht auf die Lösung.
Folgendes soll passieren:

  • Wenn ich eine Taster drücke, soll die Variable “zahl” um eins addiert werden (delay 20 millisekunden)
    → ist die Variable “zahl” größer 7 so soll zahl=1 werden
    -ist der Taster nicht mehr gedrückt, so soll eine Diode auf dem Brett anfangen die vorgegeben Zahl durch blinken widerzugeben
    → Zusätzlich durch den SerialMonitor soll das Ergebnis angezeigt werden

Mein Code sieht gerade folgendermaßen aus:

/* Kleine Anzeigespielerei */



//Als erstes wird eine Funktion definiert
  //Portbelegung fest
  const int pinLED1=11;
  const int Taster=9;
  const int zahlEnde=7;
  
  
  //Variablen
  int zahl=1;
  int i=1;
  int state=0;
  int TasterValue=0;
  
  void setup(){
    pinMode(pinLED1,OUTPUT);
    pinMode(Taster,INPUT);
    Serial.begin(9600);
  }

  void loop(){
   
    if(Taster==1){
      if(zahl==zahlEnde);{
        zahl=1;
              }
      delay(20);
      zahl=zahl+1;
    }
    else{
      Leuchtdiodenanzeige(zahl);
      Serial.print(zahl);
    }
  }
  
  void Leuchtdiodenanzeige(int zahl){    //Funktion die die LED blinken laesst
  while(i<zahl){
    digitalWrite(pinLED1,HIGH);
    Serial.print(i);
    delay(1000);
    digitalWrite(pinLED1,LOW);
    delay(1000);
    i++;
  }
}

http://pastebin.com/KGEgPUi8
Dabei soll die Funktion Leuchtdiodenanzeige mit nach nicht betätigen des Taster einmalig den Wert von Zahl zublinken. Leider passiert nichts und ich weiß nicht wo der Fehler liegt.
Kann mich einer auf die Rechte Bahn bringen, sonst habe ich das Gefühl, ich schmeiße den Uno mit Zubehör aus dem Fenster vor lauter Zorn!

//Als erstes wird eine Funktion definiert

Das ist löblich, seh ich aber nicht.

const int Taster=9; if(Taster==1){

Da sollte dein Code nicht so leicht hinkommen können ;)

int i = 1; // wenn das innerhalb von Leuchtdiodenanzeige() definiert ist, dann blinkt ein Aufruf von Leuchtdiodenanzeige(5) auch 5 mal. ( Willst du das ? )

Aber was passiert dann ? Der Unterschied zwischen "normaler" Programmierung und controller-Programmierung ist, dass das Programm hier nie fertig ist , aber ewig -- und meist so schnell wie möglich -- loop() von neuem aufruft.

Wenn du rauskriegst, warum du

int state=0; int TasterValue=0;

abgeschrieben hast, bist du ein gut Stück weiter. Viel Spass !

Ich danke dir schon mal für die Antwort. Ich muss gestehen, ich habe mir ein Beispiel aus dem Buch angesehen und wollte es dann nach meinen wünschen umbauen. Dabei habe ich einen Teil der Variablen übernommen. Diese haben aber in meinem Fall keinerlei Funktion. state war ursprünglich für eine weitere Abfrage gedacht (wieder in einer Unterfunktion), in der überprüft wird ob der Taster gedrückt ist oder nicht. Da ich diese überprüfung nicht übernommen habe, ist somit die Variable hinfällig. TasterValue, war um das High oder Low-Signal von dem Taster zu übernehmen und ich glaube hier liegt auch der Hase im Pfeffer begraben! Wie ich gerade sehe, mache ich eine Abfrage die totaler Unsinn ist!

if(Taster==1){

Diese Bedingung kann niemals erfüllt werden, da ich nur ein High oder ein Low Signal kriege. Durch das viele hin und herkopiere ist mir auch leider ein großer Teil meiner Kommentare flöten gegangen, was meinen Code etwas bescheiden aussehen lässt, das muss ich leider zugeben! Ich werde mich da morgen noch mal ransetzten und da mal ein bisschen Ordnung reinbringen. Aber deine Theorie, was das Programm machen soll, stimmt. Ich möchte nach dem loslassen vom Taster, dass eine Diode (ich nehme mal dein Beispiel) 5 mal blinken soll. Wie gesagt, ich sitze vor dem Buch und komme mit der Unterfunktion nicht wirklich weiter! Muss eine Unterfunktion nach der void setup() kommen? Wie du sieht mache ich mir schon gedanken über das was ich da versuche und durch meine Erfahrung mit SPS weiß ich auch, dass meine Bedingung immer und immer wieder abgefragt werden und das nie aufhört (daher heißt es ja auch void loop() ) :D

da ich nur ein High oder ein Low Signal kriege

0 / 1 oder HIGH / LOW : letzeres ist zwar schöner, aber nicht wirklich wesentlich ...

? Kriegst du überhaupt ein aktuelles Signal ?

pinMode(Taster,INPUT); // ist schon mal gut in setup(), aber beim Arduino reicht das nicht ...

TasterValue, war um das High oder Low-Signal von dem Taster zu übernehmen und ich glaube hier liegt auch der Hase im Pfeffer begraben! Wie ich gerade sehe, mache ich eine Abfrage die totaler Unsinn ist!

Ja, da hast du Recht! Viel Spass!

Wenn das Buch über Arduino ist, ist es evtl. einfacher, ein Beispiel erstmal unverändert ans Laufen zu kriegen, und danach zu verändern...

z.B. - was soll passieren, während der Taster gedrückt ist? 20 msec Warten ist gut um das Prellen auszusitzen, aber danach sollte der Tasterzustand wieder abgefragt werden und dein "Zufallszähler" geändert werden. ( In einer Schleife innerhalb loop() oder indem loop() neu startet ? ) - Beides geht, aber das sind die Sachen um die es hier sich hier dreht - was soll passieren, wenn du während des Blinkens den Taster wieder drückst ? - was passiert, wenn es n mal geblinkt hat ? ( auch wenn nix passiert, läuft der controller weiter und ... )

Ich sag mal so, mein vorrangiges Problem ist nun erst einmal, dass ich leider nicht weiß wo die Unterfunktion untergebracht sein muss! Kann / muss dieser vor der void setup() sein oder lieber doch erst nach der void setup()?? Leider erklärt dies mein Buch leider gar nicht und zeigt es nur einmal! Danach wird alles wieder in der void loop abgefrühstückt, was ich ein bisschen bescheiden finde (darum wurden ja die Unterfunktionen eingebaut)

Im Normalfall unter C müssen die Funktionen vor die loop. Bei Arduino-IDE ist es egal da diese auch funktioniert wenn danach die Funktion deklriert wird. Das in deinem Code ist auch falsch If-klauseln enden nie mit einem Semikolon da diese den Befehl abschließen. Also weg damit.

Ein Tip wie bekommt dein Arudino mit das an dem Pin der als eingang definiert ist sich etwas ändert?

 if(zahl==zahlEnde);

Gruß Daniel

EIGENTLICH, müssen in c / c++ Funktionen zuerst deklariert werden, bevor sie benutzt werden. Wo sie dann definiert (implementiert sagen auch manche) werden, ist egal. Kann auch in einer anderen Datei sein.

Die Arduino IDE versucht da zu helfen, und generiert und fügt automatisch Deklarationen am Anfang ein, wenn aus einer .ino Datei eine .cpp Datei gemacht wird.

  1. Deine Kommentare sind unnötig und oft falsch. Kommentare sollen nicht zeigen wie etwas implementiert ist. Das sieht man schon im Code. Stattdessen sollen sie sagen was und warum es gemacht wird.

  const int Taster=9;
<snip>
    if(Taster==1){

Die Bedigung Taster==1 kann nie erfüllt sein. Du meinst wohl eher

if (digitalRead(Taster)) {
      if(zahl==zahlEnde);{
        zahl=1;
              }
      delay(20);
      zahl=zahl+1;

Sieht mehr als schräg aus. Zahl wird ja nicht direkt hinter dieser Sequenz ausgewertet. Auf jeden Fall wird Zahl dadurch danach immer >= 2 ausfallen. Warum nicht eher sowas:

      zahl= zahl < zahlEnde-1? zahl+1: 0;
      delay(20);

In Deinem Unterprogramm wird auf die globale Variable i zugegriffen und diese nicht initialisiert. Deshalb wird die Schleife nur solange abgearbeitet bis i zu groß wird.

  void Leuchtdiodenanzeige(int zahl){    
  while(i<zahl){
    digitalWrite(pinLED1,HIGH);
    Serial.print(i);
    delay(1000);
    digitalWrite(pinLED1,LOW);
    delay(1000);
    i++;
  }

Es sollte also wohl eher

    for (uint8_t i=0; i<zahl; ++i) {

statt der while Schleife sein, oder?

Was die Fehler angeht: Du bist noch ein Anfänger. Da musst Du Geduld mitbringen. Aller Anfang ist schwer und bei Controllern erst recht.

So ich habe mich noch einmal versucht, aber leider klappt es mit den unterfunktionen immer noch nicht. Könnte mir einer ein einfaches Beispiel geben als Code geben, damit ich mir das mal genauer ansehen kann. Reicht wenn es im Gründe nur ein Programm ist, welches einen Taster überprüft und eine LED an oder aus macht. Somit hätte ich ein Beispiel, mit dem ich mir das noch einmal genauer ansehen könnte. Vllt komme ich ja so meinem neuem kleinen Programm dem Fehler auf die Schliche.

Hier mal eine kleines Programm mit zwei "Unterfunktionen" einemal mit Übergabe eines Wertes aus der Hauptloop einmal ohne. Hoffe kann die damit das ein bisschen erklären.

#define LED 13
#define TASTER 4

boolean Tasterstatus=false;  // Speichervariable für den Status (boolean weil nur 0 oder 1)
boolean LEDstatus=false;
byte Ergebniss=0;             // Ein byte 0-255

void setup(){
  pinMode(LED,OUTPUT);
  pinMode(TASTER,INPUT);
}

void loop(){
  Tasterstatus=digitalRead(TASTER);   // Einlesen des Digital IN
  if (Tasterstatus==true){            // Wenn der Digitakl In High ist 
    ToogleLED();                      // Aufrufen der Funktion Toogle LED
  }
  else                                // Wenn der Taster nicht gedrückt   
    Ergebniss=quad(5);                // Aufrufen der Quadriefunktion mit übergabe- eines Wertes und dem Ergebnis 5*5 aus der unteren Funktion
}

void ToogleLED(){            // void (Leer) eine Funktion die kein "ergebniss" liefert
  LEDstatus=!LEDstatus;   // der letzte Status wird inveriert
  digitalWrite(LED,LEDstatus);  // schreiben des Status an den Ausgang
}

byte quad(byte x){          // byte als Funktionsdekalration gibt ein byte zurück (byte x) lokale Variable innerhalb der Funktion 
  byte y;                        // darin speichern wir NUR innerhalb der Funktion das ergebniss (kannst du in der Loop nicht sehen)
  y=x*x;                         // Hier wird gerechnet y=x*x also quadrat
  return y;                      // Mit return gibt deine Funktion den Wert von y zurück (also an die Loop)
}