3-Achse Magnetometer Sensor GY-271 HMC5883 HMC5883L..... Spukt nur Nullen raus

Moin,

Habe letztlich beim Ali ZWEI Exemplare des HMC5883 Kompassmodules bestellt und gleich mit folgendem Beispielscode testen wollen:

#include <Wire.h> //I2C Arduino Library

#define addr 0x1E //I2C Address for The HMC5883

void setup(){
  
  Serial.begin(9600);
  Wire.begin();
  
  
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x02); // Set the Register
  Wire.write(0x00); // Tell the HMC5883 to Continuously Measure
  Wire.endTransmission();
}


void loop(){
  
  int x,y,z; //triple axis data

  //Tell the HMC what regist to begin writing data into
  Wire.beginTransmission(addr);
  Wire.write(0x03); //start with register 3.
  Wire.endTransmission();
  
 
 //Read the data.. 2 bytes for each axis.. 6 total bytes
  Wire.requestFrom(addr, 6);
  if(6<=Wire.available()){
    x = Wire.read()<<8; //MSB  x 
    x |= Wire.read(); //LSB  x
    z = Wire.read()<<8; //MSB  z
    z |= Wire.read(); //LSB z
    y = Wire.read()<<8; //MSB y
    y |= Wire.read(); //LSB y
  }
  
  // Show Values
  Serial.print("X Value: ");
  Serial.println(x);
  Serial.print("Y Value: ");
  Serial.println(y);
  Serial.print("Z Value: ");
  Serial.println(z);
  Serial.println();
  
  delay(500);
}

Und folgendermassen verbunden:

VCC: 3.3V (Wobei auch 5V gehen würde)
GND: GND
SCL: A5
SDA: A4

Doch bei beiden Sensoren kommen nichts statt Nullen daher… Einen Defekt schliesse ich aus, das Kompassmodul ist auf Aliexpress sehr begehrt und wenn ich schon extra zwei gekauft und ausprobiert habe…

Nun vermute ich bei den Adressen liegt der Fehler. Definiert ist die I2C Adresse als 0x1E, wobei ich auch die Adresse 0x0D ausprobiert habe. Eine andere Option fand ich im Netz nicht.

Danke für die Hilfe!

MFG

Lass doch mal einen I2C-Scanner laufen, dann siehst Du die Adresse.

Gruß Tommy

Danke, super Sache, die Adresse lautet gemäss Scanner 0x0D. Läuft aber immernoch nicht!

Lass Dir mal den Returncode von endTransmission ausgeben.

uint8_t ret = Wire.endTransmission();
Serial.println(ret);

Gruß Tommy

Habe diese beiden Zeilen in den Loop kopiert, der Wert den er dafür rausgibt ist 0. Ist dies bei endTransmission korrekt?

Die sollst Du nicht irgendwohin kopieren, sondern Deine bestehenden endTransmission prüfen.

Gruß Tommy

void setup(){
  
  Serial.begin(9600);
  Wire.begin();
  
  
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x02); // Set the Register
  Wire.write(0x00); // Tell the HMC5883 to Continuously Measure
  uint8_t retsetup =  Wire.endTransmission();
  Serial.println(retsetup);
}
void loop(){
  
  int x,y,z; //triple axis data

  //Tell the HMC what regist to begin writing data into
  Wire.beginTransmission(addr);
  Wire.write(0x03); //start with register 3.
  uint8_t retloop =  Wire.endTransmission();
  Serial.println(retloop);

So richtig? Gibt ebenfalls für beide returns 0 !

0 ist ok. D.h. die Übertragung selbst funktioniert. Dann könnte es sein, dass Deine Befehlsfolge nicht richtig ist. Ich kenne aber Deinen Chip nicht.

Bist Du Dir bei dem sicher? Es gibt auch einen QMC5833L. Der braucht eine andere Ansteuerung.
Hier ist die Lib dazu - für alle Fälle.

Gruß Tommy

Es handelt sich wirklich um den HMC5883L, hier noch den Link dazu:

Aber vielen Dank schonmal, tolle Hilfeleistung.

Die schreiben viel rein, wenn der Tag lang ist.
Nimm mal ne Lupe und schaue, ob Du eine Beschriftung auf dem Schaltkreis erkennen kannst.

Ansonsten habe ich keine weiteren Hilfen anzubieten.

Gruß Tommy

Hallo,

Du kannst zB: die library von Adafruit verwenden, dazu brauchst du zwar noch die Sensor lib von denen, aber es funktioniert. Oder gibt es einen speziellen Grund, keine lib zu verwenden.
Ich mein, es spricht nichts dagegen nur mit der Wire library zu arbeiten. ich für meinen Teil, verstehe ich zwar das I2C Protokoll, doch ich hab immer mit den Daten (ACK) Probleme. ← Obwohl viele Datenblätter wirklich leicht und verständlich geschrieben sind, naja ich habe schon noch meine Probleme damit… naja. :confused:

Hier gibts sämtliche Informationen und die oben gennanten Libraries.

Zum Abschluss noch ein Servo Kompass Sketch, das ich zufällig vor 1-2 Tagen wieder entdeckt habe. Da sich ei Servo nur um 180° drehen kann, sind 2 LEDs in der Schaltung, die Zeigt dir an ob Du den ganzen Aufbau nach links oder rechts drehen musst.

/*
 * Digitaler Servo Kompass
 * by dony
 * 
 * Beschreibung:
 * Digital Kompass - Servo v2
 * Da es sich nur um einen 180° Servo handelt, muss das
 * Holzbrett gedreht werden.
 * 
 * Wenn Sie ungefähr wissen wo Norden ist, drehen Sie das
 * Projekt so das die x-Achse, die auf dem Kompass Breakout
 * aufgedruckt ist, ungefähr nach Norden zeigt. Die LEDs
 * zeigen an in welche Richtung das Holzbrett gedreht werden,
 * damit der Servo Motor in der Lage ist, den Nordpol anzuzeigen.
 * 
 * LED rot: nach rechts drehen
 * LED grün: nach links drehen
 * 
 */

//  Variablen
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

int leftPin = 6;
int rightPin = 5;
int PinServo1 = 10;

int headingDegrees = 0;
int servoNewPos = 0;

Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
Servo servo1;

/*  Funktionen  */
void turnLeft(int onOrOff) {
  if(onOrOff == 1) { digitalWrite(leftPin, HIGH); delay(30); }
  else { digitalWrite(leftPin, LOW); }
}

void turnRight(int onOrOff) {
  if(onOrOff == 1) { digitalWrite(rightPin, HIGH); delay(30); }
  else { digitalWrite(rightPin, LOW); }
}
void servoPos(int pos) {
  servo1.write(pos);
  delay(10);
}
void setup() {
  // Diese Funktion, wird nur beim start ausgeführt
  // Pins deklarieren
  //pinMode(13, OUTPUT);
  pinMode(rightPin, OUTPUT);
  pinMode(leftPin, OUTPUT);
//  Serielle Verbindung aufbauen
  Serial.begin(9600);
//  Servo Motor initalisieren
  servo1.attach(PinServo1);
  //servoPos(90);
  delay(3000);
  //  Kompass Starten
  mag.begin();
  Serial.println("Servo Kompass");
}

void loop() {
//  Dies ist vom Original Test Code, da er durch eine komplizierte Berrechnung den genauen Winkel ausrechnet, verwende ich diese Code Teil
  /* Get a new sensor event */

  /* aus dem Beispiel Code */
  sensors_event_t event; 
  mag.getEvent(&event);

  // Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
  // Calculate heading when the magnetometer is level, then correct for signs of axis.
  float heading = atan2(event.magnetic.y, event.magnetic.x);
  
  // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
  // Find yours here: http://www.magnetic-declination.com/
  // Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
  // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.

  float declinationAngle = 0.22;
  heading += declinationAngle;
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
   
  // Convert radians to degrees for readability.
  headingDegrees = heading * 180/M_PI; 
  Serial.print("Degrees: "); Serial.print(headingDegrees);

/*  Ende des Beispiel Copy&Paste  */

//  Wenn der Nordpol auserhalb der Reichweite des Servo Motor ist, 
//  zeigt er an das man ihn nach links oder rechts drehen soll.

  if(180 < headingDegrees && 270 > headingDegrees)
  {
//  Der Aufbau soll nach links gedreht werden
    turnRight(0);
    turnLeft(1);
  }
  else if(270 < headingDegrees && 360 > headingDegrees)
  {
//  Der Aufbau soll nach rechts gedreht werden
   turnLeft(0);
   turnRight(1);
  }
  else
  {
//  Der Servo Motor ist in Reichweite des Servo Motor
//  LEDs ausschalten
    turnRight(0);
    turnLeft(0);
    delay(1);
//  nächste Zeile kommt in der ersten version raus
    servoNewPos = headingDegrees;
//  Servo Motor positionieren
    servoPos(headingDegrees);
  }

//servoPos(headingDegrees);
//  Serial.print("Degrees: "); Serial.print(headingDegrees);

//aa = headingDegrees - 90;

//  Pause und Ankündigung zwischen den Loops
/*
  delay(50);
  Serial.print("\nNew Loop...");
  delay(20);
  Serial.println("DONE");
  delay(50);
*/
  Serial.println();
  delay(50);
}

lg dony

Ich lach mich schlapp es war tatsächlich der QMC diese Chinesen können einem echt den Tag vermiesen^^

Läuft alles bestens!

Nicht nur der Werbung glauben :wink:

Gruß Tommy