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.
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?
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 :)