PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Asuro soll auf auf befehle folgen



Touby_van
22.02.2008, 14:46
hi zusammen

habe ein kleines problem. nun ich habe einen code geschrieben wo mir der asuro via terminalprogramm einen serRide erhält und dann anhand dieser eingabe verschieden handelt. sprich mir im moment noch einfach eine antwort geben soll.

das problem ist nun das ich genau zwei mal eine eingabe machen kann und er danach nur noch ein zeichen einliest.


#include "asuro.h"


int main(void)
{
unsigned char data[] = "0123";

Init();

while(1) {

SerRead (data,3,0);

if (data[0] == 'A' && data[1] == 'S' && data[2] == 'U')
SerWrite("HALLO!",6);

else if
(data[0] == 'B' && data[1] == 'O' && data[2] == 'L')
SerWrite("gang1!",6);

else if
(data[0] == 'C' && data[1] == 'I' && data[2] == 'R')
SerWrite("gang2!",6);

else if
(data[0] == 'D' && data[1] == 'E' && data[2] == 'P')
SerWrite("gang3!",6);

else

SerWrite("falsch",6);
}
return 0;
}

damaltor
22.02.2008, 19:39
was meinst du genau? du kannst zweimal drei zeichen eingeben, und dann immer nur noch eines?

spontan denke ich ist dein quellcode ok, kann ihn leider gerade nicht testen...

du kannst höchstens mal versuchen, die variable data auch nur 3 zeichen lang zu machen, also

unsigned char data[] = "12"

(das letzte zeichen wird automatisch mit dem wert null gefüll, deine variable von oben ist also 5 zeichen lang!)
oder noch einfacher

unsigned char data[3];

evtl hilfts was...

BlazeX
22.02.2008, 21:21
...3 zeichen lang zu machen, also

unsigned char data[] = "12"

(das letzte zeichen wird automatisch mit dem wert null gefüll, deine variable von oben ist also 5 zeichen lang!)
oder noch einfacher

unsigned char data[3];...

Also ich kenne das anders.
unsigned char data[] = "12" ist genau 2 Zeichen lang.

angenommen man nimmt char data[10],
strcpy(data,"123456789") hägnt automatisch ne binäre 0 an. Aber der Speicherbereich wird nicht vergrößert. nur eventuell der nächstfolgende überschrieben (das kann schwere Folgen haben), aber für solche fälle gibts ja strncpy...

Das was du geschrieben hast stimmt nicht. Und auch dass sein Array aus 5 Zeichen bestehtist Käse.

im Zweifel mit sizeof nochmal nachhaken

Aber dass data[3] aus 3 Byte besteht stimmt.

Hansi41
22.02.2008, 22:00
mit strcpy da hast du recht, aber ich kann mir auch nicht erklären, warum da snicht funktioniert....
hatte mal ähnlichen quellcode und der ha tfunktioniert...

Touby_van
22.02.2008, 22:20
danke für eure bemühung mir zu antworten also in der schule haben wir gelernt das \0 automatisch nach einem char folgt ob diese jedoch ein einzelnes byte nun braucht oder nicht weis ich auch nicht mehr so genau

nun um mein problem fileicht ein wenig zu präzisieren

via terminal programm sag ich dem asuro z.b ASU. beim ersten mal gibt er mir hallo! zurück beim zweiten mal ASU eingeben ebenfals ein hallo! doch beim dritten mal kann ich nur noch A und dan folgt gleich falsch! und das wiederholt sich dan er gibt mir gar nicht mehr die möglichkeit drei zeichen einzugeben.???

zerush
22.02.2008, 22:48
Also ich kenne das anders.
unsigned char data[] = "12" ist genau 2 Zeichen lang.

[...]

Das was du geschrieben hast stimmt nicht. Und auch dass sein Array aus 5 Zeichen bestehtist Käse.

im Zweifel mit sizeof nochmal nachhaken

Da muss ich dir widersprechen!
Also damaltor hat hier voll recht!!!
Wenn du ein Array mit einem String initialisierst, ist das Array automatisch ein Byte größer!

unsigned char data[] = "12" ist somit genau 3 Byte groß.
Und ja das kommt auch bei sizeof(data) raus!!

data[0] == '1'
data[1] == '2'
data[2] == 0

Also das einzige was Käse ist, ist das was du geschriebn hast!

BTT:
Kannst du nicht anstatt "falsch" einfach mal zurückgeben, was empfangen wurde?

BlazeX
22.02.2008, 22:54
@Zerush: Sorry! Irgenwo habe ich es anders gelesen...

Vieleicht liegt es daran dass SerRead nicht wartet bis der Puffer gefüllt ist, sonder eine gewisse Zeit auf Zeichen wartet, diese in den Puffer schreibt, den Rest mit 'T' füllt, und wenn das Haperterminal seine Zeichen zu spät sendet ist im Puffer nut "TTT". Also mal den 3. Parameter von SerRead auf zum Beispiel 5 setzten und sehen was passiert.

Das mit der binären 0 erklär ich hier mal kurz:
Ein String (z.B.: char String[256]) kann beispielsweise mit cin(C++) eingelesen werden, wenn der Benutzer aber ein Wort eingibt,was nur 200 Zeichen enthält, dann sind die letzten 56 Zeichen "Datenmüll". Damit das nicht passiert, wird bei der Eingabe eine '\0' angehängt, und bei der Verarbeitung oder Ausgabe immer nur bis zur binären 0 gearbeitet (oder ab da angehängt), es sei denn der String-Puffer ist komplett gefüllt, dann wird bis zum Ende des Puffers ausgegeben. So wird immer nur der wirklich genutzte Teil ausgegeben.

Fazit: Mit SerRead kannst du schlimmstenfalls nur einen Teil von dem was gesendet wurde empfangen.
Es wäre kompliziert, aber du könntest auch ein Programm schreiben was die Daten (Befehle wie Fahr geradeaus) zum ASURO sendet (mit char mehr als 200 Möglichkeiten), Der sendet sie dann wieder zurück um zu überprüfen ob er auch die richtigen bekommen hat. Bei größeren Puffern (wie zb "GGGGGG" für geradeaus), wäre es sicherer.
Probier das mal, damit kannst du zwar den ASURO nur steuern aber kannst es ja ändern. https://www.roboternetz.de/phpBB2/viewtopic.php?t=37993&sid=5aa70aa517c1209788384317ee631245

zerush
22.02.2008, 23:15
@BlazeX:
Kein Problem... wahrscheinlich hast du es verwechselt mit:
unsigned char data[3] = {1, 2, 3} - das ist nämlich genau 3 Byte groß.

Ich habe leider keinen ASURO, daher weiß ich nicht was da für Libs bei sind... sieht man irgendwo wie die SerRead() implementiert wurde?

Sternthaler
23.02.2008, 00:56
Hallo zusammen.
Und ein herzliches willkommen im Forum an Touby_van.

Also erst einmal zur Funktion SerRead().
Touby_van hat die Funktion schon richtig aufgerufen mit einer 0 als letzten Parameter. Dadurch wartet die Funktion nämlich darauf das 3 Zeichen empfangen werden, bevor sie überhaupt wieder zurück kommt.
Die Anzahl der Bytes in der Variablen data[] sind 5 Bytes. Die Zeichen "0123" und das angehängte \0 werden vorbelegt und als Speicher reserviert.

Der Teufel steckt hier im Timing.
Probiert mal:
#include "asuro.h"

int main(void)
{
unsigned char data[] = "0123";
unsigned int i;

Init ();

while (1)
{
for (i = 0; i < 100; i++)
Sleep (72);

SerRead (data, 3, 0);

for (i = 0; i < 100; i++)
Sleep (72);

if (data[0] == 'A' && data[1] == 'S' && data[2] == 'U')
SerWrite ("HALLO!", 6);

else if (data[0] == 'B' && data[1] == 'O' && data[2] == 'L')
SerWrite ("gang1!", 6);

else if (data[0] == 'C' && data[1] == 'I' && data[2] == 'R')
SerWrite ("gang2!", 6);

else if (data[0] == 'D' && data[1] == 'E' && data[2] == 'P')
SerWrite ("gang3!", 6);

else
SerWrite ("falsch", 6);
}
return 0;
}
Die Verzögerung bringt es ans laufen. (Sie dürfen auch kürzer sein.)
Eine der Warteschleifen kann weg. Welche, müsst ihr mir erklären ;-)

Gruß Sternthaler

damaltor
23.02.2008, 14:41
eine null wird IMMER angehängt, wenn der initialisierungsstring in doppeltan anführungszeichen " steht.

char data[] = "12"; // data[0] = "1", data[1] = "2", data[2] = \0
char data[] = { '1','2'} // data[0] = "1", data[1] = "2" (kein data[3]!)