Hi reflection,
eins habe ich vergessen: in der Init-Funktion sollte die startup-time von 160ms sichergestellt werden!
Viele Grüße,
bluesparkAB
Hallo reclection,
bist du noch an der Weiterentwicklung des Gyro-Codes interessiert?
Ich beschäftige mich momentan mit ihm und er performt ganz ordentlich an einem ARM7 Controller. Genauigkeit von weniger als 1 °/s ist nicht zu erreichen, aber das ist OK.
In deinem Code machst du einige grobe Schnitzer:
-- Du rechnest die Zweikomplementwerte falsch in vorzeichenbehaftete Werte um. Das darf nie durch Abschneiden der Vorzeichenbits geschehen. Zweikomplementwerte und vorzeichenbehaftete Werte werden immer durch die Operationen "Komplement bilden"--"Eins addieren" in das jeweils andere Format umgewandelt.
-- Deswegen dürfen nicht alle 12bit Werte sowie auch nicht alle 14bit-Werte gleich maskiert werden. Ich würde das switchen also eher auf die "address" anwenden und darin dann für jede Adresse separat die Umwandlung der beiden Bytes dummy/result_int in ein float vornehmen.
-- Du vertauschst in der Read-Funktion beim Einlesen der Werte im zweiten 16bit-Transfer LSB und MSB. Zuerst wird das MSB übertragen!
-- Die Abfolge sollte deshalb sein: 1) Beide 8bit Werte richtig aneinander hängen 2) ggf Zweikomplementwandlung 3) scale factor anwenden, ohne ihn mit 4 zu multiplizieren.
-- Deine Init-Routine schafft es nicht, einen bekannten Anfangszustand herzustellen. Die Register SMPL_PRD und GYRO_SCALE müssen abgeprüft und ggf verändert werden.
-- Das Belegen der Register "dummy" und "rsult_int" durch VerODERn ist fehleranfällig. Wieso weist du im ersten Schritt nicht direkt zu?
-- in der Funktion Read sendest du im zweiten Transfer die adress erneut. Da ist unnötig, aber nicht falsch. Du wertest ja die ersten beiden Bytes die zurückkommen nicht aus.
-- Wenn du möchtest dass nach einem kurzen Spannungsausfall am Sensor die richtigen Werte wieder aus dem flash geladen werden, solltest du Auto-Null NACH den Änderungen am SENS/AVG machen, dadurch werden diese Werte (genauso wie GYRO_SCALE auch, falls du einen nicht-default-Wert nehmen willst) nämlich auch mit ins flash geschrieben und nach einem power-up wieder richtg geladen.
-- 40us Wartezeit zwischen den 16bit Transfers ist nicht nötig. Es muss nur die stall time eingehalten werden, 15us. Alle anderen deiner delays, zwischen CS und der clock, sind unnötig.
-- Nach Autonull hingegen in der Init machst du zuwenig Pause: Stelle sicher dass mindestens 50ms (!!!) gewartet wird, denn nach Autonull folgt automatisch ein flash-update und das braucht lange.
Ich wäre dann mal an deinen Erfahrungen interessiert. Bei mir zappeln nach einem Auto-Null bei GYRO_SCALE auf default die Messwerte +/-5LSB, während der Sensor in Ruhe ist. Wie ist es bei dir?
Bleibt mir noch die Bemerkung, dass ich die Aussagen der "Experten" fumir und Volker-01 als schwer irreführend, wenig hilfreich und eher selbstgefällig-selbstdarstellerisch ansehe. Wenn Deutschlands Diplomierte und Physiker solch einen Wissensquerschnitt darstellen, wundert mich nichts mehr.
Viele Grüße,
bluesparkAB
Hi reflection,
eins habe ich vergessen: in der Init-Funktion sollte die startup-time von 160ms sichergestellt werden!
Viele Grüße,
bluesparkAB
1. kommt deine hilfe mehr als einen monat später, und ne unzureichende hilfe ist dann unter umständen immer noch besser als gar keine.Zitat von bluespark
2. einige der von dir festgestellten fehler im programm wurden längst behandelt.
3. haben weder volker noch ich behauptet experten auf dem gebiet zu sein.
4. hab ich in der tat noch nie was mit so nem sensor zu tun gehabt.
ich hätte natürlich einfach die klappe halten können.
aber ich finds konstruktiver vorläufige meinungen auszutauschen anstatt nen monat später die mutmaßliche patentlösung zu präsentieren.
5. anstatt den wissensstand der deutschen physiker in frage zu stellen, könnte man auch genauso gut mutmaßen, dass du den thread erst mal verfolgt hast, dir dann das nötige equipment gekauft hast, und lange genug rumprobiert hast, um dann den schlaumeier spielen zu können! kannst mir ruhig glauben: mit genügend geld, einem monat zeit und genügend langeweile, wären sowohl volker (vermut ich mal) als auch ich in der lage deine aussagen zu reproduzieren. so what?
Hallo bluespark,
mal nicht mit allen immer gleich so schwer ins Gericht gehen! Fällt nämlich häufig auch auf einen selbst zurück. Es kann immer mal passieren, das sich jemand verwerkelt oder etwas übersieht.
Da muss ich allerding sagen, habe ich auch schon ganz schön geschlafen.- Du vertauschst in der Read-Funktion beim Einlesen der Werte im zweiten 16bit-Transfer LSB und MSB. Zuerst wird das MSB übertragen!
Soweit ich sehe, schneidet er doch nirgend wo ein Vorzeichen ab.-- Du rechnest die Zweikomplementwerte falsch in vorzeichenbehaftete Werte um. Das darf nie durch Abschneiden der Vorzeichenbits geschehen. Zweikomplementwerte und vorzeichenbehaftete Werte werden immer durch die Operationen "Komplement bilden"--"Eins addieren" in das jeweils andere Format umgewandelt.
-- Deswegen dürfen nicht alle 12bit Werte sowie auch nicht alle 14bit-Werte gleich maskiert werden. Ich würde das switchen also eher auf die "address" anwenden und darin dann für jede Adresse separat die Umwandlung der beiden Bytes dummy/result_int in ein float vornehmen.Wenn ich mir den Code mal gerade ansehe, muss ich sagen, das dieser auf den ersten Blick schon Funktionieren sollte. (Unter Berücksichtigung der impliziten Typumwandlungen der Kompiler). Zudem hab ich nie gesagt, das der Code besonders gut oder schlecht programmiert wurde.Code:signed int result_int; unsigned int dummy; result_int = result_int << 8; // Schiebe MSB um 8 nach links result_int |= dummy; // Füge LSB hinzu switch(bit_count) // Bit Maskieren { case 12: result_int &= 0x0FFF; break; // Maskiere oberste 4 Bit --> 12-Bit Wert ** Fehlerhaft bei Auslesen vom >>Sensor Temperature Data<< -Register (Fällt bei pos. Werten unter Umständen gar nicht auf) case 14: result_int &= 0x3FFF; // Maskiere oberste 2 Bit --> 14-Bit Wert result_int = result_int << 2; // Shifte um 2 nach li. wegen Vorzeichen ** Fehlerhaft bei Auslesen vom >>Angel<< -Register break; // wird mit /4 beim Scalefactor kompensiert } result_float = result_int; // Resultat als float abspeichern result_float = (result_float * scale_factor); // Counts skalieren
soweit ich das im Datenblatt erkennen kann, hab ich da gelesen, das diese Register >> NONVOLATILE<< sind. Diese Register werden während des Startups selbstständig vom internen ASIC wider restauriert..-- Deine Init-Routine schafft es nicht, einen bekannten Anfangszustand herzustellen. Die Register SMPL_PRD und GYRO_SCALE müssen abgeprüft und ggf verändert werden.
Wie schon geschrieben, habe ich nie gesagt, das der Code besonders gut oder schlecht programmiert wurde. Es gibt hier sehr viel Optimierungspotentieal. Zudem nutzt man bei solchen Anwendungen am besten gar keine floats. Die produzieren nämlich aufgrund ihrer Darstellung nur Fehler.-- Das Belegen der Register "dummy" und "rsult_int" durch VerODERn ist fehleranfällig. Wieso weist du im ersten Schritt nicht direkt zu?
Warum soll ichs dann erwähnen ?-- in der Funktion Read sendest du im zweiten Transfer die adress erneut. Da ist unnötig, aber nicht falsch. Du wertest ja die ersten beiden Bytes die zurückkommen nicht aus.
hab ich in meinem Beitrag vom 17.12.2007, 09:45 erwähnt.eins habe ich vergessen: in der Init-Funktion sollte die startup-time von 160ms sichergestellt werden!
Habe ich auch im überarbeiteten Code unten geschrieben. Wobei ich mich in der Reihenfolge vertan habe, was mir fumir dankbarer weise gleich mitgeteilt hat, so das wirs klar gestellt haben.-- Nach Autonull hingegen in der Init machst du zuwenig Pause: Stelle sicher dass mindestens 50ms (!!!) gewartet wird, denn nach Autonull folgt automatisch ein flash-update und das braucht lange.
Gruß, Volker
Es muss nicht immer alles Perfekt sein, doch sicher funktionieren solls schon.
Salu zusammen
Sorry das ich mich nicht mehr gemeldet habe, aber ich hatte sehr viel Arbeit und in der Schule waren auch noch Prüfungen.
Werde mich aber in nächster Zeit wieder vermehrt dem Projekt widmen können. Möchte noch einmal allen für die tollen Artikel danken! Natürlich werde ich meine Erfahrungen, Erfolge, Misserfolge hier kund tun! Denke es ist noch so einiges im Argen aber das kriege ich auch noch irgendwie hin. Ist ja bekanntlich noch kein Meister vom Himmel gefallen
Greets reflection
Salu zusammen
Bitte entschuldigt, dass ich diesen „alten“ Thread noch einmal ausgrabe aber ich habe immer noch Probleme mit dem ADIS16250.
Hatte leider erst jetzt wieder Zeit mich dem Problem zu widmen
Folgendes Funktioniert im Moment:
- Die Spannung die ich auslese ist 5V
- Die Temperatur beträgt (inkl. Den 25Grad die man addieren muss) ca. 52Grad
- Der intern integrierte Winkel bleibt im Ruhezustand stehen *freu* und wechselt nun auch zwischen 0 und 360Grad. Der Winkel stimmt ungefähr. Also wenn ich das Gerät um 45Grad drehe zeigt er das auch an.
- Der Gyro Wert ist in etwa konstant. Driftet aber mit ca. 1Grad/s davon.
Denke also das mit der Initialisierung habe ich gepackt.
Nun zu dem was komisch ist:
MSB / LSB:
Ich lese immer noch so aus wie bis anhin. Also ich nehme an dass ich zuerst vom Sensor das LSB erhalte. Ich weiss, das in allen Datenblättern das Gegenteil steht, aber wenn ich annehme, dass der erste Wert das MSB ist, komme ich nie auf 5V oder 52Grad, oder einen Winkelwert der im Entferntesten stimmt. Habe dann irgendwelche Werte die unmöglich stimmen können (Temp. Z.B. 300Grad ect.)
Ich könnte ja jetzt einfach darüber hinwegsehen *dumdidum* aber das macht mir dann doch ein bisschen ein mulmiges Gefühl in der Magengegend
Gyro Winkel:
Problem beim Winkel ist folgendes. Probiere es mal zu beschreiben aber ist nicht so einfach:
Wenn ich einschalte ist der Winkel auf ca. 0Grad (alle Achsen) Die untersten Bits schlackern irgendwie rum, also die Nachkommastellen. Das machen sie rel. flott, also mehrere Mal pro Sekunde wechselt der Wert im Nachkommabereich.
So, drehe ich nun das Gerät passiert erst einmal nix mit dem Winkel der ausgegeben wird. Drehe ich weiter springt er auf einmal von 0Grad auf ca. 9-10Grad. Drehe ich weiter, springt er das nächste mal auf ca. 20Grad usw. Sind also 9-10Grad Schritte der er ausgibt. Der Winkel stimmt dann aber auch in etwa. Also wenn er auf 20Grad springt und ich das messe, dann stimmt das. Aber es kommen halt keine Werte mehr bis ich über den nächsten 10Grad Sprung raus bin.
Kann mir da jemand weiterhelfen. Wie gesagt, die Werte werden schneller ausgelesen (Ruhelage). Erst wenn ich das Gerät drehe gibt er nur alle 9-10Grad einen Wert aus.
Habe auch schon mit der Sensitivity gespielt, brachte nix, ausser das er mehr oder weniger Werte samplet, das funzt natürlich…
Hoffe mir kann einer weiterhelfen. Ich verzweifle. Ein Kollege von mir hat mir auch schon versucht zu helfen, bis jetzt erfolglos. Ist jetzt nicht so, dass wir das erste Mal programmieren, aber so einen Hund hatte ich schon lange nicht mehr drin. Wäre echt wichtig eine Lösung zu finden da die Zeit immer knapper wird.
Merci schon mal im Voraus für Eure Hilfe
Gruss reflection
PS: Achja, ich weiss jetzt nicht ob alle Kommentare noch stimmen, wurde gestern rel. spät.
Lesezeichen