empfangene daten interpretieren
-
hallo allerseits
wir haben einen helikopter, der laut manual folgendes über einen bluetooth adapter auf unseren COM4 port sendet:
struct DATA { unsigned char ident; short angvel_pitch; short angvel_roll; short angvel_yaw; short acc_x; short acc_y; short acc_z; long angle_pitch; long angle_roll; unsigned char pitch; unsigned char roll; unsigned char thrust; unsigned char yaw; unsigned char command_status; unsigned short timeStamp; unsigned char chkSum; };
ausserdem immer davor noch zwei startbyted 'P' und 'I', sowei danach zwei stopbytes 'E' und 'Z'.
da nicht direkt der struct über den port gelesen werden kann, sondern wohl nur eine folge an bytes, empfangen wir die total 33 bytes in einem unsigned char buffer[33].
danach versuchen wir den struct und die darin enthaltenen zahlen wieder "zusammen zu basten":
input.ident=buffer[2]; input.angvel_pitch=short((buffer[3])|buffer[4]<<8); input.angvel_roll=short((buffer[5])|buffer[6]<<8); input.angvel_yaw=short((buffer[7])|buffer[8]<<8); input.acc_x=short((buffer[9])|buffer[10]<<8); input.acc_y=short((buffer[11])|buffer[12]<<8); input.acc_z=short((buffer[13])|buffer[14]<<8); input.angle_pitch=(long)((buffer[15])|((buffer[16])<<8)|((buffer[17])<<16)|((buffer[18])<<24)); input.angle_roll=(long)((buffer[19])|(buffer[20]<<8)|(buffer[21]<<16)|(buffer[22])<<24); input.pitch=buffer[23]; input.roll=buffer[24]; input.thrust=buffer[25]; input.yaw=buffer[26]; input.command_status=buffer[27]; input.timeStamp=short((buffer[28])|(buffer[29])<<8); input.chkSum=buffer[30];
irgendwo scheinen wir da allerdings einen fehler zu machen. teilweise stimmen die werte. es kommt aber dann vor, dass z.b. die beiden werte für angle_pitch und angle_roll plötzlich auf riesige werte springen und dann dort bleiben.
sieht jemand zufällig gerade wo hier fehler liegen könnten? irgendwo beim shiften?
falls es wichtig ist (z.b. für die byte anordnung), wir verwenden folgendes:
intel dentrino duo, win vista business, dev-c++ compiler, xBee USB bluetooth adapter.
mit portmon haben wir ausserdem festegestellt, dass die 33 bytes korrekt gelesen werden, und auch immer brav mit PI andfangen und mit EZ aufhören.
danke für jeden hinweis!
-
ich persönlich würde das mit nem Zeiger machen, also folgendermaßen:
struct DATA *input; char buffer[33]; /* Daten in buffer lesen */ input=(struct DATA *)buffer; /* Jetzt kann mit dem Pfeiloperator auf die einzelnen Werte zugegriffen werden: printf("%d\n", input->angvel_pitch); */
mfg, loose
-
loose schrieb:
ich persönlich würde das mit nem Zeiger machen, also folgendermaßen:
damit kannste aber furchtbar auf die nase fallen, wenn der compiler zwecks member-alignment füllbytes in die struct einfügt.
-
mmh, hätte mir auffallen sollen bei 33 bytes.
bei gcc kann man das mit#pragma pack(1)
umgehen.
Ansonsten müsste man die Struktur ein wenig verändern, um sich nicht mit bit-shifts rumplagen zu müssen.
Aber einen Fehler bei den bit-shifts habe ich auch nicht gesehen. Vielleicht liegt der Fehler an der Hardware.