Kompassmodul HMC6352 problemchen

Hallo Habe den HMC6352, der Mir im Testprogramm auch sehr gut die Ausrichtung in Grad angiebt. Allerdings benötige ich für mein Projekt nicht direkt die Grad angaben sondern nur einen Counter der bei Jeder Gradänderung Incrementiert. Das Heißt der Kompass springt im Moment noch von 1 auf 360 und umgekehrt, soll aber mit 0 und -1 ... weiter gehen. weiß jemand wie ich das umrechnen könnte?

Ich verstehe nicht was Du haben möchtest. Erklährst Du es bitte nochmal.
anstatt 1 bis 360 was mochtest Du haben? -179 bis 180? wobei 0 Norden angibt?
Grüße Uwe

nein nein. ich möchte den kompass für eine art Servo verhalten eines Motors mit encoder nutzen. Dabei ist es zweitrangig in welche himmelsrichtung der Kompass schaut, es geht eher darum die werte des Kompasses gemappt auf die werte des Encoders zu vergleichen und gegebenfalls anzugleichen wenn die werte von einander abweichen. Vereinfacht gesagt soll mein motor genau dahin schauen wo mein kompass hinguckt. das problem is wenn der kompass <1 ist beginnt er logischer weise mit 360, was allerdings nachteilig für den encoder des motors ist da aufeinmal eine wertedifferenz von 359 entsteht..... Ich müsste mit einer funktion den wertebereich des HMC auf normale INT wertebereich bringen...

vieleicht kann man die daten auch anders aus dem HMC herauslesen im Datenblatt steht geschrieben das es noch soetwas wie einen
"Continuous Mode" giebt,http://www.sparkfun.com/datasheets/Components/HMC6352.pdf weiss aber nicht genau ob es überhaupt das ist was ich suche oder wie man es auslesen könnte.
naja nur so eine Idee. Ich denke man kann es aber auch einfach verrechnen,...irgendwie...

Ok, ich glaube ich habe verstanden.
Du willst einen "Nullwert" (startrichtung) speichen uns einen Wert haben wieweit bzw in welche Richtung die aktuelle Richtung abweicht ( x grad rechts oder y grad links).

Mit einer incrementierung ist das so eine Sache; die kleinen ungenuigkeiten und das springen von +/1 Grad ergibt beim incrementiern / decrementieren schnell mal eine Abweichung in eine RIchtung und so bist Du schon mal auf einer viel zu großen Zahl.

Ich verstehe nicht wieso Du einen Kompass verwenden willst, wenn Du auf dem Motor berits einen Encoder hast. Mit einem eventuel notwendigen (wen der Encoder diesen noch nicht hat) Homesensor für eine absolute Positionsbestimmung reicht das um eine genauen Richtungwert zu haben.

Lösungsvorschlag:

Speichere einen Startwert der Richtung ab.
Subtrahiere vom Startwert jedesmal den gemessenen Wert des Kompasses.
Wenn das Ergebnis kleiner als -179 ist addiere 360,
Wenn das Ergebnis größer als 180 ist subtrahiere 360.

Grüße Uwe

Hallo, also ich habe eine Lösung gefunden die allerdings noch nicht ganz Optimal scheint. So wie du es mir beschrieben hast hat es irgendwie nicht funktioniert, Die Werte sind Trotzallem an den entsprechenden Stellen Gesprungen. Habe das jetzt so gelöst... das problem ist jetz wohl nur mein Tiefpass da für den Fall ich 0 Messe bzw. verrechne, (0*0,025 ist 0!!) die werte an der stelle "abgeschnitten" werden. die kleinste Zahl sollte 1 sein. Klingt einfach zu Lösen, einfach +1, und nach dem Tiefpass wieder -1. geht aber irgendwie nich kommt Kauderwelch heraus... Hast du eine Idee wie ich auf einfachen wege (ohne "Smoothsteps") das gleichmäßig Glatt bekomme?

#include <Wire.h> 
 
int compassAddress = 0x42 >> 1;  

int reading = 0;             //gemessener wert
float reading_B = 0;         // wert übergeben (für tiefpass, muss float sein)
int reading_before = 0;      // vorherige messung
float reading_old = 0;        // bereits geglätteter alter gemessener wert
int reading_glatt = 0;        // geglätteter wert (mit tiefpass)

boolean Firstrun = true;      // status für ersten durchlauf
int Startwert = 0;            // initial gemessene Ausrichtung

void setup() 
{ 
  Wire.begin();                
  Serial.begin(9600);           
} 
  
void loop() 
{ 
//////////////////////////////////////////daten empfang vom Kompass)////////////
Wire.beginTransmission(compassAddress);
Wire.send('A');
Wire.endTransmission();
 
Wire.requestFrom(compassAddress, 2);
if(2 <= Wire.available())   
  { 
    
    reading = Wire.receive();  
    reading = reading << 8;    
    reading += Wire.receive();      
///////////////////////////////////////////////////////////////////////////////////////////    
    reading_B = reading ;          //zum weiterverarbeiten übergeben
//_______________________________________________ //wird nur einmal ausgeführt   
  if (Firstrun == true)
   {
    Startwert = reading_B;
    Firstrun = false;
   }  
 //________________________________________________   
                                                // Werte von 0-3590 auf unbegränzt trimmen
   if ((reading_B - reading_before) > 3500) 
        reading_B = reading_B - 3600;
  else if ((reading_B - reading_before) < -3500)
        reading_B = reading_B + 3600;
   
    reading_B -= Startwert;                     // Zähler nullen
    reading_glatt = ((reading_B*0.025) + (reading_old*0.975)); // Tiefpass glättet den gemessenen wert
    
    reading_old = reading_glatt;    // wert für nächsten durchlauf übergeben
   
    Serial.println(reading_glatt);

  }
 
  
                
}

OK jetzt ist hier doch noch ein Fehler im Konzept, Funktioniert doch nicht,(eigenartiger weise) Springt auch...Mist... da ist das Tiefpassproblem erstmal zweitrangig... funktioniert für die ersten 360 Grad umdrehung aber bei jeder weiteren sringts wieder an den entsprechenden stellen... Sorry für das hin und her.. ich weiss grad nich sorichtig weiter...

Entschuldige Biele01

Meine Frage: wieso Du den Kompass und nicht den Encoder verwendest hast Du nicht beantwortet.

Zum Kompass: Du möchtest, wenn der Kompass 2 Umdrehungen im UZS macht einen Gradwert von 720 Grad haben?

Grüße Uwe

Also erstmal ich habs jetzt endlich gelöst...ist eigentlich total Logisch,...knick in der Denkleitung.... so schaut jetzt das funktionierende Testprogramm aus

#include <Wire.h> 
 
int compassAddress = 0x42 >> 1;  
int reading = 0;


float reading_before = 0;
float reading_B = 0;
float reading_C = 0;
float reading_old = 0;
int reading_glatt = 0; 
 

boolean Firstrun = true;      // status für ersten durchlauf


void setup() 
{ 
  Wire.begin();                
  Serial.begin(9600);           
} 
  
void loop() 
{ 
//***************************************************************************lese von Kompass 
Wire.beginTransmission(compassAddress);
Wire.send('A');
Wire.endTransmission();
 
Wire.requestFrom(compassAddress, 2);
if(2 <= Wire.available())   
  { 
    
    reading = Wire.receive();  
    reading = reading << 8;    
    reading += Wire.receive();      
    reading_B = reading;
//*************************************************************************** nur ein mal ausführen
  if (Firstrun == true)
   {
    reading_before = reading_B;
    Firstrun = false;
   }    
//***************************************************************************ansonsten wird die umrechnung ausgeführt
else
   {
       reading_C += (reading_B - reading_before);

       if   ((reading_B - reading_before)> 1800)
              reading_C -= 3600;

       if   ((reading_B - reading_before)< -1795)
              reading_C += 3600;
 //***************************************************************************Tiefpass glättet den gemessenen wert 
      reading_glatt = ((reading_C*0.025) + (reading_old*0.975)); 
 //***************************************************************************wert für nächsten durchlauf übergeben    
      reading_before = reading_B;
      reading_old = reading_glatt;    
  
 
 
    Serial.println(reading_glatt);

  }
  }
  
  
  
                
}

zu deiner Frage wesshalb ich nicht den Encoder nehme..
Ich habe eine Kamerakran gebaut der von Schrittmotoren und encoder betrieben, bereits mit einen Joystick gesteuert wird. Als Untergeordnete Steuermöglichkeit Möchte ich den Kompass in mein Handsteuerpult integrieren, um ggf. die Z achse des Remoteheads 1:1 mit der drehung des Steuerpultes realisieren. Zusätzlich soll ein weiterer Kompass am unbeweglichen Ende das Kamerakranes Angebracht sein, um die Radiale bewegung des Kranauslegers zu Kompensieren, sodas ohne ein zusätzliches eingreifen Die Kamera in der 0 position immer in die richtung schaut in der ich sie Genullt habe. Die Encoder sind für den Fall nur die Referenz, ich möchte mich ja an der Globalen Ausrichtung (Magnetfeld Erde) orientieren und nich der Lokalen, des Motors,die ist untergeordnet.. Außerdem ist der Encoder zum Datenloggen gedacht,er soll mir die Lokale ausrichtung angeben, desshalb kann ich den Encoder Counter nicht hineinpfuschen.... Habs sicher kompliziert erklärt...Wenn du noch eine idee für die Tiefpass misere hast,wie ich da um die "Flache" 0 herumkomme...

Ok jetzt verstehe ich was Du machst und habe keine bessere Idee.
Hab nicht verstanden, was Dir an der null nicht gefällt
aber:
if (wert <= 0) wert--; natürlic nur 1 mal zu machen

PS: Die GPS-Position mitloggen?

Grüße Uwe

naja ich meinte damit die tiefpass funktion.
Da nehme ich ja (0,1den aktuellen wert) + (0,9alten wert). sobalb mein aktueller wert aber 0 und alter 1 ist das ergebnis im int wertebereich 0. bei 0 und 0 is auch null und bei -1 und 0 das selbe. erst bei -1 und -1 machts wieder sinn.

Die GPS Daten mitloggen wäre quatsch da das raster viel zu ungenau ist. ich möchte die ausrichtung im zusammenhang mit der zeit Loggen, von allen encodern, somit kann ich genau aufzeichnen zu welcher zeit ich welchen motor wie stark bewegt hab, und das zu jeder zeit wieder abspielen (Motion Controll)(geil wäre auch zeitscaliert). Die Daten können auch für ein 3D Cameratracking verwendet werden (wie zb Boujou, eine Software die ich auch auf arbeit nutze aus Videomaterial durch aufwendige berrechnung die exakte kamerabewegung im Raum nachzustellen,um gegebenenfalls Künstliche welten einzuarbeiten) ja und mit den Daten lässt sich das ganze extrem vereinfachen,oder untrackbare szene wie meeresoberflöche, person vor Bluescreen, Stürmisches Kornfeld,etc. einfachst bearbeiten.)

ja und deinen vorschlag die null einfach auszuradieren, glaube das klappt nicht bzw,hat letzten endes den gleichen effekt, oder vieleicht addiere ich vor dem tiefpass einfach sagen wir mal 32768, (unwahrscheinlich das ich 9 umdrehungen nach li oder re mache.) und ziehe sie danach einfach wieder ab?probier ich dann mal.

Die GPS koordinaten waren gedacht den Aufnahmestandort zu dokumentieren. Bei Video vileicht nicht so sinnvoll.

Warun nimmst du einen Tiefbassfilter und nicht einfach den Mittelwert aus 5 oder 10 Kompass-Messungen die jeweils zur aktuellen Positionsbestimmung gemacht werde. Das filtert auch das Rauschen raus.

Grüße Uwe

hm das wäre vieleicht die bessere lösung, im moment funktioniert es geade recht gut, der tiefpass hat allerdings noch einen für mich nützlichen vorteil, er glättet ja nicht nur sondern verzögert bei schnellen änderungen die werte,was von vorteil ist, ich möchte je eine recht sanfte start und stop phase haben. ich überlege nun welche sensor ich nun für die hoch runter bewegung nutzen sollte. ein Gyro der nicht wegdriftet,mit einem kompass der neigungsausgleich besitzt? kannst du da etwas empfehlen, inertialsensor(aber welcher) sollte nun auch nicht sooo teuer sein denke um die 150 müsste ich schon ausgeben oder.vieleicht tuts auch ein headtrecker oder copilotsystem...??

3 Achsen Beschleunigungssensor für die Neigung:

zB http://www.watterott.com/de/Breakout-Board-BMA180 mit integrierten A/D-Converter
oder
http://www.watterott.com/de/Breakout-Board-ADXL335 mit analogausgängen
Andere Modelle sind lieferbar.

Hast Du das Nullproblem auch wenn Du das Ergebnis als Floatzahl für die Berechnug behälst, für die Motorsteuerung aber rundest und eine INT zahl hast?
Grüße Uwe

also das mit der Null hab ich genauso gemacht wie du es beschrieben hast, Ich hab erstmal den work around das ich zuvor eine Sehr hohe zahl addiere, dann berechne und später wiedr abziehe. sozusagen würde dann nach 9 umdrehungen einmal die nullstelle kommen, was in der praxis eher nie passieren wird....

Wegen den Beschleunigungs sensoren? hab ich keinen plan bis jetzt, der BMA180 klingt so erstmal ganz gut, aber woher weiß der sensor welchen winkelgrad er im moment schaut ohne referenz oder horizont? und 2 sensoren miteinander zu verknüpfen (sensor fusion) das wird bei mir nix. ich dachte es giebt da gleich ein modul was neigungs ausgleichenden kompass und drehwinkel messer onboard hat.. irgendsowas, den neigungskompensierten kompass kann ich ja auch seperat kaufen und verbauen, zusammen wäre aber schicker.