Hallo zusammen,
seit längerer Zeit suche ich nach einem einigermaßen elegantem Weg, AT-Kommandos zu interpretieren.
Diese starten, daher der Name, mit AT und werden dann mit weiteren (Steuer-)Zeichen aufgefüllt.
Der Abschluss erfolgt immer mit einem Carriage Return.
(Das prüfe ich beim füllen des Puffers und rufe dann die entsprechende Funktion auf)
So weit, so einfach:
uint8_t Buffer[10];
uint8_t Counter;
void ProcessInput(){
if(Counter < 3)
return;
if(Buffer[0] != 'A' || Buffer[1] != 'T')
return;
switch(Buffer[2]){
case 'I':
Serial.print("ELM 327");
break;
case 'D':
//Reset to default
Serial.print("OK");
break;
default:
Serial.print("?");
break;
}
//Carriage Return 13
Serial.write(0x0D);
//Prompt: >
Serial.write(0x3E);
}
Nun bestehen die Kommandos leider nicht alle aus 3 Zeichen, sondern allerhand möglichen Kombinationen:
ATD
ATD0
ATD1
ATDP
ATDPN
ATS0
ATS1
ATSI
ATSP
ATSH XX YY ZZ
(Das ist nur ein klitzekleiner Auszug der Kommandopalette)
Diese auch noch zum Überfluss Befehle und Werte freudig durchmischen.
So sieht der Fall mit dem "D" dann schnell so aus:
case 'D':
if(Counter == 3){
//Reset to default
Serial.print("OK");
}
if(Counter == 4){
//Describe Protocol
if(Buffer[3] == 'P')
Serial.print("ISO4711");
else
bool displayDlc = Buffer[3] == '1';
}
//Describe Protocol by number
if(Counter == 5)
Serial.print(3);
break;
Denke Ihr versteht schon worauf ich hinaus möchte ![]()
Das switch-case wird extrem unübersichtlich und die Kombination aus Längen- und Zeichenprüfung wird in anderen Beispielen nur noch schlimmer!
Jetzt könnte ich natürlich für jeden Fall mit mehreren Optionen eine Funktion aufrufen, welche wiederum ein switch-case beinhaltet. Und dieses im Zweifel noch eine weitere Funktion mit weiteren cases ![]()
Wenn man alles per if abfrühstückt, ist alles in einer Ebene und ein bisschen übersichtlicher:
uint8_t Buffer[10];
uint8_t Counter;
void ProcessInput(){
if(Counter < 3)
return;
if(Buffer[0] != 'A' || Buffer[1] != 'T')
return;
if(Compare('I')){
Serial.print("ELM 327");
}
if(Compare('D')){
//Reset to default
Serial.print("OK");
}
if(Compare('D', '0')){
bool displayDlc = false;
}
if(Compare('D', '1')){
bool displayDlc = true;
}
if(Compare('D', 'P')){
//Describe Protocol
Serial.print("ISO4711");
}
if(Compare('D', 'P', 'N')){
//Describe Protocol by number
Serial.print(3);
}
//Carriage Return 13
Serial.write(0x0D);
//Prompt: >
Serial.write(0x3E);
}
bool Compare(char c1){
if(Counter != 3)
return false;
return Buffer[2] == c1;
}
bool Compare(char c1, char c2){
if(Counter != 4)
return false;
return Buffer[2] == c1 && Buffer[3] == c2;
}
bool Compare(char c1, char c2, char c3){
if(Counter != 5)
return false;
return Buffer[2] == c1 && Buffer[3] == c2 && Buffer[3] == c3;
}
Diese "Lösung" kommt dann spätestens bei der Übergabe von Hex-Werten für z.B. "ATSH" zum Ende:
-> ATSH0CFF34
Wie seht Ihr das?
Den einen Königsweg wird es nicht geben, aber möglicherweise habt Ihr eine Idee wie man das besser lösen kann!
Vielen Dank und schönes Wochenende ![]()