Tipp für case-Schleife in C gesucht

  • Genauso ist es. Der Anwender soll zur Laufzeit wechseln können. Und um die Zuordnung einfacher zu haben, ist der erste Eintrag im 2-dimensionalen Array die "Master-FB". Ich will dan wie oben beschrieben immer vom gefundenden Index auf den Master-Code gehen. Damit habe ich dann wirklich Konstanten in der Case-Schleife. Es stellt so eine Art Code-Übersetzung dar.


    Einen Teil davon habe ich schon implementiert. Ist aber noch etwas durcheinander und momentan scheitere ich gerade, beim Durchlaufen des Arrays. Ich habe mit nämlich einen eigenen Datentyp für die FB-Codes definiert, bestehend aus uint8_t je Code. Durch den Datentyp kann ich aber nicht mehr so einfach mit einem Index arbeiten. Ich schau es mir später nochmal an und poste ggf. den Code dazu.


    Danke für die vielen Ideen.

  • Hab den vorschlag von Pesi mal versucht in code umzusetzen: [...]
    for( i=1, i<= Maxcode, i++ )


    Der Vollständigkeit halber, falls einer versucht den Code zu übersetzen:
    Wenn ich mich recht erinnere ist die korrekte Syntax für for-Schleifen in C

    Code
    for (start_cmd; condition; loop_cmd)


    sprich die einelnen Ausdrücke mit Semikolon getrennt, statt mit Komma. Werden mehrere Anweisungen per Komma getrennt, versteht der Compiler das als zu demselben Ausdruck gehörig. So ist z.B.

    Code
    for (i=0, r=0.0; i<end; r+=i*dr, ++i)


    zulässig. Es würden zwei Variablen zu Schleifenbeginn initialisiert und beide nach jedem Schleifendurchlauf hochgezählt/verändert (zumindest in C++, ob das in C mit den Kommata auch funktioniert weiß ich nicht. Auf jeden Fall gehört auch in C da ein Semikolon als Trenner hin).

  • Sorry für OT again, aber wenn wir schon mal dabei sind ...


    Code
    for( i=1; i<= Maxcode; i++ )
    {
          if( recivedCode == fb[afb][i] )
          {
                command = i;
    
                // um die Schleife schneller zu beenden ( nicht notwendig)
                i = Maxcode;
          }
    }


    Da fällt mir noch was auf: um eine Schleife direkt zu beenden gibt es das keyword "break".
    Also statt den Zähler i per Hand hochzusetzen, damit die end condition erfüllt wird, einfach break; schreiben. Spart immerhin eine Zuweisung und einen Vergleich - und ist deutlich saubererer Stil.

  • Ich mache es letztlich ähnlich:


    iFBindex = Nummer der Fernbedienung
    code = Empfang der Fernbedienung
    FB = Array der FB-Codes



    Ein Problem habe ich nur damit:


    FB[iFBindex][iKeyIndex]


    weil:



    Damit kann ich den 2. Index iKeyIndex nicht mehr verwenden. Aber eigentlich brauche ich den ganzen typisierten Spaß gar nicht und könnte das als reines Array aufbauen.

  • Ähhhm. Stimmt. Wenn man den Index als Ausgabecode nimt kann das nach einem Sortieren nicht mehr funktionieren. Mann müsste dann zu jedem "Eingabecode" auch den "Ausgabecode" als Tupel in einem Feldelement speichern. Dann ist die Reihenfolge unerheblich. Je nach dem (Anzahl und Dichte der Codes) kann das eine (Index als Ausgabecode) oder das andere (Tupel) besser sein.

  • genau das war es, was ich in meinem nicht-Informatiker-Deutsch ausdrücken wollte... ;)


    wie viele Codes braucht man denn letztlich bei so nem Controller...? heller, dunkler, Hue und Sättigung rauf/runter, Programm auswählen (z.B. Zifferntasten 0-9), Speed up/down, Einstellungen speichern, an/aus, was noch...?


    also letztlich so 20-24 relevante Codes, da braucht es wohl (unbesehen, Einschätzung, in Assembler auf jeden Fall) für das einfache Schleife durchlaufen und vergleichen unter'm Strich weniger Speicher für's Programm und Laufzeit als binäre Suche und Quicksort und Tupel, auf jeden Fall ist es deutlich einfacher... ;)


    Turi, läuft das nun so....? - ich habe aus Neugier mal gegoogelt, das mit dem zweidimensionalen Array für die Codes müsste doch dann wohl eher so heissen:

    Code
    int FB [4] [22] = {
    
    
          { 0, 16, 17, 32, 33, 11, 47, 59, 43, 44, 53, 13, 46, 42, 60, 56, 19, 18, 20, 21, 12, 10 },
          { 5, 16, 17, 32, 33, 11, 15, 60, 53, 54, 41, 45, 50, 52, 55, 39, 44, 46, 47, 42, 12, 10 },
          { 8, 16, 17, 32, 33, 34, 99, 99,  3, 44, 99, 13, 46, 42, 60, 56, 99, 99, 99, 99, 12, 10 },
          { 0, 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
    
    
    };

    ?


    Und dann kann man mit FB[iFBindex][iKeyIndex] eben den Wert rauslesen, also z.B. FB[1] [8] wäre dann 53...

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • Ja Pesi, es funktioniert erst mal mit dem Index-Zugriff. Irgendwo habe ich habe noch einen Bug drin, denn es funktioniert momentan nur bei der Master-FB. Aber das wird sich finden lassen.


    Das mit der Typisierung wäre nicht schlecht gewesen, da man so besser weiß, was für ein Code hinter Index 7 steckt. Es gibt da sicher auch noch eine Möglichkeit mit Zeigern und Typ-casting. Aber da kenne ich mich leider zu wenig aus und habe nicht die Geduld.

  • Was mir gerade noch einfällt, wenn du vor hast, dass der Nutzer die Codes für seine FB programmieren kann, dann solltest du noch ne Überwachung oder Sperre einbauen, dass man einen FB-Code nicht doppelt nehmen kann. (bei einer FB)


    EDIT:
    turi: was genau meinst du mit Typisierung?

  • turi: verständlich.... ;)


    k.A. wie man das in C normal macht, in asm (geht aber doch in C bestimmt auch..?) würde ich da einfach Kommentare machen, so in der Art:



    oder meintest Du, dass Du dann beim Case eben schreiben kannst "Case FBvolup" statt z.B. "Case 1"...?


    in asm geht das mit Aliasen, also ich schreibe dann halt vorher irgendwo .equ FBvolup = 1 - das geht doch in C auch mit #define FBvolup = 1 oder..?

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

    Einmal editiert, zuletzt von Pesi ()

  • Das mit der Typisierung wäre nicht schlecht gewesen, da man so besser weiß, was für ein Code hinter Index 7 steckt.

    Wenn du damit obigen "typedef struct ..." meinst: Ja, klar geht das nicht. Ein struct ist ein Struct und kein Array. Wenn du weißt wie der Compiler den Struct im Speicher verteilt kannst du höchstens einen Zeiger auf solch einen Struct zu einem Array casten. Das iss aber nicht die feine, englische... Wenn du aussagekräftige Namen für die Indices haben wilst, dann definier mit etwas a la "typedef enum {FB_UP, FB_DOWN, FB_RIGHT, FB_LEFT} fb_code_idx_t;" halt einen enum-Typen. Wenn du eine Variable von solch einem Typen als Index für ein "switch-case" verwendet kann der GCC auch fehlende "case" für Codes anzeigen.

  • jkunz hat es erfasst, was ich mit Typisierung meinte: das typedef struct. Ich habe das inzwischen entfernt und es ähnlich wie Pesi mit Kommentaren gemacht. Die einzelnen Befehle in der case-Schleife sind sprechend, momentan aber noch redundant per #define definiert. Speicher geht damit nicht verloren, aber es könnte mit dem Master-Code auseinander laufen, wenn man nicht aufpasst. Ich werde dashalb mal noch die Namen in den Mastercode einfügen. Dann ist es konsistent.


    Die Idee mit dem casting und Zeiger hatte ich auch schon, da ein uint8_t ja immer ein Byte groß ist, wäre das auch gegangen. Aber es macht das nicht einfacher/übersichtlicher.


    Das mit der Prüfung auf doppelten Code ist eine gute Idee. Ich habe ja selbst derzeit doppelte Codes vergeben (99), wenn die Taste nicht verfügbar ist. Das kommt leider bei einigen Geräten vor. Da müsste man nochmal intensiver auf die Suche gehen bei der Universal-FB.