Hallo zusammen ich habe ein Problem um einen String zu empfangen und brauche Hilfe. Habe meinen µC AVR MT128 mit Hyperterminal verbunden, ich kann Zeichen senden und string senden. Ein einzelnes Zeichen kann ich auch empfangen aber ich muss ein String empfangen können. Diese string möchte ich dann wider an den uart senden können. Eigentlich möchte ich GPS Daten empfangen um sie zu vergleichen. wenn die Daten übereinstimmen soll dann ein 433 MHZ Sender eine Schranke öffnen. was ich habe ist folgendes empfangen von einzelnen zeichen unsigned char test=uart_getc(); // zeichen wird eingelesen if (test) { uart_putc(test); // zeichen wird ausgegeben } ich muss zugeben ich bin ein Anfänger und währe froh für ein bisschen Hilfe.
Wie wäre es einfach mal mit dem entsprechenden Tutorial? http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Empfang_von_Zeichenketten_.28Strings.29
Hi >Eigentlich möchte ich GPS Daten empfangen um sie zu vergleichen. wenn >die Daten übereinstimmen soll dann ein 433 MHZ Sender eine Schranke >öffnen. Das Ereignis wird nach mehreren Stunden Wartezeit an der gleichen Stelle bestimmt auch mal eintreten. Mit C kann ich dir nicht helfen. Aber mir deinem Ansatz wird es nicht so funktionieren, wie du denkst. MfG Spess
wie meinst du das ? ich bekomme NEMA Daten geliefert und diese sind eindeutig. ich will einen vergleich machen und wenn die werte übereinstimmen dann soll der 433 Mhz Sender das Signal senden um die Schranke zu öffnen, wenn die Schranke dann passiert wurde und das Auto hat sich bewegt dann ändern sich auch die NEMA Daten und der vergleich stimmt nicht mehr und der Sender sendet nicht mehr. wieso soll das nicht gehen verstehe ich nicht wäre nett wen du das genauer beschreiben würdest.
Weil es Gleichheit nicht gibt. Die Koordinaten beinhalten ein Rauschen, abhaengig von Wetter, Tageszeit, Satelliten, usw. Dh auch wenn du vor dem Tor stehst, so ist die koordinate einmal daneben, dann dahinter usw. Der Standardansatz wird sein, mit einem Radius, wo man innerhalb sein muss zu arbeiten.
Ich knüpf hier mal an... Mich würde es interessieren, wie man einen gesendeten String korrekt puffert und mit einem Befehlsrepertoir vergleicht in C++. Wie sicher ist es bei so einer seriellen Verbindung, dass bei korrekter Beschaltung des Quarzes und richtigen Einstellungen zb bei max 115kbauds. Können da einzelne Zeichen verloren gehen, wenn man die Zeichen im Interrupt in ein Array puffert? Macht man das mit einem Array? Oder gibt es da bessere Lösungen um gleich den stream der UART mit einem String im flash zu vergleichen? Danke und Gruß Karl
Hi
>wie meinst du das ? ich bekomme NEMA Daten geliefert und diese sind >eindeutig.
Das heisst, selbst wenn du deinene GPS-Empänger nicht bewegst, wirst du
trotzdem ständig andere Koordinaten empfangen.
MfG Spess
Karl wrote: > Ich knüpf hier mal an... Mich würde es interessieren, wie man einen > gesendeten String korrekt puffert und mit einem Befehlsrepertoir > vergleicht in C++. Indem man die Aufgaben aufteilt. Du hast 2 voneinander unabhängige Themenkreise zum einen muss ein String empfangen werden zum anderen muss dieser String ausgewertet werden String empfangen kann man im Grunde genauso machen, wie das in dem Tutoriallink weiter oben angegeben ist. In C++ würde man als Speicherfläche nicht unbedingt ein char Array nehmen, sondern mit einer String Klasse, zb std::string arbeiten, aber das Prinzip ist haarscharf dasselbe Wie man die String Auswertung macht, hängt davon ab, wie komplex die definierte Komamndo-Sprache gestaltet wird und auch wie umfangreich diese ist. Im einfachsten Fall ist das einfach nur ein Vergleich mit vorgegebenen Schlüsselwörtern und entsprechenden Aktionen dazu. Im komlpiziertesten Fall könnte man Techniken aus dem Compilerbau dazu benutzen um den empfangenen String in Einzelteile zu zerlegen und die Bedeutung des Empfangenen zu entschlüsseln. > Wie sicher ist es bei so einer seriellen Verbindung, > dass bei korrekter Beschaltung des Quarzes und richtigen Einstellungen > zb bei max 115kbauds. Können da einzelne Zeichen verloren gehen, wenn > man die Zeichen im Interrupt in ein Array puffert? Da den eigentlichen Empfang eines einzigen Zeichens ja die Hardware, unabhängig von deinem Programm macht, geht das schon mal relativ sicher gut. Störungen am Kabel mal aussen vor gelassen. In deinem Programm muss nur sicher gestellt sein, dass du die Zeichen nur rechtzeitig abholst. Mit einer Interrupt Steuerung ist das auch kein Problem. Bleibt nur noch: In deiner Interrupt Routine musst du die Zeichen irgendwo Zwischenspeichern. Du hast dafür keine endlose Speicherfläche zur Verfügung, also muss auch sichergestellt sein, dass die ertens ausreichend gross dimensioniert ist das Hauptprogramm auch eine Chance hat, den Buffer wieder mal auszuleeren > Macht man das mit > einem Array? Kann man machen. In C++ und bei einem einigermassen potenten µC könnte man auch einen std::vector oder einen std::string benutzen. Die künmmern sich dan selbsttätig darum, dass der Bufferspeicher vergrößert wird, falls notwendig. > Oder gibt es da bessere Lösungen um gleich den stream der > UART mit einem String im flash zu vergleichen? Keine gute Idee. Aufgabenteilung ist eines der wichtigsten Prinzipien in der Programmierung. Nur dadurch ensteht der Bausteincharakter von Bibliotheken. Der Empfang eines Strings hat erst mal nichts, aber auch gar nichts damit zu tun, was du mit dem String weiter machen möchtest. Also vermisch die Dinge auch nicht.
@Karl Heinz: Vielen Dank für die sehr gute Beschreibung. Das mit der Aufgabenteilung habe ich soweit verstanden, allerdings habe ich noch probleme zu verstehen, was du mit den Namespaces meinst. std (using namespace std) habe ich mal benutzt um consolenprogramme zu schreiben und um die Standardein und -ausgabe zu lesen und schreiben, mehr aber leider noch nicht. Da mein "Befehlssatz" eher mager (maximal 6-8Zeichen) sein soll, und ich mich mit Arrays besser auskenne, als mit Namespaces, bleibt mir erstmal nix anderes übrig, als das mit Arrays zu erschlagen. Nehmen wir mal an, ich empfange in der ISR die Zeichen und ich beschreibe jedesmal ein char array[i]=UDR, welcher vorher mit "\0" gefüllt ist und inkrementiere i solange bis entweder enter gedrückt wird oder i überläuft... Dann hätte ich doch schon mal mein Befehl gepuffert? und zwar in einem nullterminierten char array, also ein String? Und in der main könnte ich dann mein string mit meinem "Befehlsrepertoir" vergleichen mit zb stricmp()? vergleicht die bibfunktion stricmp() denn ein Array mit Nullterminierung, mit einem "xxxxxx"string? Würde mich über jede Hilfe und jeden Tip sehr freuen Vielen Dank nochmal, lg Karl
Karl wrote: > Nehmen wir mal an, ich empfange in der ISR die Zeichen und ich > beschreibe jedesmal ein char array[i]=UDR, welcher vorher mit "\0" > gefüllt ist und inkrementiere i solange bis entweder enter gedrückt wird > oder i überläuft... Yep. > Dann hätte ich doch schon mal mein Befehl gepuffert? und zwar in einem > nullterminierten char array, also ein String? Genau > Und in der main könnte ich dann mein string mit meinem > "Befehlsrepertoir" vergleichen mit zb stricmp()? > vergleicht die bibfunktion stricmp() denn ein Array mit > Nullterminierung, mit einem "xxxxxx"string? Klingt doch nach einem guten Plan. Das hier könnte dir noch ein paar Ideen liefern http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger
Hier hast du mal ein Beispiel wie man so was macht Die Funktion PutChar sendet ein Zeichen aus und die Funktion GetChar liest ein Zeichen ein Die Routine CharCount Gibt zurueck ob ueberhaupt ein Zeichen zum einlesen da ist Der empfangene String muss mit einem CR abgeschlossen sein und steht anschliessend in szStr zur weiterverarbeitung zu verfuegung. Wenn ein kompleter String eingelesen wurde gibt die Funktion eine 1 zurueck sonst eine 0 Gruss Helmi
Karl heinz Buchegger wrote: > Karl wrote: >> Ich knüpf hier mal an... Mich würde es interessieren, wie man einen >> gesendeten String korrekt puffert und mit einem Befehlsrepertoir >> vergleicht in C++. > > Indem man die Aufgaben aufteilt. > Du hast 2 voneinander unabhängige Themenkreise > zum einen muss ein String empfangen werden > zum anderen muss dieser String ausgewertet werden Exakt. Und das mit dem String empfangen geht ganz gut mit ein paar fertigen Libraries, dies es gibt - z.B. http://homepage.hispeed.ch/peterfleury/avr-software.html . Viel Erfolg! Gruß, Frank
Hallo habe immer noch Probleme mit dem empfangen von Strings. Ich benutze die Funktion in einer Header /* Zeichen empfangen */ uint8_t uart_getc(void) { while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar ; return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben } void uart_gets( char* Buffer, uint8_t MaxLen ) { uint8_t NextChar; uint8_t StringLen = 0; NextChar = uart_getc(); // Warte auf und empfange das nächste Zeichen // Sammle solange Zeichen, bis: // * entweder das String Ende Zeichen kam // * oder das aufnehmende Array voll ist while( NextChar != '\n' && StringLen < MaxLen - 1 ) { *Buffer++ = NextChar; StringLen++; NextChar = uart_getc(); } // Noch ein '\0' anhängen um einen Standard // C-String daraus zu machen *Buffer = '\0'; } in der Main rufe ich char Line[10]; // Array vom Typ int uart_gets( Line, sizeof( Line ) / sizeof( Line[0] ) ); nun will ich den String nachdem ich 10 Zeichen bzw enter gedrückt habe wider ausgeben auf den Heiperterminal und es geht nicht. ich benutze dafür uart_puts(Line); bei mir funktioniert das nicht was mache ich falsch die uart_puts sieht so aus ist in einer Header int uart_putc(unsigned char c) { while (!(UCSR1A & 0b00100000)); //waiting until buffer is ready to receive UDR1 = c; // sende zeichen return 0; } void uart_puts (char *s) { while (*s) { uart_putc(*s); s++; } } wenn ich einen string senden will z.b. mit uart_puts("hallo welt"); habe ich keine Probleme
Wojtek Szopieraj wrote: Hier gehts auf ... > uint8_t uart_getc(void) > { > while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar > ; > return UDR; // Zeichen aus UDR an Aufrufer > zurueckgeben > } also UDR Während hier gehts um > int uart_putc(unsigned char c) > { > while (!(UCSR1A & 0b00100000)); //waiting until buffer is ready to > receive > > UDR1 = c; // sende zeichen > return 0; > } also UDR1 Hast du wirklich 2 unabhängige USART im Einsatz?
kleiner Fehler beim kopieren, benutze nur den UCSR1A uint8_t uart_getc() { if (UCSR1A & 0b10000000) //if there is unreaded data return UDR1; else //no unreaded data return 0; } trotzdem weiß ich nicht weiter. kann es daran liegen dass das Programm in einer endlos- schleife läuft und dass wenn ich eine Zeichenkette eingeben will de µC dass gar nicht merkt ?
Wojtek Szopieraj wrote: > kleiner Fehler beim kopieren, > benutze nur den UCSR1A > uint8_t uart_getc() > { > if (UCSR1A & 0b10000000) //if there is unreaded data > return UDR1; > else //no unreaded data > return 0; > } > Diese uart_getc kann aber mit dem uart_gets von weiter oben nicht funktionieren. Sollen wir noch länger weiterraten oder bist du gewillt dein komplettes Programm mal zu posten?
1 | uint8_t uart_getc() |
2 | {
|
3 | if (UCSR1A & 0b10000000) //if there is unreaded data |
4 | return UDR1; |
5 | else //no unreaded data |
6 | return 0; |
7 | }
|
8 | |
9 | |
10 | void uart_gets( char* Buffer, unsigned int MaxLen ) |
11 | {
|
12 | unsigned int NextChar; |
13 | unsigned int StringLen = 0; |
14 | NextChar = uart_getc(); // Warte auf und empfange das nächste Zeichen |
die uart_getc wartet nicht auf ein Zeichen, sondern kehrt sofort zurück. Wobei ein Return Wert von 0 angibt, dass kein Zeichen vorliegt. Ich sehe aber in der uart_gets nichts, was tatsächlich auf ein Zeichen warten würde. Im Gegenteil: Der Kommentar deutet darauf hin, dass uart_gets auf die Funktion uart_getc baut, dass diese auf ein Zeichen wartet. Mit anderen Worten: die uart_gets füllt in Windeseile den Buffer mit 0 Bytes an und kehrt zurück. uart_gets liefert damit einen Leerstring. Die uart_getc, die du ursprünglich gepostet hast, hätte auf ein Zeichen gewartet. Warum hast du sie abgeändert?
vielen dank es geht, jetzt habe ich es auch gesehen dass ich ein was übergebe wenn kein Zeichen ankommt, ich bin ein Anfänger und aus Fehlern lernt man :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.