MCU 90393 über SPI

Hallo,
ich möchten den Magnetsensor MCU 90393 über die SPI-Schnittstelle auslesen.
Leide klappt das nicht so und im Netz finde ich kein Beispiel.

Ich habe versucht das funktionierende Beispiel über die I2C umzuschreiben.

Was ist nicht richtig?

LG

Mein SPI-Versuch:

#include <SPI.h>
 
const int slaveSelectPin = 10;
 
void setup(){
  pinMode(slaveSelectPin, OUTPUT);
  digitalWrite(slaveSelectPin, HIGH);
  Serial.begin(115200);
  SPI.begin();
  digitalWrite(slaveSelectPin, LOW);
  delay(100);
  // Select Write register command
  SPI.transfer(0x60);
  // Set AH = 0x00, BIST disabled
  SPI.transfer(0x00);
  // Set AL = 0x5C, Hall plate spinning rate = DEFAULT, GAIN_SEL = 5
  SPI.transfer(0x5C);
  // Select address register, (0x00 << 2)
  SPI.transfer(0x00);
  // Stop I2C Transmission
  delay(100);
   
  // Request 1 byte of data
  unsigned int c = SPI.transfer(0x00);
 
  // Select Write register command
  SPI.transfer(0x60);
  // Set AH = 0x02
  SPI.transfer(0x02);
  // Set AL = 0xB4, RES for magnetic measurement = 0
  SPI.transfer(0xB4);
  // Select address register, (0x02 << 2)
  SPI.transfer(0x08);
  // Read status byte
  c = SPI.transfer(0x00);
  digitalWrite(slaveSelectPin, HIGH);
  delay(300);
}
 
void loop(){
  unsigned int data[7];
  digitalWrite(slaveSelectPin, LOW);
  // Start single meaurement mode, ZYX enabled
  SPI.transfer(0x3E);
  // Read status byte
  unsigned int c = SPI.transfer(0x00);
 
  delay(100);
   
  // Send read measurement command, ZYX enabled
  SPI.transfer(0x4E);
   
 
  // Read 7 bytes of data
  // status, xMag msb, xMag lsb, yMag msb, yMag lsb, zMag msb, zMag lsb
    data[0] = SPI.transfer(0x00);
    data[1] = SPI.transfer(0x00);
    data[2] = SPI.transfer(0x00);
    data[3] = SPI.transfer(0x00);
    data[4] = SPI.transfer(0x00);
    data[5] = SPI.transfer(0x00);
    data[6] = SPI.transfer(0x00);
  digitalWrite(slaveSelectPin, HIGH);
  // Convert the data
  int xMag = data[1] * 256.00 + data[2];
  int yMag = data[3] * 256.00 + data[4];
  int zMag = data[5] * 256.00 + data[6];
  static int xMax, yMax, xMin, yMin;

  Serial.print("X-Axis : ");
  Serial.println(xMag);
  Serial.print("Y-Axis : ");
  Serial.println(yMag);
  /*Serial.print("Z-Axis : ");
  Serial.println(zMag);
  Serial.println("");*/



  delay(300);
}

Funktionierendes Beispiel über I2C:

#include<Wire.h>
#include <Streaming.h>
 
// MLX90393 I2C Address is 0x0C(12)
#define Addr 0x0C
 
void setup(){
  // Initialise I2C communication as MASTER
  Wire.begin();
  // Initialise serial communication, set baud rate = 9600
  Serial.begin(9600);
   
  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select Write register command
  Wire.write(0x60);
  // Set AH = 0x00, BIST disabled
  Wire.write(0x00);
  // Set AL = 0x5C, Hall plate spinning rate = DEFAULT, GAIN_SEL = 5
  Wire.write(0x5C);
  // Select address register, (0x00 << 2)
  Wire.write(0x00);
  // Stop I2C Transmission
  Wire.endTransmission();
   
  // Request 1 byte of data
  Wire.requestFrom(Addr, 1);
   
  // Read status byte
  if(Wire.available() == 1){
    unsigned int c = Wire.read();
  }
 
  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select Write register command
  Wire.write(0x60);
  // Set AH = 0x02
  Wire.write(0x02);
  // Set AL = 0xB4, RES for magnetic measurement = 0
  Wire.write(0xB4);
  // Select address register, (0x02 << 2)
  Wire.write(0x08);
  // Stop I2C Transmission
  Wire.endTransmission();
   
  // Request 1 byte of data
  Wire.requestFrom(Addr, 1);
   
  // Read status byte
  if(Wire.available() == 1){
    unsigned int c = Wire.read();
  }
  delay(300);
}
 
void loop(){
  unsigned int data[7];
   
  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Start single meaurement mode, ZYX enabled
  Wire.write(0x3E);
  // Stop I2C Transmission
  Wire.endTransmission();
   
  // Request 1 byte of data
  Wire.requestFrom(Addr, 1);
   
  // Read status byte
  if(Wire.available() == 1){
    unsigned int c = Wire.read();
  }
  delay(100);
   
  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Send read measurement command, ZYX enabled
  Wire.write(0x4E);
  // Stop I2C Transmission
  Wire.endTransmission();
   
  // Request 7 bytes of data
  Wire.requestFrom(Addr, 7);
   
  // Read 7 bytes of data
  // status, xMag msb, xMag lsb, yMag msb, yMag lsb, zMag msb, zMag lsb
  if(Wire.available() == 7);{
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
    data[6] = Wire.read();
  }
   
  // Convert the data
  int xMag = data[1] * 256.00 + data[2];
  int yMag = data[3] * 256.00 + data[4];
  int zMag = data[5] * 256.00 + data[6];
  
  Serial.print("X-Axis : ");
  Serial.println(xMag);
  Serial.print("Y-Axis : ");
  Serial.println(yMag);
  Serial.print("Z-Axis : ");
  Serial.println(zMag);
  Serial.println("");

  delay(300);
}

Meinst du den MLX90393 ?

Dann lies hier.

HotSystems:
Meinst du den MLX90393 ?

Dann lies hier.

Das ist ein I2C-Beispiel!

https://learn.sparkfun.com/tutorials/qwiic-magnetometer-mlx90393-hookup-guide/all

Bist Du sicher daß Deine Platiene die Möglichkeit hat SPI zu aktivieren?
Grüße Uwe

Ja,
sie hat SPI-Anschlüsse.
Die sind nicht zur Deko!

ar182:
Das ist ein I2C-Beispiel!

Ja, richtig.
Dann habe ich deinen Eingangspost wohl falsch verstanden.

Welches Modul hast Du eigentlich?
Grüße Uwe

MCU 90393

Und mit welchem Arduino betreibst Du nen Sensor? Du hast schon gesehen, dass der Sensor nur Signale bis max 3,6V kann? Du darfst den Sensor nicht an einem Uno oder Nano oder nem anderen 5V Arduino direkt betreiben, da musst du Levelschifter verwenden.

LG Stefan

Deltaflyer:
Und mit welchem Arduino betreibst Du nen Sensor? Du hast schon gesehen, dass der Sensor nur Signale bis max 3,6V kann? Du darfst den Sensor nicht an einem Uno oder Nano oder nem anderen 5V Arduino direkt betreiben, da musst du Levelschifter verwenden.

LG Stefan

Hallo Stefan,

vielen Dank für deine Antwort.
Es wäre aber hilfreich, wenn ihr meinen Text auch lesen würdet.
Da kann man herauslesen, dass ich über I2C durchaus eine Verbindung aufbauen kann.

Ich habe im oberen Sketch versucht, die Befehle die in der I2C- Version verwendet werden
auf eine SPI-Version zu übertragen.

Jetzt währe zu klären, ob das grundsätzlich so möglich ist und wenn ja, wo der Fehler liegt.

Jetzt währe zu klären, ob das grundsätzlich so möglich ist und wenn ja, wo der Fehler liegt.

Leider kann ich nicht nicht sagen wie es geht.
Denn es fehlt mir so ein Teil zum gegentesten.
Aber laut Datenblatt geht es.

Ein paar Sachen stehen im Datenblatt, die ich nicht in deinem Code identifizieren kann.
(vielleicht habe ich sie auch übersehen)

Jeglicher Kommandotransfer muss durch loslassen der /CS Leitung abgeschlossen werden, bevor das nächste Kommando abgesendet werden kann.
Auf manches Kommando muss eine Pause folgen.
Das erste Kommando im Programm sollte den I2C Teil des Sensors deaktivieren.


Auch bleibt die Frage nach den tödlichen 5V offen.

Danke combie,

damit kann ich arbeiten.
Ich werde mich am Abend daran machen:

ar182:
Hallo Stefan,

vielen Dank für deine Antwort.
Es wäre aber hilfreich, wenn ihr meinen Text auch lesen würdet.
Da kann man herauslesen, dass ich über I2C durchaus eine Verbindung aufbauen kann.

Ich habe im oberen Sketch versucht, die Befehle die in der I2C- Version verwendet werden
auf eine SPI-Version zu übertragen.

Jetzt währe zu klären, ob das grundsätzlich so möglich ist und wenn ja, wo der Fehler liegt.

ICH HABE DEINEN TEXT GELESEN! Gerade deshalb habe ich ja wegen der Levelinkompatiblität aufmerksam gemacht. SPI ist nunmal nicht gleich I2C! Was mit I2C vlt. grade noch so funktioniert, muss mit SPI noch lange nicht klappen. Bei i2C zieht das Device die Daten-Leitung auf 0V. Bei SPI muss das Device auch HIGH-Pegel liefern können. Wenn es das nicht schafft, weil zu hohe HIGH.Pegel erwartet werden, kann das Teil nunmal nix von Daten senden.

Das nur so am Rande, falls Dir SPI noch weiter Probleme bereitet, obwohl der Programm-Code passt.

LG Stefan