Peter II schrieb:> du hast nicht die doku glesen, was der return wert aussagt.ben schrieb:> Wo finde ich denn eine vernünftige Funktions Referenze über die AVR> Funktionsbibliotheken?
Hahahahahahaha...Hauptsache drauflosklimpern...bei Problemen hilft das
Spasti-Forum hier.
ben schrieb:> Wo finde ich denn eine vernünftige Funktions Referenze über die AVR> Funktionsbibliotheken?
Die sollte eigentlich in deinem C-Lehrbuch zu finden sein, wenn du schon
das (sicherlich nicht kleine) Kapitel über 'Stringverarbeitung in C'
nicht gelesen hast. Solltest du lesen! Denn gerade über
Stringverarbeitung gibt es in C eine Menge zu erzählen und zu beachten.
Ansonsten: Tante Google findet normalerweise mit dem Funktionsnamen auch
sofort eine Referenzsseite.
"C strcmp"
sollte eigentlich weiter helfen
Als Minimalkurzversion des Allernotwendigsten kann man auch da mal
reinschauen
String-Verarbeitung in C
Karl Heinz Buchegger schrieb:> Als Minimalkurzversion des Allernotwendigsten kann man auch da mal> reinschauen> String-Verarbeitung in C
Und als Linux-User tippt man einfach "man strcmp" in die Kommandozeile
und hat gleich die komplette Beschreibung der Funktion.
Kan asta schrieb:> Hahahahahahaha...Hauptsache drauflosklimpern...bei Problemen hilft das> Spasti-Forum hier.
So läufts doch. Ne Schleife tut nicht was sie soll? Erstmal nen Thread
starten und 1000 Zeilen Code dumpen. Wozu selbst denken und überlegen?
Mal ne Debug-Ausgabe reinmachen? Mal den LA raukramen? Nööö.
Ich meine hier scheitert es ja bereits am Nachschauen des Syntax für
eine Funktion. Klar, das Forum wirds wissen.
Also dann tu ich mal was von mir erwartet wird:
Lieber TE, die strcmp gibt 0 zurück wenn die Strings gleich sind.
gruß cyblord
hab eine consolen anwendung in c geschrieben und meinen fehler denke ich
mal gefunden.
1
intmain(void)
2
{
3
chara[20]="OK\r\n";
4
charb[20]="OK\r\n";
5
6
if(!strcmp(a,b))
7
{
8
printf("true");
9
}else{
10
printf("false");
11
}
12
13
return0;
14
}
so funktionierts in dem Consolen Projekt aber wenn ich das auf den
Mikrocontroller portiere und über die UART Schnittstelle ein "OK\r\n"
bekomme und vergleiche sagt er mir das sie nicht gleich sind aber ich
habe mir beide ausgeben lassen über mein terminal programm und sie sind
100% identlisch. Was kann ich noch probieren?
ben schrieb:> aber ich> habe mir beide ausgeben lassen über mein terminal programm und sie sind> 100% identlisch
lass sie dir als Hex anzeigen, dann wirst du den unterschied sehen.
ben schrieb:> Was kann ich noch probieren?
Systematisch den Fehler suchen. Also woher weißt du dass deine Funktion
meint die String wären nicht unterschiedlich? Eventuell liegts an deiner
led_ok Funktion. Immerhin hast du in diesem Beispiel korrekt die strcmp
negiert. Hast du das letztendlich in deinem AVR Program auch gemacht? Im
Eingangspost war es noch nicht so.
gruß cyblord
Hab mir das alles direkt als Hex ausgeben lassen und gebe es auch nach
einander als Hex ein. Da sollte kein Fehler sein.
Hier die komplette Vergleichsfunktion:
1
voiduart_cmp_answer(void)
2
{
3
uart_c('\n');
4
uart_str(uart_answer);
5
uart_c('\n');
6
if(strcmp(uart_answer,"OK\r\n")==0)
7
{
8
uart_str("alles ok!!!\n");
9
}else{
10
uart_str("fehler!!!\n");
11
}
12
}
Der einzige Unterschied der mir noch einfällt ist das die variable
uart_answer kein \0 hat. Wird dieses Zeichen mit vergleichen oder wie
bei einer Ausgabe Funktion ignoriert?
ben schrieb:> habe mir beide ausgeben lassen über mein terminal programm und sie sind> 100% identlisch.
Wie hast du sie dir ausgeben lassen?
Die sind garantiert nicht identisch, sonst hätte strcmp das bemerkt.
Führende Leerzeichen? Ist die \r\n tatsächlich genau so in beiden
Strings enthalten? Gibt es da ev. noch nachlaufende Leerzeichen?
Bei der Ausgabe (es sei denn natürlich man sieht sich das alles auf
Byte-Hex Ebene an) muss man ein wenig vorsichtig sein und auch ins
Kalkül ziehen, dass es in den Strings Zeichen gibt, die man auf dem
Terminal bei einer reinen Textausgabe nicht sieht. Wie zb Leerzeichen,
Tabulator oder auch Zeilenumbruch. Da heist es dann: Wie kann ich meine
Ausgabe so gestalten, dass ich auch auf solche Dinge mal einen Blick
werfen kann und mir die Ausgabe darüber etwas erzählt.
ben schrieb:> Der einzige Unterschied der mir noch einfällt ist das die variable> uart_answer kein \0 hat.
Den muss sie haben, sonst ist es in erster Instanz gar kein String. Ein
String endet dort, wo das \0 ist.
> Wird dieses Zeichen mit vergleichen oder wie> bei einer Ausgabe Funktion ignoriert?
Da alle Strings IMMER mit einem \0 enden, macht es wenig Sinn, das extra
zu vergleichen. Durch die Art und Weise wie Strings verglichen werden,
fällt das automatisch an. Der Vergleich basiert darauf, das im Grunde
das erste Byte gesucht wird, welches sich in beiden Strings
unterscheidet. Gelingt dies, ehe \0 erreicht wird, dann sind die Strings
unterschiedlich.
Scheinbar stimmt die Länge der beiden Strings schon nicht über ein. Ich
bin nur von dem ausgegangen, was mir das Terminalprogramm angezeigt hat
und was ich eingegeben habe.
Ich werde es weiter probieren. Danke trotzdem.
ben schrieb:> Scheinbar stimmt die Länge der beiden Strings schon nicht über ein. Ich> bin nur von dem ausgegangen, was mir das Terminalprogramm angezeigt hat> und was ich eingegeben habe.
Das stinkt nach dem leidigen \r\n Problem.
Hinweis:
Es ist absolut vernünftig, wenn die Einelesefunktion für Zeilen die
unausweichlichen \r oder \n gleich entfernt und nicht im String anlegt.
D.h. in deinem Programm brauchst du dich dann damit nicht mehr
rumschlagen. Von der Zeileneinlesefunktion kriegst du den String "OK"
und nur diesen String. Egal, ob jetzt das Terminal (oder allgemeiner:
die UART Gegenstellen) eine Zeile mit \n, mit \r oder mit \r\n
abschliesst. Wenn du die unterschiedlichen Varianten immer und überall
quer durch das ganze Programm berücksichtigen musst, dann wirds
aufwändig. Aber im Grunde braucht diese Zeichen ja kein Mensch. Du weißt
ja, dass es sich bei dem String um eine komplette Zeile von der Eingabe
handelt.
Nein an der \0 lag es nicht.
jetzt will ich alle \r und \n aus dem string raushalten doch das gelingt
mir nicht.. mit:
1
unsignedcharincomming=UDR;
2
3
...
4
5
if(incomming!=13||incomming!=10)
6
{
7
uart_answer[uart_answer_count]=incomming;
8
uart_answer_count++;
9
}
wenn ich den String immernoch ausgeben lasse, hat er ein \r also 13 oder
0x0D wie man es auch immer nennen will.
Hab ich da etwas in meiner if-Anweisung falsch?
ben schrieb:> Hab ich da etwas in meiner if-Anweisung falsch?
Seit wann schreibt man incoming mit 2 m? Da ist schonmal der erste
Fehler...
Dir fehlen Grundlagen zur String-Verarbeitung.
ben schrieb:> Nein an der \0 lag es nicht.
Doch. Du vergisst, den String zu terminieren!
Das folgende ist zwar schon mal besser, weil Du '\n' und '\r' nicht mit
Dir rumschleppen musst, aber beseitigt nicht Dein Problem.
> if(incomming != 13 || incomming != 10)
Hier muss ein && statt ein || hin.
> {> uart_answer[uart_answer_count] = incomming;> uart_answer_count++;> }
Schon besser, aber da fehlt immer noch ein
uart_answer[uart_answer_count] = '\0';
am Ende (Deiner Einleseschleife). Zeig doch mal den kompletten Code
statt diese Fitzelchen!
Übrigends: verständlicher wäre
if(incomming != '\r' && incomming != '\n')
statt
if(incomming != 13 && incomming != 10)
Den Fehler macht wohl jeder mal.
Gedankenhilfe:
Für jede Zahl, egal was sie ist, gilt
sie ist entweder NICHT 13
oder sie ist NICHT 10
selbst dann nicht wenn die Zahl 13 ist. Denn 13 ist ja nicht gleich 10.
d.h. egal was deine Zahl ist, diese Bedingung ist in ihrer Gesamtheit
für jede Zahl IMMER erfüllt.
(Das dahinerliegende Problem: Wir benutzen im Alltag die Wörter 'nicht'
'und' 'oder' in einer laxen Form, die sehr darauf basiert, dass unser
Gegenüber weiß was wir meinen. Oft genug benutzen wir diese Wörter ganz
einfach falsch und wenn man es genau nimmt, dann bauen wir im Alltag
völlig falsche 'logische Operationen'. D.h. an dieser Stelle vorsichtig
sein. Da kann eine 'wortwörtliche' Übersetzung in eine
Programmiersprache ganz schnell in die Hose gehen. Immer mit ein paar
Testbeispielen im Kopf durchspielen)
Frank M. schrieb:> ben schrieb:>> Nein an der \0 lag es nicht.>> Doch. Du vergisst, den String zu terminieren!
Das ist doch reine Spekulation bei dem Fitzelchen, den er gezeigt hat.
> am Ende (Deiner Einleseschleife). Zeig doch mal den kompletten Code> statt diese Fitzelchen!
genau
Karl Heinz Buchegger schrieb:> Gedankenhilfe:> Für jede Zahl, egal was sie ist, gilt> sie ist entweder NICHT 13> oder sie ist NICHT 10
Ich merke es mir anders:
NOT (a || b) <==> NOT a && NOT b
Also:
Wenn CR oder NL, dann ignorieren
Dann andersherum
Wenn NICHT CR UND NICHT NL, dann speichern.
Karl Heinz Buchegger schrieb:> Das ist doch reine Spekulation bei dem Fitzelchen, den er gezeigt hat.
Klar ist das reine Spekulation, aber es ist die einzige Erklärung, warum
seine ursprüngliche strcmp-Variante (mit Vergleich auf 0, aber mit
"\r\n") nicht funktionierte. ;-)
Ich wette daher mal ein Bierchen ;-)
Kan asta schrieb:> uart_answer[uart_answer_count++] = incoming;> uart_answer[uart_answer_count] = 0x00;
VIEL zu langsam, weil ja immer die 0 geschrieben wird.
if(incomming != 13 && incomming != 10) {
uart_answer[uart_answer_count++] = incoming;
} else {
uart_answer[uart_answer_count] = 0x00;
}
Frank M. schrieb:> Karl Heinz Buchegger schrieb:>> Das ist doch reine Spekulation bei dem Fitzelchen, den er gezeigt hat.>> Klar ist das reine Spekulation, aber es ist die einzige Erklärung, warum> seine ursprüngliche strcmp-Variante (mit Vergleich auf 0, aber mit> "\r\n") nicht funktionierte. ;-)>> Ich wette daher mal ein Bierchen ;-)
ok. dann wette ich mal ein virtuelles Bierchen auf \r\n Probleme :-)
Peter II schrieb:> Kan asta schrieb:>> uart_answer[uart_answer_count++] = incoming;>> uart_answer[uart_answer_count] = 0x00;>> VIEL zu langsam, weil ja immer die 0 geschrieben wird.
Völlig wurscht, solange die Zeichen von der UART kommen.
Karl Heinz Buchegger schrieb:> Völlig wurscht, solange die Zeichen von der UART kommen.
Hast recht, wer benutzt schon Interrupts oder solchen Firlefanz.
Kan asta schrieb:> Ein Programmierer würde schreiben:>> uart_answer[uart_answer_count++] = incoming;> uart_answer[uart_answer_count] = 0x00;
Ein Programmierer würde vorher abprüfen, ob noch Platz ist für das
Zeichen && dem '\0'. Und ich vermute uart_answer[] besteht aus Chars,
dann würde ich zumindest auch ein char zuweisen ('\0') und nicht direkt
einen Ordinalwert. Macht vllt. keinen Unterschied, aber weist indirekt
auf die Verwendung von Char hin.
Peter II schrieb:> VIEL zu langsam, weil ja immer die 0 geschrieben wird.
Jepp.
> if(incomming != 13 && incomming != 10) {> uart_answer[uart_answer_count++] = incoming;> } else {> uart_answer[uart_answer_count] = 0x00;> }
Hm, auch dieses Fitzelchen überzeugt nicht richtig, weil hier die
Leseschleife mitsamt der Abbruchbedingung fehlt.
Besser:
Karl Heinz Buchegger schrieb:> Peter II schrieb:>> Kan asta schrieb:>>> uart_answer[uart_answer_count++] = incoming;>>> uart_answer[uart_answer_count] = 0x00;>>>> VIEL zu langsam, weil ja immer die 0 geschrieben wird.>> Völlig wurscht, solange die Zeichen von der UART kommen.
In erster Linie muss es richtig sein. Und dazu gehört auch, dass ein
\r\n nicht als 2 Eingabezeilen gemeldet werden.
Frank M. schrieb:> while ((incoming = uart_getc ()) != '\r' && incoming != '\n')> {> uart_answer[uart_answer_count++] = incoming;> }> uart_answer[uart_answer_count] = '\0';
nagut, dann noch die länge prüfen
Kan asta schrieb:> Karl Heinz Buchegger schrieb:>> Völlig wurscht, solange die Zeichen von der UART kommen.>> Hast recht, wer benutzt schon Interrupts oder solchen Firlefanz.
:-)
Jehova!
Peter II schrieb:> nagut, dann noch die länge prüfen
Meine (und Deine) Lösung haben ein Problem: Ein '\r' bricht die Schleife
ab und das '\n' bleibt im Input-Buffer und wird erst das nächste mal
eingelesen. Das führt dann beim Lesen der nächsten Antwort zu einer
"Leerzeile". Okay, die könnte man einfach ignorieren, aber korrekt wäre
es so:
1
while(uart_answer_count<BUFFER_LEN&&
2
(incoming=uart_getc())!='\n')// Bei NL abbrechen
3
{
4
if(incoming!='\r')// CR ignorieren
5
{
6
uart_answer[uart_answer_count++]=incoming;
7
}
8
}
9
uart_answer[uart_answer_count]='\0';
Da kann man mal sehen, was da alles für Komplikationen eintreten können
;-)
Danke und Sorry für den dummen Logikfehler.. und das schlimem ist ich
murmel mir auch die ganze Zeit ein UND vor...
Ich habe den String terminiert. Das war aber im Quellcode weiter unten
und zu einer anderen Bedingung.
Kan asta schrieb:> Umsetzung einer UART-Kommunikation:> [Mist]
Sag mal, kannst Du auch mal was anderes als Unsinn schreiben? Er
kommuniziert mit einem Modem. Willst Du da jetzt eine Statemachine mit
256 Funktionen draus machen?
Modem? Stand nirgends. Ich vermute, der TO will mit verschiedenen
Strings verschiedene Leds an- und abschalten. Das würde zu seinen
Programmierkenntnissen passen.
State Machine? Seh ich nirgens.
256 Funktionen? Du darfst den Array auch mit Null-Zeigern auffüllen.
So kann der TO dann sogar noch per UART resetten.
Frank, sei mir nicht böse aber überlass das Denken besser den anderen.
Kan asta schrieb:> Modem? Stand nirgends. Ich vermute, der TO will mit verschiedenen> Strings verschiedene Leds an- und abschalten.
Dann erklär mal, warum er auf seinem µC die Antwort "OK\r\n" auswerten
will und nicht "Lampe1 an" oder "Lampe5 aus". Der String "OK\r\n" deutet
auf die Antwort eines Hayes-kompatiblen Modems (wahrscheinlich ein
Bluetooth-Adapter) hin.
> Das würde zu seinen Programmierkenntnissen passen.
Das ist reine Spekulation Deinerseits.
> State Machine? Seh ich nirgens.
Ein AT-kompatibles Modem gibt Strings wie "OK\r\n" bzw. "CONNECT\r\n"
und keine Einzelzeichen aus. Um solche Strings per Einzelzeichen-Analyse
auszuwerten - wie Du es vorschlägst - braucht man eine Statemachine.
> 256 Funktionen? Du darfst den Array auch mit Null-Zeigern auffüllen.> So kann der TO dann sogar noch per UART resetten.
Witzbold. Der aktive Part ist hier der µC und nicht das Gegenüber, das
geht klar aus dem String "OK\r\n" hervor. Der µC sendet einen Befehl und
das Gegenüber antwortet mit "OK\r\n".
Oder hast Du schon mal einen Befehl namens "OK" gesehen?
> Frank, sei mir nicht böse aber überlass das Denken besser den anderen.
Gerne anderen, aber nicht Dir.
Frank M. schrieb:> Um solche Strings per Einzelzeichen-Analyse> auszuwerten - wie Du es vorschlägst - braucht man eine Statemachine.
Alles falsche Annahmen, die du aus dem String "OK" ziehst.
Ich sage auch manchmal "OK". Bin ich ein Modem?
Kan
Reiß dich ein wenig am Riemen, sonst bist du ganz schnell gesperrt.
Es ist schon teilweise schwer genug Hilfe zu geben. Auf Klugscheisser
wie dich können wir hier gerne verzichten. (Ist ja nicht nur in diesem
Thread so)
Kan asta schrieb:> Karl,> sei nicht so streng. Irgendwie ist es hier> doch manchmal auch ganz unterhaltsam.
Das ist aber kein Grund, in dem Masse beleidigend zu werden, wie du es
in letzter Zeit häufig bist.
Kommt immer aufs Gegenüber an.
Schau mal im Thread "AVR FAT32 beschädigte Dateien",
da hab ich hervorragend Hilfe geleistet.
Nur weil mein Umgangston ein bisschen derber ist,
muss man nicht gleich SPERREN und ZENSIEREN.
Karl Heinz Buchegger schrieb:> Kan>> Reiß dich ein wenig am Riemen, sonst bist du ganz schnell gesperrt.> Es ist schon teilweise schwer genug Hilfe zu geben. Auf Klugscheisser> wie dich können wir hier gerne verzichten. (Ist ja nicht nur in diesem> Thread so)
Endlich wird diesem Vogel mal die Meinung gesagt. Weiter so!
Kan asta schrieb:> Kommt immer aufs Gegenüber an.> Schau mal im Thread "AVR FAT32 beschädigte Dateien",> da hab ich hervorragend Hilfe geleistet.
und das berechtigt dich andauernd ausfallend zu werden? interessante
Logik.
Kan asta schrieb:> Nur weil mein Umgangston ein bisschen derber ist,> muss man nicht gleich SPERREN und ZENSIEREN.
Doch muss man. Sonst lernst du es nicht.
Karl Heinz Buchegger schrieb:> uart_str ist die Ausgabefunktion.> Der String selber steht in uart_answer.
Ja, jetzt wo Du es sagst, rieche ich es auch ;-)