Einsteiger benötigt Hilfe

Hallo liebe Leute.
Ich bin neu hier und relativ neu in Arduino-Programmierung.
Ich habe folgendes Problem: Für meine Facharbeit möchte ich ein alternatives Inputdivice, ähnlich wie die Tastatur bauen und Programmieren. Dieses soll aus insgesamt 16 Tasten bestehen: 12 sollen Buchstaben ausgeben (es sind die digitalen Pins 0-11 , nenne ich sie mal fin) und 4 sollen die Buchstaben, die bei fin ausgegeben werden, verändern (dies sind die analogen Pins A0-A3, nenne ich sie mal chan). Dazu habe ich einen Programmcode geschrieben, dessen void loop wie folgt aussieht (ich habe die void setup und alles davor aus Gründen der Übersicht mal weggelassen):

void loop()
{
  start:
  for(int j=0 ; j<=3 ;j++)
  {
    if(digitalRead(chan[j]) == LOW)
    {
      digitalWrite(led, HIGH);
      delay(20);
      digitalWrite(led, LOW);
      switch (j)  
      {
        case 0:                                                            //Erste Auswahltaste
        start0:
        for(int i = 0 ; i<=11 ; i++)
        {
          if(digitalRead(fin[i]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(10);
            digitalWrite(led, LOW);
            Keyboard.press(bef0[i]);
            delay(50);
            while (digitalRead(fin[i]) == LOW)
            {
              digitalWrite(led, HIGH);
              Keyboard.press(bef0[i]);
            }
            digitalWrite(led, LOW);
            Keyboard.releaseAll();
          }
        }
        for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start0;
          }
        }
      
        case 1:                                                          //Zweite Auswahltaste
        start1:
        for(int i = 0 ; i<=11 ; i++)
        {
          if(digitalRead(fin[i]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(10);
            digitalWrite(led, LOW);
            Keyboard.press(bef1[i]);
            delay(50);
            while (digitalRead(fin[i]) == LOW)
            {
              digitalWrite(led, HIGH);
              Keyboard.press(bef1[i]);
            }
            digitalWrite(led, LOW);
            Keyboard.releaseAll();
          }
        }
        for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {            
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start1;
          }
        }
      
        case 2:                                                          //Dritte Auswahltaste
        start2:
        for(int i = 0 ; i<=11 ; i++)
        {
          if(digitalRead(fin[i]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(10);
            digitalWrite(led, LOW);
            Keyboard.press(bef2[i]);
            delay(50);
            while (digitalRead(fin[i]) == LOW)
            {
              digitalWrite(led, HIGH);
              Keyboard.press(bef2[i]);
            }
            digitalWrite(led, LOW);
            Keyboard.releaseAll();
          }
        }
        for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {            
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start2;
          }
        }
      
        case 3:                                                          //Vierte Auswahltaste 
        start3:
        for(int i = 0 ; i<=11 ; i++)
        {
          if(digitalRead(fin[i]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(10);
            digitalWrite(led, LOW);
            Keyboard.press(bef3[i]);
            delay(50);
            while (digitalRead(fin[i]) == LOW)
            {
              digitalWrite(led, HIGH);
              Keyboard.press(bef3[i]);
            }
            digitalWrite(led, LOW);
            Keyboard.releaseAll();
          }
        }
        for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {           
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start3;
          }
        }
      }
    }
  }
}

Der Arduino macht nun folgendes: Ich muss einen analogen Pin wählen, um anfangen können zu schreiben und habe eine LED an Pin 13 zwischengeschaltet um eine Kontrollleuchte zu haben. Wähle ich jetzt einen analogen Pin von A1-A3 wird das entsprechende Case angesteuert. Aber nur einmal. Danach kann ich keinen anderen cha mehr auswählen außer A0. Wähle ich A0 aus, kann ich garnichts mehr auswählen.
Ich benutze einen Arduino Leonardo und habe noch nicht viel Erfahrung mit Hardwareprogrammierung, allerdings mir C++, spezifiziert auf QT und PHP.
Ich hoffe es sind nicht Programmcode mangelt :smiley: .
Vielen Dank im Vorraus! :sweat_smile:

Mal abgesehen davon das Du mitten im Code wahrscheinlich zu start2 springen willst anstelle zu start:

würg

Mich wunderts, das der Code überhaupt ansatzweise was sinnvolles macht.

Bei den ganzen Gotos wird mir übel, Du jumpst da teilweise mitten in Entscheidungsbäume rein, das kann nur in die Hose gehen.

Fang mal an Deinen Code modularer aufzubauen und bestimmte, sich wiederholende Funktionen in Functions auszulagern und diese parametrisiert auzurufen.

Warum liest Du in den case-Zweigen nochmal die chan-Ports? Nur für die LEDs? Und was sollen die Schleifen bewirken?

        for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start0;
          }
        }

Wenn chan[0] LOW ist springst Du raus, wenn HIGH dann auch. Die Prüfung für chan[1] und chan[2] erreichst Du so nie.

Warum überhaupt das Gejumpe? Du bist in mehreren Schleifen, am Ende fällst Du wieder in die loop() und die geht ganz alleine wieder nach oben.

Thorben:
delay(50);

Mit so vielen und langen delays wie Du sie da programmierst, wird das mehr ein Verschnaufpausen-Device, das seine Zeit mit eigenem Warten verbringt, als ein Input-Device, das auf fremde Benutzereingaben blitzschnell reagiert.

Meine Meinung: Die beschriebene Anwendung muß ohne delays programmiert werden. Allenfalls ein winziges delay zur Tastenentprellung, wenn es denn unbedingt sein soll.

Thorben:
}
}
}
}
}
}

Ist es für die Facharbeit eigentlich verboten worden, dem Programm mit selbstgeschriebenen Unterfunktionen eine übersichtliche Struktur zu geben?

Thorben:
allerdings mir C++, spezifiziert auf QT und PHP

C++ und PHP sind schließlich bekannt für die vielen goto Anweisungen im Code, die gute Programmierer immer verwenden!

Programmieraufgabe:
Erstellen Sie eine Funktion, die den Wert einer Zahl i ändert.
Enthält i den Wert 1, so wird er in 2 geändert, und umgekehrt.

Lösung:

int tausche_1_2(int i)
// liefert 2 bei Eingabe 1
// liefert 1 bei Eingabe 2
// liefert sonst i und eine Serial-Fehlermeldung bei allen anderen i
{
  if (i == 1) goto skip_1; 
  if (i == 2) goto skip_2;
  goto error;
  skip_1:
  i = 2; 
  goto done;
  skip_2: 
  i = 1; 
  goto done;
  error:
  Serial.print("Falscher Eingabewert: ");
  Serial.println(i);  
  done: ;
  return(i);
}

Hallelujah!
Echte Programmierer haben keine Angst vor unübersichtlichen Programmen mit vielen gotos!
:wink:

jurs:
Hallelujah!
Echte Programmierer haben keine Angst vor unübersichtlichen Programmen mit vielen gotos!
:wink:

Man kann auch Russisches Roulette mit ner Halbautomatischen spielen, ist in etwa genauso effektiv. ]:smiley:

vieledinge:
Man kann auch Russisches Roulette mit ner Halbautomatischen spielen, ist in etwa genauso effektiv. ]:smiley:

Das mit dem Smiley ist natürlich ironisch gemeint.

Wenn ich sowas programmieren wollte, dann wären da im Code natürlich keine gotos und auch keine delays drin. Einen Leonardo, mit dem man eine USB-Tastatur simulieren kann, habe ich zwar nicht, aber ich habe mal ein Programm-Grundgerüst für eine alternative Tastatur mit verschiedenen Tastschaltern gemacht, die grob skizziert so aussehen könnte, der entscheidende Code muss natürlich noch geschrieben und eingefügt werden:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

#define CHARBUTTONS 12
#define MODIFIERBUTTONS 4

// Mit 4 Modifier-Tasten und 12 Zeichentasten sind (mindestens)
// 5*12 =60 verschiedene Zeichen eingebbar, z.B.
char charTable[MODIFIERBUTTONS+1][CHARBUTTONS]={
    {'a','b','c','d','e','f','g','h','i','j','k','l'},
    {'m','n','o','p','q','r','s','t','u','v','w','x'},
    {'y','z','!','%','&','/','(',')','=','?','.',','},
    {'1','2','3','4','5','6','7','8','9','0','+','-'},
    {'A','B','C','D','E','F','G','H','I','J','K','L'}
    };


int readCharButton()
// returns number of button once a button is pressed
// returns -1 otherwise
// fires once each button is pressed (after being released before)
{
  // put your code here!
}


int readModifierButton()
// returns 0 (no ModifierButton) or number of ModifierButton pressed
// at the moment the function is called
{
  // put your code here!
}

    
void fireButton(int charBtn, int modifierBtn)
// do the action!
{
  // Keyboard.press(charTable[modifierBtn][charBtn])
  Serial.println(charTable[modifierBtn][charBtn]); 
}
    

void loop() {
  // put your main code here, to run repeatedly: 
  int charButton,modifierButton;
  charButton=readCharButton();
  if (charButton>=0) // charButton has fired
  {
    modifierButton=readModifierButton(); // check for modifier button
    fireButton(charButton,modifierButton); // action! 
  }
}

Mal so ganz grob skizziert, wie es machbar wäre.

Jedenfalls strukturiert mit selbstgeschriebenen Funktionen, die aus der loop heraus aufgerufen werden, und nicht mit einer ellenlangen loop-Funktion, die völlig unübersichtlich ist.

Nur noch den Code für die beiden Funktionen readCharButton() und readModifierButton() zusammenschreiben und fertig.

Die Fünffachbelegung von Buchstabentasten durch vier Modifier-Tasten ist natürlich sehr "alternativ", denn an PC-Tastaturen sind viele User schon mit der Dreifachbelegung durch zwei Modifier-Tasten (Großbuchstabentaste und die AltGr-Taste) vollkommen überfordert.

Wow, danke für die vielen Konstruktiven Antworten! Dieses Forum ist das erste Forum in welchem ich tatsächlich mal gute Informationen bekomme! Danke :smiley:

Auf jeden Fall, um etwas Struktur in meine Aussagen zu bekommen, das Gerät wird ein Handschuh werden. Dieser soll aus Gründen der, nenne ich es mal "Bequemlichkeit", 12 Tasten haben, die Buchstaben erzeugen und 4, die die anderen 12 so verändern, das sie andere Buchstaben schreiben. Heißt also, drücke ich fin[0] als bsp. soll er mir ein a ausgeben. Drücke ich jetzt chan[1], dann soll er mir, da, wo vorher 'a' ausgegeben wurde, jetzt 'm' ausgeben. Deswegen auch die vielen Goto's. Jeder Case hat eine eigenen goto (fals ich das so ausdrücken darf).

case 0:                                                            //Erste Auswahltaste
        start0:
        for(int i = 0 ; i<=11 ; i++)
        {
          if(digitalRead(fin[i]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(10);
            digitalWrite(led, LOW);
            Keyboard.press(bef0[i]);
            delay(50);
            while (digitalRead(fin[i]) == LOW)
            {
              digitalWrite(led, HIGH);
              Keyboard.press(bef0[i]);
            }
            digitalWrite(led, LOW);
            Keyboard.releaseAll();
          }
        }
        for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start0;
          }
        }

wenn ich jetzt in einem case drin bin, also zum beispiel case0 gedrückt habe, soll er gucken ob:
a) ein Finger gedrückt ist. Wenn das der Fall ist, soll er die entsprechende Taste drücken.
b) einer der 4 chan-"Tasten" gedrückt wurde. Wenn das der Fall ist, soll er zu einem anderen case gehen, mit der gleichen fin-"Taste" einen anderen Buchstaben erzeuge.

"Taste" ist deswegen in Anführungszeichen, weil an den Fingern nur Kupferlitze sitzt, bzw. sitzen wird, die halt als INPUT_PULLUP definiert sind, damit es einfacher ist mit der Abfrage.
Zu den Delays: Probier es mal aus auf der Tastatur. Wenn man eine Taste drückt und gedrückt hält, wird der Buchstabe, oder das Zeichen einmal geschrieben und dann kommt eine Kurze Pause von ca. einer halben Sekunde, nur so ca., wo er keine Aktion ausführt oder eine Taste drückt und danach die Taste durch weg, ohne Unterbrechung schreibt. Deswegen die Delays. Die Delays dienen außerdem auch dazu, das man das Leuchten von der Kontroll-LED richtig wahrnehmen kann. An der LED kann man das Problem ganz gut sehen. Wenn man eine der chan-"Tasten" drückt, leuchtet die LED genau einmal auf und danach nicht mehr. Ich kann am Anfang immer genau einmal, eine der chan-"Tasten" drücken, welche ich will. Diese Leuchtet dann halt einmal auf und danach nicht wieder, egal wie lange ich die "Taste" gedrückt halte. Danach kann ich nur noch chan0 auswählen. Diese kann ich auch gedrückt halten und die LED leuchtet die ganze Zeit durch. Versuche ich aber eine andere auszuwählen, geht dies nicht. Und genau hier verstehe ich nicht wieso .. :~
Ich hoffe mein Problem ist deutlicher geworden.
Ich habe das ganze vorher schon mal mit if-abfragen probiert, anstatt mit den Cases.. War eine ganz Blöde Idee. Nicht nur, das es dann noch unübersichtlicher war, funktionierte das nicht.. :confused:

Eine Lösung habe ich gefunden, wenn auch keine elegante :wink:
Als Abbruchbedingung habe ich jetzt einfach folgendes gemacht:

for(int i = 0 ; i <=11 ; i++)
        {
          if (digitalRead(chan[1]) == LOW)
          {
            goto start1;
          }
          else if (digitalRead(chan[2]) == LOW)
          {
            goto start2;
          }
          else if (digitalRead(chan[3]) == LOW)
          {
            goto start3;
          }
          else
          {
            goto start0;
          }
        }

Nur verstehe ich den Fehler von mir nicht. In meiner alten Abbruchbedingung habe ich es quasi "Variabel" gemacht und mit der for-schleife einfach jeden einzelnen chan abgefragt ob er LOW ist und wenn ja, er zurück zum Anfang gehen soll. Da die Taste ja gedrückt ist, soll er danach zu dem Entsprechenden case gehen. Wo liegt der Fehler hier drin?

for(int n=0 ; n<=3 ; n++)
        {
          if(digitalRead(chan[n]) == LOW)
          {
            digitalWrite(led, HIGH);
            delay(20);
            digitalWrite(led, LOW);
            goto start;
          }
          else
          {
            goto start0;
          }
        }

Ich glaube Du soltest Dich erstmal von Deinem Ansatz lösen und das Thema strukturiert angehen.

Wie wäre es denn z.B. mit einer Funktion "read_chan()", welche Dir einen Wert 0 (keine Taste gedrückt),1,2,3,4 (für die jeweilige Taste) liefert.
Ebenso eine Funtion read_fin() die das gleiche für die 12 Tasten macht (0 für keine) 1 - 12 für die einzelnen Tasten

Das ist das erste was Du baust, mehr nicht. Leiglich eine Ausgabe in der loop() welche Tasten (Nummer der Taste) gerade gedrückt wurden.
Einzige Vorgabe für diese Aufgabe ist KEINE!!! gotos verwenden....

Wenn das geschafft ist, wird das Programm Stück für Stück erweitert.

Mario.

Thorben:
Zu den Delays: Probier es mal aus auf der Tastatur. Wenn man eine Taste drückt und gedrückt hält, wird der Buchstabe, oder das Zeichen einmal geschrieben und dann kommt eine Kurze Pause von ca. einer halben Sekunde, nur so ca., wo er keine Aktion ausführt

Nein, es wird nicht eine halbe Sekunde oder so "keine Aktion ausgeführt", sondern es wird auch in dieser Zeit auf das Drücken oder Loslassen von Tasten gewartet. Sobald eine Taste gedrückt wird, feuert unmittelbar der dazugehörende Scancode über das Tastaturkabel.

Delay heißt: "Mach ne Pause und warte auf das Ende der Pause, egal was zwischendurch passiert, ja nicht reagieren.

Und das was bei einer Tastatur tatsächlich abläuft ist: "Du kannst ne Pause machen, aber Du mußt auf dem Sprung sein und sofort reagieren, wenn in Deiner Pause eine Tastenaktion passiert".

Was Du brauchst, ist quasi dasselbe Verhalten wie bei einer Tastatur: Du hast einerseits Buchstabentasten, die angeschlagen werden können und dann blitzschnell eine Aktion hervorrufen, indem ein Zeichen ausgegeben wird. Und Du hast Modifikations-Tasten, die für sich kein Zeichen ausgeben können, sondern die nur das ausgegebene Zeichen beim Anschlagen von Buchstabentasten modifizieren. So wie etwa die Großbuchstaben-Umshalttaste (Shift), die Steuerungs-Taste (Strg) oder die AltGr-Taste.

Damit das Ausgeben von Zeichen flüssig und geschmeidig abläuft, müssen die Tasten genauso ohne delay abgefragt werden wie auch das Blinken ohne delay realisiert werden muss.

Wenn Du delays einbaust, machst Du die Steuerung damit nur hakelig, langsam und unzuverlässig. Wenn z.B. eine Taste schnell angeschlagen und losgelassen wird und dies innerhalb eines delays stattfindet, kann der Arduino überhaupt nicht mehr feststellen, dass die Taste überhaupt gedrückt war (mit Ausnahme der zwei Pins 2 und 3 am Uno, auf die man Hardware-Interrupts programmieren könnte, mit denen man auch Aktionen abgreifen kann, die innerhalb von delay stattfinden).

Mein Rat: Finger weg von delay bei so einem Vorhaben!

Ahh, ok, das wusste ich nicht ^^ Danke!
Gibt es irgentwie eine Möglichkeit das, das auf dem Arduino Leonardo genauso um zu setzen? Es soll möglichst genauso wie auf der Tastatur funktionieren, ich kenn mich aber ehrlich gesagt nicht so gut aus in Hardware-Programmierung.
Danke nochmal!

Da es für eine Facharbeit ist, wie Du selbst schreibst, wird Dir hier sicher keiner eine fertige Lösung präsentieren. Das wäre am Ende ja auch "erschleichen" einer Prüfungsleistung. Gnügend Tipps für die Umsetzung hast Du ja erstmal bekommen und kannst anfangen. Wenn es Probleme gibt, die sich konkret benennen lassen (also nicht einfach nur ... GEHT NICHT :slight_smile: ), dann wird Dir hier sicher geholfen.

Thorben:
Gibt es irgentwie eine Möglichkeit das, das auf dem Arduino Leonardo genauso um zu setzen?

Die Möglichkeiten sind vielfältig.

Was verstehst Du unter "genauso"? Dass die Taste beim Drücken zunächst den Buchstabencode nur einmal feuert, und wenn die Taste dann länger gedrückt bleibt soll sie nach einer Weile anfangen, den Buchstabencode in schneller Folge als Dauerfeuer zu senden?

Auch das sollte möglich sein.

Ein Programm-Grundgerüst hatte ich ja weiter oben schon gepostet. Das schwierige ist die Funktion readCharButton() mit entsprechendem Code zu füllen, so dass diese Funktion beliebig oft aufgerufen werden kann, keine delays enthalten sind, aber dass sie eben nur bei Erfüllung bestimmter Bedingungen den entsprechenden Buchstabencode zurückliefert.

Im wesentlichen könnte es dann so funktionieren, dass sich die Funktion in internen Statusvariablen merken muss, wann eine bestimmte Taste zuletzt gedrückt wurde (Systemzeitabfrage mit millis()-Funktion), anhand der Entprellzeit feststellt ob es sich bei zwei Kontaktschließungen um "einmal gedrückt" (Kontaktprellen) oder "doppelt gedrückt" (zwei Buchstaben) handelt, und ob der Buchstabencode bei gültigem Tastendruck bereits zurückgeliefert wurde.

Und wenn es dann mit dem Feuern von Einzelbuchstaben funktioniert, kann man die Funktion so erweitern, dass auch die Dauerfeuerfunktion bei längerem Drücken anspringt, wozu man sicher wieder neue Statusvariablen deklarieren müßte, also ein bischen Speicherverbrauch kommt da schon zusammen. Ist sicher ein bsischen tricky, das einwandfrei hinzubekommen.

Dagegen ist die oben im Programmgerüst eingeführte Funktion "readModifierButton()" geradezu trivial zu coden: Wenn eine Buchstabentaste ihren Code abfeuert, braucht man einfach nur in diesem Augenblick nachsehen, welche Modifier-Taste gedrückt ist und kann danach sofort in einer Tabelle nachsehen, ob der normale oder ein modifizierter Buchstabencode gesendet werden soll.

Soll ich an das oben gepostete Programmgerüst mal noch ein paar Zeilen mehr Fleisch dran coden, damit Du klarer siehst?

mkl0815:
Das wäre am Ende ja auch "erschleichen" einer Prüfungsleistung.

Echt jetzt?
Selbst bei einer wissenschaftlichen Arbeit dürfen doch fremde Quellen verwendet werden!
Fremde Quellen müssen nur korrekt mit Quellenangabe zitiert werden, d.h. eigene Leistung und fremde Leistung müssen aus der abgegebenen Arbeit klar ersichtlich sein. Das dürfte dann ja wohl auch für Facharbeiten gelten, in denen Gymnasial-Schüler an wissenschaftliches Arbeiten herangeführt werden sollen, oder?

Selbst eine Frau Schavan bekommt ihren Doktortitel ja nicht deshalb aberkannt - wie ehedem Herr Guttenberg, nur weil sie fremde Quellen genutzt hatte, sondern weil sie fremdes Material nicht ausreichend per Kennzeichnung und Quellenangabe als fremdes Material angegeben hat.

mkl0815:
Da es für eine Facharbeit ist, wie Du selbst schreibst, wird Dir hier sicher keiner eine fertige Lösung präsentieren. Das wäre am Ende ja auch "erschleichen" einer Prüfungsleistung. Gnügend Tipps für die Umsetzung hast Du ja erstmal bekommen und kannst anfangen. Wenn es Probleme gibt, die sich konkret benennen lassen (also nicht einfach nur ... GEHT NICHT :slight_smile: ), dann wird Dir hier sicher geholfen.

Ich setze voraus, daß wenn jemand eine Facharbeit schreibt, daß er Verstanden hat, um was es dabei geht. Einen fremden Code zu nehmen den man nicht verstanden hat, ist überaus gefährlich, da man ihn nicht erklären kann. Auch ein "perfekter", professioneller Code verleitet die Prüfer schwierigere Fragen zu stellen, da sie von einem höheren Niveau des Studenten ausgehen. Darum rate ich Thorben seine grauen Zellen anzustrengen und aus den bereits gemachten Hilfen bzw Ratschlägen selbst seinen Code zu schreiben. Bei weiteren Problemen sind wir sicher weiter behilflich.

@Thorben
Auch ich bin der Meinung: vergiß GOTO. In C braucht man es nicht. Außerdem werden Rücksprungadressen in den Stack geschrieben, die bei einem Herausspringen aus einer Schleife mittels goto nicht gelöscht werden und so den Stack zum Überlauf bringen. Das macht den Sketch instabil.

Grüße Uwe

hi,

trenne die aufgaben. zuerst schaffe es, die 15 tasten einzulesen, egal wie schnell oder langsam Du sie drückst, und lass sie Dir auf dem serial monitor ausgeben. dabei mußt Du auch das problem mit dem entprellen einbeziehen.
wenn das läuft, gehe die logik an, was passiert, wenn eine der 4 "speziellen" tasten gedrückt wurde, oder eben keine, was passiert, wenn zwei "spezielle" tasten hintereinander gedrückt werden (oder was machst Du, wenn du eine "falsche" chan-taste drückst, und Du das korrigieren willst), usw..
ich hab' gerade heute mit einem solchen gerät gearbeitet, das 5fach belegte tasten hat, ein LKW-parametriercomputer von siemens, da irrt man sich auch mal beim tippen, fehler wollen abgefangen werden, aber das ist programmierlogik, das kommt als zweites, erstmal tasten korrekt lesen...

gruß stefan

Wow, ich hätte nicht gedacht das ich so viel erfahre, während ich versuche ein Problem zu lösen! :smiley:
Jetzt mal back to topic.
Ich möchte von niemandem hier eine fertigen Programmcode verlangen, geschweige denn verwenden. Rein Theoretisch wäre es mir erlaubt, da meine Facharbeit aus 3 Teilen besteht und ich den Arduino-Code nicht klar deffiniert selbst schreiben soll, aber da würde ich mich aber in meiner Ehre verletzt fühlen. Das ich nachgefragt habe, ob es möglich ist, diese, bei der Tastatur übliche (ich nenne es mal) "delay"-Zeit einzubauen, hängt damit zusammen, das ich mich nicht mit der Hardware-Programmierung auskenne.

@jurs:
Also, ich glaube ich habe es im weitesten verstanden, ich werde damit jetzt ein bisschen "rumspielen" und ausprobieren und mich dann mal wieder melden. Vieleicht wenn ich es dann noch nicht hinbekommen habe, aber vielen vielen dank! :slight_smile:

@uwefed:
Ich bin selber grade am gucken wie ich das besser hin bekomme. Dieser Quellcode dient quasi erstmal als "Sicherungsnetz", das ich überhaupt einen funktionierende Code habe, da ich halt noch nicht so viel mit Arduino programmiert habe. Alles in einem war das quasi mein erster Versuch und dort trat dann halt dieses eine doofe Problem auf, das die chan-Tasten, abgesehen von der Nullten nicht, bzw. nur einmal, drücken konnte und dachte mir dann, ich frage lieber erstmal Profis, woran das beim "einfachen" Code lag, anstatt gleich mit dem etwas schwereren, aber eleganteren Code anfange.

@Eisebaer
Hi. Also, das habe ich in meiner allerersten Auseinandersetzung mit dem Arduino und dieser Aufgabenstellung bereits erledigt. Das reine Lesen von (bei mir waren es) 12 Tasten ist möglich und funktioniert absolut reibungslos. Auch ohne Goto befehle und der Abfrage der 4 "speziellen" Tasten und das hier war quasi mein Versuch, die Abfrage der 4 "speziellen" Tasten mit einzubinden :wink:

Außerdem werden Rücksprungadressen in den Stack geschrieben, die bei einem Herausspringen aus einer Schleife mittels goto nicht gelöscht werden und so den Stack zum Überlauf bringen. Das macht den Sketch instabil.

Kinder, Uwe ist ein toller Moderator, aber alles darf man ihm auch nicht glauben.

Mit einem goto kann man nicht aus einer Funktion herausspringen (oder hinein) und so den Stack "zum Überlauf bringen". So einen Mist würde der avrgcc Compiler nicht zulassen. Wo goto syntaktisch zulässig ist, funktioniert es auch. Und es funktioniert auch 1000 Mal, d.h. nach einer halben Sekunde noch.

Aber außer den Sonderfällen continue; break; return; sollte man wirklich ohne Sprünge auskommen und eher an Funktionen denken, wenn man die gleiche Aktion an verschiedenen Stellen im Code braucht.


Falls das missverständlich war: Natürlich kann man Code schreiben, der den RAM zum Überlauf bringt, ohne dass der Compiler es merken kann.
Z.B. ein String Objekt verwenden :wink:

ups

ich hoffe aber bei 99,5% der Fälle liege ich aber richtig :wink: :wink: :wink:
Grüße Uwe

habe mitgeschrieben, uwe, 99,63267%, ein insgesamt tragbares ergebnis...

Danke Stefan, da bin ich ja beruhigt. :cold_sweat: :cold_sweat: :wink: :wink: