Archiv verlassen und diese Seite im Standarddesign anzeigen : Kompass für RP6
Hallo,
wollte mal fragen wie schwer es ist ein Kompass auf den RP6 zu bekommen.
https://www.roboternetz.de/wissen/index.php/Bascom_und_Kompass_CMPS03 damit wäre es zwar sehr leicht, aber irgendwie finde ich es doof ca 40€ dafür hinzublättern.
Theoretisch reichen ja schon 2 KMZ 10 Sensoren.
Hat jemand damit schon erfahrung gemacht?
Habe schon viele Schaltpläne gesehn, die erst noch O-Amps einsetzen? Ist das "Signal" sonst zu schwach für ein I/O Port?
Wie sieht das mit Störungen durch umligende Elektronik aus?
mfg Axel
sechsrad
14.07.2008, 12:00
kannst auch einen kompass für 1 euro draufstellen.
@sechsrad, warum kannst du diese blöden Kommentare nicht einfach mal lassen? Was will er denn damit anfangen, wenn es einen Kompass drauf legt, den er nicht mit dem Robby auswerten kann? Oder ist es für dich so schwer zu verstehen, dass es sich hierbei um einen Kompass handeln soll, den der Robbyauslesen kann?
Aber nun zurück zu deiner Frage, axel88.
Schwer wird es bestimmt nicht sein. Du bruachst erstmal zwei ADCs (kein I/O Port!). Ob bei der Basis noch zwei frei sind weiß ich nicht. Wenn nicht, wird die Erweiterung Abhilfe leisten.
Das Siganl, das die KMZ Reihe liefert ist für einen normalen µC zu schwach. Wenn du dir mal das Datenblatt des KMZ 10 anschaust, wirst du feststellen, dass die Ausgangsspannung suuper klein ist. Die muss man also verstärken. Es gibt PICs, die haben interne Verstärker, da bräuchtest du keine weiteren Bauteile Aber ich denke mal, dass du bei den AVRs bleiben willst.
Auch gibt es noch den KMZ 52, da brauchst du nur einen von, da der praktisch zwei KMZ 10 innen drinn hat.
Aber das größte Problem werden die Störfelder der Elektronik, vor allem der Motoren sein. Du musst auf jeden Fall einen Abstand von 20cm zu den Motoren einplanen, mehr wäre besser, ab 30 cm würde ich davon ausgehen, dass es keine Störungen mehr gibt.
Da es aber meistens sehr schwer ist, diese Entfernungen herzustellen, kannst du dich mal nach Mu Metall umschauen. Das wäre ideal zum abschirmen.
Ich hoffe, ich konnte dir etwas helfen,
jon
Ja danke, das ist schon einmal ein Anfang. Muss mich dann aber auch erstmal an noob auten :D
1. Wo bestellt man sich sowas am besten? reichelt hat kein KMZ 52 conrad nur ein KMZ51 (leider nur tschechisches Datenblatt...)
2. Hab zwar auf dem RP6 noch die 2 ADC Ports frei, würde aber dann doch mal aufstocken, kommt bald bestimmt noch mehr...
Als I/O Port ist im Manual ja der PCF8574 vorgeschlagen, was wäre ein "äquivalenter" ADC-Port-IC ?
3. Was ist der Spannungs/Genauigkeits bereich von den ADC-Ports? bzw was für ne Verstärkung muss ich mir Basteln?
mfg Axel
Keine Ahnung, wo man den KMZ 52 bekommt. Zwei der kmz 51 oder 10 machen es aber auch.
Du brauchst einen ADC! Und nicht einen I/O Port Expander.
Wenn du dich mal nen bisschen auf die Suche begibst, wirst du ein paar Portexpander finden. Wichtig ist aber, dass der mindestens 10 bit hat (bis 1024) oder gar 12 bit, was besser wäre und die Genauigkeit steigern würde.
Der PCF8591 hat z.B. nur 8 bit. Das ist für dich zu wenig.
Was für eine Verstärkung du dir bauen musst kriegst du raus, wenn du weißt, was für einen ADC du hast. Dann kannst du dir mal Tante Wiki zu Rate ziehen und nach Operationsverstärker suchen. Da ist bestimmt erklärt, wie man sich so einen Verstärker baut.
Viele Grüße,
jon
Hab mal ne Facharbeit über den O-Amp geschrieben, spätestens wenn ich mir die nochmal zu Gemüte führe, dürfte das kein Problem sein.
Der I/O Port Expander war jetzt auch nicht für den Kompass gedacht... dachte nur wenn ich schonmal aufstocke, dann direkt ein bisschen mehr ^^
ok vielen Dank! werd mich dann da mal durcharbeiten.
mfg Axel
hab endlich mal einen I2C fähigen 12Bit ADC gefunden... http://www.digchip.com/datasheets/new_parts/200802/1116373.php aber noch nichts gefunden, wo man ihn bestellen könnte. Wo bezieht ihr denn eure Bauteile?
Was passiert denn wenn ich nur den 8-Bit ADC nehme? Ich denke so genau wird das ganze auf grund der Störfelder eh nicht, und muss es ja auch nicht...
mfg Axel
wenn du 8 bit hast, dann hast kannst du deine Spannung, die am Pin anliegt nur in 256 Stufen unterteilen. Wenn du dagegen 10 bit hast, sind es schon 1024 Stufen, bei 12 bit ganze 4096 Stufen.
Um so mehr Stufen, desto genauer halt...
Viele Grüße,
jon
naja 1,4° wären bei 8 Bit wohl das Ende, glaub zwar kaum das es viel genauer braucht, aber macht ja auch die gleiche Arbeit, das aufzulöten... bleibt nur die Frage woher... :(
mfg Axel
Ich bestelle meine Kleinteile nur bei Reichelt, wenn es sein muss kaufe ich mal einfache Widerstände oder Kondensatoren in Einzelstücken beim Conrad.
Von daher kann ich dir da leider nicht weiter helfen.
Viele Grüße,
jon
um I2C kommt man auch nicht herum?
Du kannst einen weiteren µC nehmen. Der würde aber dann über den I2C Bus mit dem Master kommunizieren...
Letztendlich kommst du um I2C nicht drumherum. Es sei denn, du nimmst einen anderen Bus, aber das macht bei den AVRs keinen Sinn. Dafür ist I2C zu gut. Ich würde sogar sagen; das beste.
jon
naja ich mach mal irgendwo nen neues Thread auf, wo man die Teile herbekommt, wobei wenn google nichts findet, wer dann? :D
RP6conrad
15.07.2008, 22:45
Ich habe mir so ein compass mit zwei KMZ10 sensoren gebaut und hat folgende erfahrung : Signalspannung von die MR-Brucke ist recht niedrig : in mVolt bereich. Dazu benotigen sie eine OPAMP mi ca 2000 fache Verstarkung. Irgendwo muss auch die Offset von OPAMP und Brucke geregelt werden. am besten ein OPAMP mit ofsett eingang und trimpoti verwenden.Die Ausgange von OPAMP gehen nach die ADC0 und 1. Diese Signale sind dan 2 Sinussen um 90° verschoben Dort muss das Signal dan verarbeitet werden mit Sinus/ Tangens Functionen. Geht mit math.h bib. Leiter : Positionen von KMZ ist sehr wichtig : hoch und weit weg von Emotor. Magnetfeld in Hause ist auch gestort durch alle eisen in Bau. Da wollte Robi niemals gerade fahren, aber brauchbar ist das. Andere Nachteil : Sinus und Tangens functionen sind mit float operators und kosten viel Ziet in µProcessor.
Aber, es hat functioniert !!
Also betreibst du den Kompass über die freien ADC ports des RP6?
Werd ich glaub ich auch mal mit anfangen, da ich momentan noch kein 10Bit ADC Port mit I2C gefunden habe...
naja ich meld mich mal bei Fragen/Problemen/Erfolgen wieder...
mfg Axel
Wie hast du das mit der +/- Stomversorgung bei den O-Amps gelöst?
RP6conrad
17.07.2008, 09:30
Die OPAMP die ich verwende sind die OP177F. Versorgungsspannung ist GND und 5 VDC von Robi. Verstarkung und Offset sind so geregelt das das Signal immer zwischen 1000 mV bis max 4000 mV ist. In Graphik sind sie die beide Signale wahrend eine 360° Umdrehung von Robi. Daraus muss dan die "Heading" berechnet werden. In Prinzip die ArcTangens von ADC0/ADC1.
Stimmt ist ja ziemlich egal ob +/- oder +/GND man will ja garkeine negativen Ausgangswerte...
sagmal hast du die O-Amps ähnlich wie hier verschaltet?
http://www.magnetometer.org/mag-magnetoresistive.php
Hast du auch die 2 Stufe mit "sensitive adjustment" ? Also Praktisch wärs ja schon, dann muss man nicht solang mit den Widerständen rumlöten bis es passt :D
Dann noch zur Anordnung der Sensoren:
Also die KMZ müssten doch "waagerecht" verbaut werden, oder?
Reicht es sie auf die vordere Experimantierplatine zu bauen? (ca 13cm vom Motor) oder misst man Software technisch einfach nur bei stehemden Motor?
mfg Axel
13cm sind nach meinen Erfahrungen mit dem CMPS03 beim RP5-Chassis zu wenig. Es sollten auf jeden Fall 20 sein, um halbwegs brauchbare Ergebnisse zu bekommen.
Ob du während der Fahrt misst oder wenn du stehst ist egal. Die Motoren stören so oder so durch die Dauermagneten. Wenn es softwaremäßig geht würde ich während dem Fahren messen. Dann hast du nicht alle paar cm das nervige Stehenbleiben.
Viele Grüße,
jon
also werde ich mir ein Türmchen oder ne Art antenne aus den KMZ's bauen müssen... sieht bestimm drollig aus :D
japs. das wirst du wohl machen müssen.
Wie das aussieht ist Definitions-Sache. Man kann sich aber bestimmt auch eine Konstriktion überlegen, die den Robby nach etwas aussehen lässt.
Ich fand bei IMADEIT-V1 (meinem einen Roboter) das Horn recht lustig.
jon
RP6conrad
18.07.2008, 22:23
Ich habe die Verstarkung mit eine Stufe gerealisiert. Sehr einfache Schaltung : eine OPAMP OP177F, ruckkupplung mit Wiederstand von 2 Megaohm. Die einzele Wiederstande von KMZ10 Brucke sind ca 1000 ohm. Damit bildet sich dan eine 2000 Fache Verstarkung. Offset regelung mit trimpoti ueber die OP. Verstarkungjustierung ist nicht absolut notwendig, kann mann auch ueber software machen.
Du hast den -Vo (output Voltage) des KMZ10 garnicht beschaltet?
RP6conrad
20.07.2008, 23:04
Jadoch. Die Anaologe Ausgange von Wheatstone Brucke (KMZ10) gehen zu die Eingange + und - von OP. Und 5 VDC /Ground gehen auch zum KMZ10. Beide KMZ10 mussen in ein Winkel von 90° orientiert werden.
RP6conrad
21.07.2008, 14:51
Es scheint mir das die Verstarkung von Schaltung zu niedrig ist. Beide Stufe verstarken ca 9* (140k/22k). Gesamt Verstarkung ist dan nur max 81*. Da habe ich eine Verstarkung von ca 2000 !! Versuche auch mal die Verstarkung erste Stufe zu erhohen (R5 nach 1 MegaOhm ?). Kônnen sie die Spannung nach die erste Stufe messen ?
Mit meine Schaltung habe ich ein Differesna von ca 600 Einheiten (Graphic). Versuche sie auch mal eine Magnet in der Nahe von KMZ10 zu halten, dan soll die max. Werte deutlich hoher liegen.
Also ich erreiche so 250 Stufen, wenn ich dann die Verstärkung der 2. Stufe erhöhe, springen sie wahrlos... aber werde mich mal an die 1. Stufe machen...
Nachtrag: ( hatte mein erstes Thema gelöscht, weil ich schon ein Fehler meinerseits gefunden hatte und noch niemand geantwortet hat...) "So, heute sind endlich die Teile gekommen, habe jetzt eine Schaltung wie hier(http://www.magnetometer.org/mag-magnetoresistive.php) zusammengelötet. Statt dem Temperaturabhängigen Widerstand (R6) habe ich einen 2k benutzt und statt dem R12 (zum Glück hatte der Händler kein 150Ohm) ein 250 Ohm.
Ausgang an ADC0 und mir fröhlich die Werte angeschaut:
positiv: Sie ändern sich beim Magnetfeld, nach etwas Einstellarbeiten an den Potis auch Veränderungen bei 90° Drehung zu beobachten.
negativ: 90° Drehung macht grade mal 50 Einheiten aus (ADC0 170-220)
dabei ist R12 schon maximal?! Habe dann mal ein 500k Wiederstand in Reihe mit R12 gelötet, damit der Verstärkungsfaktor noch höher wird. Komischer weise erreiche ich jetzt nur Differenzen von ca 5 Schritten auf 90°
Irgend wer ne Idee warum? Habe ich irgendwelche Fehlerquellen übersehen?
mfg Axel"
So habe das Hardwaretechnisch jetzt soweit abgefrühstückt:
Hier mal die Lösung/Erfahrungen:
Schaltung wie oben, R5 = 1M Ohm R12 = 250K Ohm(Poti) + 200K Ohm
Der Offset (R1) Steht mittig (ca 50K) ist aber sehr empfindlich beim Einstellen, ich würde ihn durch ein 40k Wiederstand und ein 20k Poti ersetzen, wenn ich es nochmal machen würde. Der Sensitive Adjustement steht auf "voll" ist also in der Anwendung relativ überflüssig (Macht ja auch Sinn, das Magnetfeld der Erde wird wohl fast immer gleichstark sein :D).
Insgesamt kommt die 2. Stufe mir aber sinnvoll vor, da ich riesige Schwankungen hatte, wenn ich in einer Stufe eine sehr hohe Verstärkung hatte.
Werd mich jetzt mal an die Software machen...
mfg Axel
So brauch mal wieder Rat :(
bei der Softwaretechnischen auswertung fiel auf, das ADC0 an der Stelle woe er maximal sein sollte, zwischen 2 Werten springt... (zb. 30 /220) der andere Sensor springt höchstens um eine Stelle (60/61) in anderen Winkeln halten sich beie Sensoren korrekt.
ADC0 ist ja bei 220 weit von der Sättigung entfernt, also ist es recht unlogisch das er springt?
naja ne Erklärung täte mir echt gut -.-
mfg Axel
RP6conrad
23.07.2008, 22:34
Der ADC0 hat keine Probleme, aber welche OPAMP verwendet du ? Moglicherweise liegt das problem bei Sattigung von der OPAMP. Jeden OPAMP kan seine Ausgang nur in bestimmte Grenze lineair aussteuern, abhangig von Versorgingsspannung. Kann sein das 220 (= ca +1Volt) zu nahe an der GND ist. Schau mal das Datenblatt von OPAMP nach. Versuch sie auch mit der Offset das ganse etwas hoher zu regeln (minimal Werte ADC0 = 300). Dieses Problem kan sich in beide Stufen stellen !!
Ich verwende ein LM324. Das mit der Sättigung ist aber unlogisch, weil die andere Seite bis zu 7 Sauber arbeitet. Und warum springt er dann beim höchsten Wert?
Zum Offset: Experimentier da grade mit rum, da der 100k poti zu ungenau ist, habe schonmal ein 5k und ein 25k eingelötet, aber da hänge ich viel zu tief in der Sättigung :( kann ich den Poti nicht einfach Tauschen? Es kommt doch im Endeffekt nur auf das Verhältnis der Widerstände zwischen GND und VDD an? Oder muss ich dann noch mit Festen Widerständen aufstocken, wenn ich ein kleineren Poti nehme?
mfg Axel
RP6conrad
26.07.2008, 23:00
Ich verwene eine trimpoti (10 umdrehungen) an der forgesehene eingang von OP177. Geht problemlos, aber auch muss ich genau abregelen zwischen beide max.
Ok habe das gemacht was im Hanbuch als "Anfänger fehler" verbucht wird :D hatte zur Berechnung eines Mittelwerts uint8 verwendet, was dann bei hohen Werten diese Sprünge ins niedrige verursacht haben muss...
Habe grad kein Trimpoti hier, desshalb habe ich einen 2,5k Poti mit 2X 33k Widerständen benutzt, das schränkt zwar den Radius ein, aber zum Glück passt das und ist präzise genug ^^
So noch mehr Fragen zur Software:
-warum schmeißt folgender code nur falsche Werte aus?
#define KMZ0MAX 750
#define KMZ0MIN 60
int32_t KMZ0 = 0;
(...)
KMZ0 = (adc0 - KMZ0MIN -(KMZ0MAX-KMZ0MIN)/2)*1000/(KMZ0MAX-KMZ0MIN);
(...)
writeInteger(KMZ0 , DEC);
im Endeffekt soll KMZ0 ein wert zwischen -1 und 1 sein mit dem Faktor 1000, da es keine Nachkommastellen gibt :( im Taschenrechner funktioniert diese "Formel" ...
*die Werte liegen grundsätzlich zwischen 6 und 70 o.ä.
*einmal hatte ich 1000 durch 100000 ersetzt, und einen richtigen Wert erhalten, andere Werte sponnen trotzdem
* habe noch nie ein negativen Wert ausgegeben bekommen, aber eine Bedingung für ein negativen Wert wurde mal erfüllt, kann writeInteger negative Werte ausgeben?
- Wie funktioniert das mit dem include math.h ? ist das schon in der RP6 lib? Wo finde ich die doku?
mfg Axel
Hallo,
writeInteger ist für 16 Bit Werte! Mit 32 Bit gibts dann Müll ;)
Aber ich kann mir auch nicht vorstellen das Du wirklich 32 Bit Wert brauchst.
(nein ich hab nicht den ganzen Thread gelesen)
Jedenfalls wenn Du das unbedingt brauchst kannst Du das mal hiermit probieren:
// Original - nur um die Änderungen zu verdeutlichen:
/* void writeInteger(int16_t number, uint8_t base)
{
char buffer[17];
itoa(number, &buffer[0], base);
writeString(&buffer[0]);
} */
// Geänderte Version:
void writeInteger32(int32_t number, uint8_t base)
{
char buffer[33]; // 33 wegen BIN! Für DEC wärs natürlich nicht nötig...
itoa(number, &buffer[0], base);
writeString(&buffer[0]);
}
Und ja, das kann negative Werte ausgeben!
AVRLibC Doku:
http://www.nongnu.org/avr-libc/user-manual/index.html
MfG,
SlyD
naja auf 32Bit kann ich denke ich verzichten... aber warum wirft er nun für z.b. den Wert(ADC0) "111" "52" statt "-42,..." aus? Also ich seh immer noch keine negativen werte?!
mfg und Danke für die Antwort Axel
EDIT: Hatte den Faktor mal auf 100 reduziert, um sicher nicht aus den 16Bit zu fallen ^^
Mach mal ein paar mehr Klammern um die Berechnung drum - damit auch die Reihenfolge korrekt eingehalten wird.
(düfte zwar daran nicht liegen, aber schaden kann es nicht)
Dann könnte es noch sein, das der Compiler einige Werte nicht als 16 Bit signed Integer behandelt - also mach mal z.B. vor den adc0 Wert ein
(int16_t)
und auch nochmal vor den ganzen Ausdruck.
(das nennt sich "type cast" also Typumwandlung)
Also so:
(int16_t)((((int16_t)adc0 - KMZ0MIN - ((KMZ0MAX-KMZ0MIN)/2))*1000)/(KMZ0MAX-KMZ0MIN));
Ich hoffe mal die Klammerung ist so wie Du es gemeint hast
MfG,
SlyD
also mit dem (int16_t)adc0 wurden schonmal die ersten negativen Zahlen gesichtet :) aber ich bewege mich noch im Wertebereich von -50 bis 50 anstatt -1000 bis 1000 ich spiel mal noch etwas mit den Klammern...
besten Dank Axel
EDIT: Habe es jetzt schon auf
KMZ0 = (((int16_t)adc0 - 405)*1000)/690;
reduziert, aber ich erhalte immer noch falsche werte :(
also wenn man den Faktor auf 100 reduziert, habe ich schon viele richtige Werte erhalten, aber nicht an allen Stellen :( geh also davon aus das die Klammerung etc richtig ist :)
ich poste mal die Werte, vielleicht fällt ja jemanden etwas auf:
KMZ0=-44KMZ1=-26 ---> Stimmt
ADC0= 98ADC1= 183
KMZ0=-38KMZ1=34
ADC0= 137ADC1= 154
KMZ0=-16KMZ1=-18 ---> Stimmt auch
ADC0= 293ADC1= 122
KMZ0=10KMZ1=-36
ADC0= 474ADC1= 177
KMZ0=14KMZ1=-6
ADC0= 506ADC1= 195
KMZ0=22KMZ1=-34
ADC0= 560ADC1= 244
KMZ0=23KMZ1=-35
ADC0= 565ADC1= 243
KMZ0=22KMZ1=-32
ADC0= 561ADC1= 245
KMZ0=23KMZ1=-30
ADC0= 567ADC1= 246
KMZ0=22KMZ1=-27
ADC0= 559ADC1= 248
KMZ0=22KMZ1=-30 ---->Stimmt auch
ADC0= 559ADC1= 246
KMZ0=23KMZ1=-25
ADC0= 565ADC1= 249
KMZ0=22KMZ1=-24
ADC0= 560ADC1= 250
KMZ0=23KMZ1=-27
ADC0= 564ADC1= 248
KMZ0=23KMZ1=-30
ADC0= 564ADC1= 246
KMZ0=23KMZ1=-20
ADC0= 566ADC1= 252
KMZ0=22KMZ1=-25
ADC0= 562ADC1= 249
KMZ0=23KMZ1=-27
ADC0= 564ADC1= 248
KMZ0=22KMZ1=-19
ADC0= 562ADC1= 253
KMZ0=27KMZ1=-45
ADC0= 598ADC1= 303
KMZ0=28KMZ1=-10
ADC0= 605ADC1= 455
KMZ0=9KMZ1=18
ADC0= 468ADC1= 603
KMZ0=8KMZ1=24
ADC0= 465ADC1= 607
KMZ0=9KMZ1=24
ADC0= 472ADC1= 607
KMZ0=8KMZ1=28
ADC0= 465ADC1= 609
KMZ0=8KMZ1=21
ADC0= 465ADC1= 605
KMZ0=8KMZ1=18
ADC0= 467ADC1= 603
KMZ0=8KMZ1=21
ADC0= 467ADC1= 605
KMZ0=9KMZ1=23
ADC0= 468ADC1= 606
KMZ0=8KMZ1=26
ADC0= 465ADC1= 608
KMZ0=8KMZ1=23
ADC0= 466ADC1= 606
KMZ0=8KMZ1=26
ADC0= 466ADC1= 608
KMZ0=9KMZ1=21
ADC0= 469ADC1= 605
KMZ0=9KMZ1=26
ADC0= 470ADC1= 608
KMZ0=-37KMZ1=6
ADC0= 143ADC1= 596 ---> Stimmt
KMZ0=43KMZ1=-7 --->Stimmt nicht KMZ0=-51
ADC0= 51ADC1= 522
KMZ0=43KMZ1=0
ADC0= 50ADC1= 527
KMZ0=43KMZ1=-7
ADC0= 48ADC1= 522
KMZ0=43KMZ1=-6
ADC0= 51ADC1= 523
KMZ0=43KMZ1=-9
ADC0= 48ADC1= 521
KMZ0=44KMZ1=-6
ADC0= 54ADC1= 523
KMZ0=43KMZ1=-12
ADC0= 48ADC1= 519
KMZ0=43KMZ1=-4
ADC0= 48ADC1= 524
KMZ0=43KMZ1=-9
ADC0= 48ADC1= 521
KMZ0=43KMZ1=-9
ADC0= 49ADC1= 521
KMZ0=43KMZ1=-4
ADC0= 49ADC1= 524
KMZ0=44KMZ1=-7
ADC0= 55ADC1= 522
KMZ0=43KMZ1=-9
ADC0= 48ADC1= 521
KMZ0=43KMZ1=-7
ADC0= 50ADC1= 522
KMZ0=43KMZ1=-14
ADC0= 50ADC1= 518
KMZ0=43KMZ1=-6
ADC0= 49ADC1= 523
KMZ0=43KMZ1=-12
ADC0= 50ADC1= 519
KMZ0=43KMZ1=-6
ADC0= 51ADC1= 523
KMZ0=43KMZ1=-11
ADC0= 47ADC1= 520
KMZ0=43KMZ1=-16
ADC0= 50ADC1= 517
KMZ0=43KMZ1=-16
ADC0= 53ADC1= 517
KMZ0=42KMZ1=-4
ADC0= 46ADC1= 524
KMZ0=42KMZ1=-16
ADC0= 43ADC1= 517
KMZ0 = (((int16_t)adc0 - 405)*100)/690;
naja bei der Auswertung ist mir noch aufgefallen, das meine Formel noch nen Inhaltlichen Fehler hat, da sie bei 60 nicht -100 ist :( aber das erklärt ja nicht, warum mirco Prozessor und Taschenrechner zu unterschiedlichen Werten kommen :(
abgesehn davon hätte ich schon gern den Faktor 1000, weil 100 "schritte" bei 360° nicht so genau ist :(
mfg Axel
Habe es jetzt wie folgt gelöst:
(...)
ZW0A=(KMZ0MAX-KMZ0MIN)/2;
ZW0B=KMZ0MIN + ZW0A;
KMZ0 = (((int16_t)adc0 - ZW0B)*100)/ZW0A;
(...)
und für den Faktor 100 macht er das jetzt ganz brav, nur beim Faktor 1000 bekomme ich komische Werte (zwischen ca -104 bis 103)
habe mal überschlagen das er an den max Werten Zwischenwerte +/- 345.000 berechnen muss!!! Das fällt natürlich aus dem 16Bit Rahmen.
Kann ich mit dem type cast den irgendwie dazu bringen die Rechnung in 32Bit durchzuführen, sich das aber als 16Bit Variable zu speichern?
Oder muss ich mir für die Rechnung ne extra Variable in 32Bit einrichten?
mfg Axel
kann mir einer von denen, die sowas schonmal programmiert haben zeigen wie sie das gelöst haben?
Logisch ja kein Ding, aber beim umrechen von (uint16_t)adcX zu einem double für acos( x double) habe ich nur Probleme. :(
entweder erhalte ich Werte >1 oder nur 1; 0; -1 :(
@RP6conrad
läuft das bei dir mit dem atan ? arctan hat doch nur ein Wertebereich von -pi/2 bis pi/2 ergo nur 180° und dann wird (atan)' für große Werte so klein, das man doch ziemlich große Fehler erhält?
ich wollte das über den arccos(x) für |x|<0,707 und an den Stellen |x| >0,707 den anderen Sensor (bzw sinus ) zu nehmen.
So werden alle "flachen Stellen" an den kleine Fehler große Wirkung haben ausgeblendet.
Ist zwar noch etwas Arbeit, und dafür muss ich das mit den double erstmal in den Griff kriegen -.-
mfg Axel
RP6conrad
04.08.2008, 19:01
Das verwenden von atan2 hat mich auch einiges an Kopfbrecher bezorgt ! wichtig ist das alle Variabele die du brauch in deine Berechnungen von die richtige Type sind !! Dan naturlich auch noch die math.h lib nicht vergessen. Auch nicht vergessen das immer in radialen wird gerechnet. Zum umrechnen einfach multiplizieren mit 57.
Hier meine code
void task_compass(void) //opgelet, gebruik stopwatch5() in deze functie
{ //langzaam omwille van atan !!
double headingA ;
double heading0 ;
double heading1 ;
int16_t heading ;
static int16_t oldheading;
static int16_t headingX=0;
startStopwatch5();
if(getStopwatch5() > 250)
{ heading0 =adc0;
heading1 =adc1;
headingA = atan2(((heading0-470)*1.1),(heading1-470));
heading=headingA*57,3;
if ((heading-oldheading)>180) headingX = headingX-360;
if ((oldheading-heading)>180) headingX = headingX+360;
oldheading = heading;
M32heading = heading+headingX;
setStopwatch5(0);
writeString_P("ADC0: ");
writeInteger(adc0, DEC);
writeChar(' ');
writeString_P("ADC01: ");
writeInteger(adc1, DEC);
writeString_P(" heading: ");
writeInteger(heading, DEC);
writeChar(' ');
writeString_P(" ADCLSL: ");
writeInteger(adcLSL, DEC);
writeChar(' ');
writeString_P(" ADCLSR: ");
writeInteger(adcLSR, DEC);
writeChar(' ');
writeChar('\n');
}
}
Problem das sich stelt : bei jeden Durchgang von 0°, bekommt man eine Sprung !! (von -pi RAD nach +pi RAD). Aber dazu kann man einfach mit eine If Schleife dan mal 2pi bei oder abziehen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.