Forum: Mikrocontroller und Digitale Elektronik Telnet Server - Menü Auswahl effizienter lösen


von Ardu (Gast)


Lesenswert?

Moin Moin,
ich arbeite zur Zeit an einem Telnet Server, dieser läuft auch ziemlich 
gut, jedoch in er Menü Auswahl nicht wirklich effizient.

Siehe Code:
1
void parseCommand() {
2
3
  if(cmd.equals("quit")) {
4
      client.stop();
5
      connected = false;
6
  
7
      else if(cmd.equals("1 on")) 
8
      {
9
        digitalWrite(2, HIGH);
10
      }
11
      
12
      else if(cmd.equals("1 off")) 
13
      {
14
        digitalWrite(2, LOW);
15
      }
16
      else if(cmd.equals("2 on")) 
17
      {
18
        digitalWrite(3, HIGH);
19
      }
20
      else if(cmd.equals("2 off")) 
21
      {
22
        digitalWrite(3, LOW);
23
      }
24
      else if(cmd.equals("3 on")) 
25
      {
26
        digitalWrite(4, HIGH);
27
      }
28
      else if(cmd.equals("3 off")) 
29
      {
30
        digitalWrite(4, LOW);
31
      }
32
      else if(cmd.equals("4 on")) 
33
      {
34
        digitalWrite(5, HIGH);
35
      }
36
      else if(cmd.equals("4 off")) 
37
      {
38
        digitalWrite(5, LOW);
39
      }
40
      
41
      else if(cmd.equals("all on"))
42
      {
43
        digitalWrite(2, HIGH);
44
        digitalWrite(3, HIGH);
45
        digitalWrite(4, HIGH);
46
        digitalWrite(5, HIGH);
47
      }
48
      else if(cmd.equals("all off"))
49
      {
50
         digitalWrite(2, LOW);
51
         digitalWrite(3, LOW);
52
         digitalWrite(4, LOW);
53
         digitalWrite(5, LOW);
54
      }
55
      
56
      
57
      else 
58
      {
59
        server.println("Invalid command, type help");
60
      }
61
  cmd = "";
62
}

ich habe es mit switch case versucht aber da Zeigt mir mein Compiler den 
Mittelfinger. Es läuft auf einem Arduino DUE ( ARM Cortex M3)

von Ardu (Gast)


Lesenswert?

hm :(

von Daniel S. (daniel_s49)


Lesenswert?

Ist die Frage jetzt, wie du diesen Code effizienter gestalten kannst 
oder ist die Frage warum dieser Code nicht compiliert?
Letzteres läge wohl an der fehlenden } vor dem ersten else if.

Für ersteres würde ich vermutlich den String am Leerzeichen trennen 
(split oder so - kenn die Arduino-Libs da nicht).
Wenn vorne zwischen '1' und '5', dann umwandeln in Zahl ('5'-'1'=5 - 
alternativ atoi()). Wenn hinten "off" dann LOW merken, sonst HIGH und 
dann mit den beiden Werten die digitalWrite() aufrufen.

von Stephan (Gast)


Lesenswert?

Ich würde den String auch decodieren macht das Programm universeller und 
den Code besser wartbar.

von Daniel A. (daniel-a)


Lesenswert?

Ich weiss nicht, ob es Effizienter ist, aber hier hatte ich einen 
iterativen ansatz vorgestellt:
Beitrag "Re: Arduino Serial ganze wörter abfragen"

Möglicherweise kann man hier etwas ähnliches machen.

von Ardu (Gast)


Lesenswert?

Daniel S. schrieb:
> Ist die Frage jetzt, wie du diesen Code effizienter gestalten
> kannst
> oder ist die Frage warum dieser Code nicht compiliert?
> Letzteres läge wohl an der fehlenden } vor dem ersten else if.
>
> Für ersteres würde ich vermutlich den String am Leerzeichen trennen
> (split oder so - kenn die Arduino-Libs da nicht).
> Wenn vorne zwischen '1' und '5', dann umwandeln in Zahl ('5'-'1'=5 -
> alternativ atoi()). Wenn hinten "off" dann LOW merken, sonst HIGH und
> dann mit den beiden Werten die digitalWrite() aufrufen.

ne es funktioniert ja, ich suche nach alternativen, bzw weniger schreib 
arbeit bzw weniger if Anweisungen.

Daniel A. schrieb:
> Ich weiss nicht, ob es Effizienter ist, aber hier hatte ich einen
> iterativen ansatz vorgestellt:
> Beitrag "Re: Arduino Serial ganze wörter abfragen"
>
> Möglicherweise kann man hier etwas ähnliches machen.

werde es mir mal angucken :)

von nicht“Gast“ (Gast)


Lesenswert?

Moin,

Du kannst die Kommandos im einem struckt ablegen und dazu einen 
Funktionzeiger.
1
typedef struck {
2
   char *command,
3
   void (*commandFunction)(int arg1, bool arg2 )
4
} command;

Dann machst du dir ein Array aus Commands
1
command commandList[] = { { 1 on, funktionZumAusführen},
2
                          { 1 off, NeudefInition}};

Dann kannst du einfach über das Array iterieren und bei einem Treffer 
mit Equal die funktion ausführen.

Ich hoffe, ich konnte den Ansatz verständlich machen. Da ist leider 
ziemlich umständlich mit den Tablet.

Grüße

von Bernd K. (prof7bit)


Lesenswert?

Du könntest den String so parsen dass Du einerseits ein Kommando "on" 
oder "off" (oder noch andere Kommandos) erkennst und andererseits deren 
Argument(e) (in diesem Falle eine Zahl oder "all") (oder kein Argument 
bei manchen anderen Kommandos).

Dann musst Du Dir eine sinnvolle simple und konsistente und einfach zu 
parsende Grammatik für alle Deine jetzigen und zukünftigen Kommandos 
ausdenken (zum Beispiel wäre es evtl leichter zu parsen wenn das 
Kommando zuerst und dann erst die (optionalen) Argumente kommen.

von Andi (Gast)


Lesenswert?

setz den command an erste stelle und schreib einen generischen handler.
Sprich
1
void onHandler(char * argp, int argLeng) {
2
3
//zahl zu beginn von argp auswerten und  pin setzen
4
}
5
  
6
struct cmdDef {
7
  char * cmd;
8
  void (fun*)(char * argp, int argLen);
9
};
10
11
struct cmdDef handlers[] = {
12
  {"on", &onHandler},
13
  {"off", &ofHandler}
14
};

von Andi (Gast)


Lesenswert?

Du prüfst dann in einem for-loop, ob der befehlsstring mit einem der 
commands beginnt. Ist das der fall, wird der entsprechende handler 
aufgerufen.
Dabei ist argp ein pointer auf das erste zeichen nach dem befehl, argLen 
die anzahl der noch bleibenden zeichen.

von Klaus (Gast)


Lesenswert?

Ardu schrieb:
> else if(cmd.equals("1 on"))

Aber in die Doku schreiben, daß nur exakt 1 Leerzeichen zwischen der 
Zahl und dem Kommando zulässig ist.

MfG Klaus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.