I2C AK09911, Fehler bei Wire.endTransmission()

Hallo Zusammen

Ich möchte die Register vom AK09911 beschreiben und auslesen, jedoch schaffe ich das irgendwie nicht.
Das habe ich bis jetzt getan.

Ich habe mir mal das Datasheet des besagten Chips durchgelesen und anschliessend auch die Reference Seite über die Wire.h Library auf der Arduino Webseite.
Nach etwas Verwirrung, was denn bitte xxh als Register Adressen zu bedeuten hat, habe ich rausgefunden, dass das einfach Hex Zahlen sind.
Dann habe ich versucht mein erstes Skript zu schreiben, um mir als erstes mal die X Achse auszugeben. Dieses sieht wie Folgt aus:

//Test for the Magnetic Compass Arduino for MA
#include <Wire.h>
int slave_adress = 12;
int statusofend = 0; //for the return value of the Wire.endTransmission() function.

void startup();
void powerdown();

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Online");
  startup();
  Serial.println("Startup done");
}

void loop() {
  if (Serial.readString() == "12"){
    powerdown();  
  }
  Wire.beginTransmission(slave_adress);
  Wire.write(0x11);
  Wire.requestFrom(slave_adress, 2);
  

  while(Wire.available() == 0);
  int x = Wire.read();

  Serial.print("Receved Value for X = ");
  Serial.println(x);
  Serial.print("Receved binary Value for X = ");
  Serial.println(x, BIN);
  Serial.println("loop done");
  
}

void startup(){
  Wire.beginTransmission(slave_adress);
  Serial.println("Transmission begin");
  Wire.write(0x31);
  Serial.println("Write Adress");
  Wire.write(0b00000010);                     //activates Continuous Mode 1
  Serial.println("Data written");
  statusofend = Wire.endTransmission();
  Serial.println(statusofend);
  Serial.println("Transmission ended");
}

void powerdown(){
  Wire.beginTransmission(slave_adress);
  Wire.write(0x31);
  Wire.write(0);
  Wire.endTransmission();

Das ganze bleibt immer im Setup stecken, nämlich im Wire.endTransmission() befehl.
Bearbeitung Es bleibt im ersten Wire.endTransmission() befehl stecken, dem aus void startup(); Bearbeitung

Datasheet: https://www.akm.com/akm/en/file/datasheet/AK09911C.pdf
Breakout Bord: Cjmcu-008 3 axis magnetometer compass magnetic sensor accuracy 0.15μt/ lsb module Sale - Banggood.com sold out-arrival notice-arrival notice

  • Die Adresse ist 0001100, entsprechend dem Datasheet, siehe Seite 21. Ich habe CAD auf Ground gesetzt.
  • Generelle Informationen über die Register finden sich auf Seite 25-29.
  • Das Skript soll den Continuous measuremenet mode 1 starten, Register und Wert, den ich in startup verwendet habe, finden sich auf Seite 29.
  • Nähere Informationen über die Datenregister auf Seite 28.
  • I2C Read / Write auf 23f.

Was ich noch nicht im Skript realisiert habe wäre eine Überprüfung einiger Status register.
(Satusregister 1 DRDY, DRO und HOFL in Statusregister 2)

Danke für eure Hilfe.

AliSot2000

Wire.beginTransmission(slave_adress);

Wire.write(0x11);
Wire.requestFrom(slave_adress, 2);

Das ist falsch!
Erst muss deine Transmission beendet werden, bevor ein Request begonnen wird.

Mit Wire.endTransmission(false) kannst du die Verbindung dann dennoch aktiv halten.

Den Baustein kenne ich allerdings nicht!
Schon mal dein I2C Scanner laufen lassen, um zu zeigen, ob die Adresse wirklich stimmt?

combie:
Das ist falsch!

Dem Datasheet zu folge nicht. (Siehe Bild im Anhang, oder 7.3.2. Seite 23 im Datasheet)
Weder im Text noch im Schema ist etwas von einer Stop Condition geschreiben, lediglich 2 start conditions.

combie:
Schon mal dein I2C Scanner laufen lassen, um zu zeigen, ob die Adresse wirklich stimmt?

Den habe ich mal durchlaufen lassen, allerdings erfolgslos. Ich habe das folgende Skript benutzt und noch einige Serial.print() befehle eingebaut.

Der Output des modifizierten Skripts ist nach 1min:

I2C Scanner
Scanning...
Current Adress: 1
Begin Transmission done

Ich habe mehrere male den Arduino resetet und auch meinen Arduino Uno durch einen Arduino Mega ersetzt mit dem selben Ergebnis.
Übrigns verwende ich die Geekcreit-Arduino-Kopien nicht original Arduinos.

// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    Serial.print("Current Adress: ");
    Serial.println(address);
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    Serial.println("Begin Transmission done");
    error = Wire.endTransmission();
    Serial.println("End Transmission done");

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

Dem Datasheet zu folge nicht.

Wenn du meinst.... die Wire Doku ignorieren du können....
Dann dauerts halt noch ein paar Tage länger, bis es läuft, soll nicht mein Problem sein.
Tipp:
Arbeite mit der Doku, und nicht dagegen.
Dagegen verlierst du.

Den habe ich mal durchlaufen lassen, allerdings erfolgslos.

Wenn der Scanner nichts anzeigt, dann hast du da auch noch ein Problem.
Und zwar eins, welches ZUERST gelöst werden möchte.
Pullup vergessen?

Weder im Text noch im Schema ist etwas von einer Stop Condition geschreiben, lediglich 2 start conditions.

Du hast bei dem Code, welche ich zitiert habe, nur eine Start Condition.
Keine 2.
Darum wird der Code versagen. Dich nicht glücklich machen.

Das halten der Verbindung, mag in deiner Anwendung nicht von Belang sein, aber Schlampig, ist es alle male, wenn man es nicht tut..
Tipp:
Baue und programmiere es so, dass es Multimaster und Multitasking fähig ist.

  1. das kostet dich nichts
  2. du lernst jetzt und hier das richtige
  3. du fällst irgendwann später nicht wegen dieser Schlampigkeit auf die Nase.

endTransmission() hätte man wirklich anders nennen müssen. Der Fehler wird so oft gemacht. Ein besserer Name wäre endSend() o.ä.

write() schreibt die Daten erst mal nur einen Puffer. Dieser Puffer wird mit erst mit endTransmission() versendet

Vielleicht....

Eigentlich reicht die Vorstellung/Projektion/Entscheidung völlig aus, dass auf ein Wire.beginTransmission(..) zwingend ein Wire.endTransmission() folgen muss.
Zumindest, bevor ein ein Wire.requestFrom(...) versucht wird.

Das kann man auch zu einer Frage der Symmetrie/Schönheit/Eleganz machen.
Es ist also (aus meiner Sicht) egal, ob man das Problem aus Richtung der Logik, oder der Ästhetik, angeht.
Der Erfolg kommt nur durch beachten der Bedingungen.

Ich habe eure Vorschläge ausprobiert.

Die SCL- und SDA-Lines sind jetzt jeweils über einen 5kOhm Widerstand an 3.3V angeknüpft.

Die von euch vorgeschlagenen Wire.endTransmission()- und Wire.beginTransmission()-Befehle habe ich auch hinzugefügt.

Die Anleitung zur Wire Library habe ich auch nochmal gelesen. Irgendwie wird ich da nicht ganz schlau draus, zumindest bei dem Wire.requestFrom()-Befehl.
If true, requestFrom() sends a stop message after the request, releasing the I2C bus. Was genau soll diese "stop message" sein? Ist das das "pull up" von SDA während SCL HIGH ist? Oder ist es sont was?

(Und was ich auch nicht verstehe, bei Wire.beginTransmission(); sendet man ja die Slave Adresse. Aber warum gibt man dann die Slave Adresse nochmal im Wire.requestFrom() als Parameter?)

Jedenfalls bleibt das Problem bestehen. Die Ausgabe in der Konsole sieht nach ca. 1min so aus:

Online
Transmission begin
Write Adress
Data written

Noch eine weitere Beobachtung. Ich habe mal so ein JYETech Oszilloskop verwendet um SDA und SCL zu inspzieren. Den Ground anschluss von Oszi. habe ich mit dem Ground vom Arduino verbunden und die Probe des Oszi. entweder and SCL oder and SDA.

Was ich dort gesehen habe ist eine Squarewave mit stark gerundeten Ecken. (Also sieht eher so wie die Mitte zwischen Sinus- und Squarewave aus). Diese hat eine Frequenz von 95.8kHz.
Die Welle bleibt einfach die ganze Zeit vorhanden. Sie taucht auf sobald der Arduino resetet wird und bleibt dann bestehen bis zum nächsten Reset. Auch ist die Welle Identisch von SCL und SDA und wenn ich SCL und SDA mit einem 10kOhm widerstand verbinde zeigt das Oszilloskop keine Spannungsschwankungen an. Also würde ich folgern, dass einerseits SCL und SDA in Phase sind und andererseits eigentlich nie eine Transmission statt findet.
Ich habe auch noch die Kontinuität von SCL und SDA auf dem Arduino gecheckt. Die dedizierten header sind verbunden zu den korrespondierenden Analoge pins, jedoch auch nicht untereinander.

Was ich auch noch probiert habe ist das Scanner Skript an einem I2C bus laufen zu lassen, an dem mehrere Geräte hingen. (noch ein Gyroskop/Accelerometer und ein Barometer/Humiditäts-Meter/Termometer) Auch in dem Skript scheiterte der Wire.endTransmission()-Befehl. Auch in dem Fall war das Resultat auf dem Oszilloskop das selbe.

Hier ist noch der revidierte Code.

//Test for the Magnetic Compass Arduino for MA
#include <Wire.h>
int slave_adress = 12;
int statusofend = 0;

void startup();
void powerdown();

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Online");
  startup();
  Serial.println("Startup done");
}

void loop() {
  if (Serial.readString() == "12"){
    powerdown();  
  }
  Wire.beginTransmission(slave_adress);
  Wire.write(0x11);
  
  Wire.endTransmission(false);          //Der Empfehlung nach eingefügt
  Wire.beginTransmission(slave_adress); //Der Empfehlung nach eingefügt
  
  Wire.requestFrom(slave_adress, 2);
  

  while(Wire.available() == 0);
  int x = Wire.read();
  Wire.endTransmission();               //Der Empfehlung nach eingefügt
  
  Serial.print("Receved Value for X = ");
  Serial.println(x);
  Serial.print("Receved binary Value for X = ");
  Serial.println(x, BIN);
  Serial.println("loop done");
  
}

void startup(){
  Wire.beginTransmission(slave_adress);
  Serial.println("Transmission begin");
  Wire.write(0x31);
  Serial.println("Write Adress");
  Wire.write(0b00000010);
  Serial.println("Data written");
  statusofend = Wire.endTransmission(); //Hier scheitert das Skript. 
  Serial.println(statusofend);          //Es lief bisher noch nie weiter.
  Serial.println("Transmission ended");
}

void powerdown(){
  Wire.beginTransmission(slave_adress);
  Wire.write(0x31);
  Wire.write(0);
  Wire.endTransmission();
}

AliSot2000

Die Welle bleibt einfach die ganze Zeit vorhanden.

Kein Wunder, wenn du permanent auf dem Bus rum reitest.

void loop() {
  if (Serial.readString() == "12"){
    powerdown();  
  }
  Wire.beginTransmission(slave_adress);
  Wire.write(0x11);
  
  Wire.endTransmission(false);          //Der Empfehlung nach eingefügt
  Wire.beginTransmission(slave_adress); //Der Empfehlung nach eingefügt
  
  Wire.requestFrom(slave_adress, 2); // <<<---- GRRR
...

Als hätte ich nichts gesagt....
Schade eigentlich.

Was genau soll diese "stop message" sein?

Die Stopp Message gibt den Bus frei.
Manchmal muss man das, z.B. wenn man mit seinen Operationen auf dem Bus fertig ist.
Um anderen Mastern eine Chance zu geben.
Und machmal darf man den Bus eben nicht frei geben, damit einem kein anderer Master dazwischen hacken kann.
Für dich ist beides richtig.
Schön geordnet, in der richtigen Reihenfolge.

Nochmal: endTransmission() sendet Daten. Nach dem Empfangen hat das nichts zu suchen

combie:
Kein Wunder, wenn du permanent auf dem Bus rum reitest.

void loop() {

if (Serial.readString() == "12"){
    powerdown(); 
  }
  Wire.beginTransmission(slave_adress);
  Wire.write(0x11);
 
  Wire.endTransmission(false);          //Der Empfehlung nach eingefügt
  Wire.beginTransmission(slave_adress); //Der Empfehlung nach eingefügt
 
  Wire.requestFrom(slave_adress, 2); // <<<---- GRRR
...

Was haben wir jetzt gegen Wire.requestFrom? Soll da noch ein "true" rein, damit ich nicht eine Wire.endTransmission() schicken muss?

Und wo und wie reite ich auf dem Bus rum? Soll ich das if Statement rausnehmen? Wenn ich darauf hinweisen darf, wir haben diese Stelle im Code NIE erreicht! Ich würde wirklich gerne mal dahin kommen. Und noch dazu besteht dieses Problem mit endTransmission() ja nicht nur in diesem Skript sondern auch im Scanner Script

combie:
Als hätte ich nichts gesagt....
Schade eigentlich.
Die Stopp Message gibt den Bus frei.
Manchmal muss man das, z.B. wenn man mit seinen Operationen auf dem Bus fertig ist.
Um anderen Mastern eine Chance zu geben.
Und machmal darf man den Bus eben nicht frei geben, damit einem kein anderer Master dazwischen hacken kann.
Für dich ist beides richtig.
Schön geordnet, in der richtigen Reihenfolge.

Das hätte ich jetzt begriffen... schön. Also wenn ich da gerne noch etwas zurück hätte dann false, sonst true.

Was haben wir jetzt gegen Wire.requestFrom?

Keiner hat was gegen Wire.requestFrom !
Sogar ganz im Gegenteil.
Nur du setzt es an die falsche Stelle.

Da reden wie jetzt seit dem Anfang drüber....
Wie kann ich dir helfen, damit der Groschen fällt?

Ich wiederhole es gerne nochmal:

Eigentlich reicht die Vorstellung/Projektion/Entscheidung völlig aus, dass auf ein Wire.beginTransmission(..) zwingend ein Wire.endTransmission() folgen muss.
Zumindest, bevor ein ein Wire.requestFrom(...) versucht wird.

Noch mal mit anderen Worten:
Jedem Wire.beginTransmission hat ein Wire.endTransmission zu folgen.
Dazwischen darf sich kein Wire.requestFrom befinden.

Jedem Wire.beginTransmission hat ein Wire.endTransmission zu folgen.
Dazwischen darf sich kein Wire.requestFrom befinden.

Combie gibt gern etwas zum Nachdenken, bzw. ungern idiotensichere Anweisungen..

In Wirklichkeit meint er:

void loop() {
   ...
  Wire.beginTransmission(slave_adress);
  Wire.write(0x11);
  Wire.endTransmission(false);          //Der Empfehlung nach eingefügt
  // Wire.beginTransmission(slave_adress); // <<<---- GRRR
  
  Wire.requestFrom(slave_adress, 2);  
...

Vor requestFrom() (lesen) darf natürlich kein beginTransmission() (start senden) stehen.

In Wirklichkeit meint er:

Das weiß ich nicht, ob ich das meine...
Denn ich kenne den Baustein nicht, und habe den nicht da, um ihn zu testen.

Aber ich weiß, recht gut (hoffe ich), wie I2C fluppt.
Denn habe es selbst recht vielfältig im Einsatz.

Und ja, liebster michael_x, so sieht es viel besser aus.

--
Wie oft ich schon gesehen habe, wie versucht wird ein requestFrom() in eine Transmission einzubetten, kann ich gar nicht zählen. Sowohl hier im Forum, als auch woanders.
Interessant ist ja dabei, dass sowas in keinem der Wire Beispiele zu sehen ist.
In keiner der vielen im Internet zu findenden (funktionierenden) I2C Abhandlungen.
Und davon gibt es hunderte.
Wie man auf eine solche Idee kommen kann ist mir ein völliges Rätsel.
Darum stehe ich auch etwas hilflos davor.
Ich sehe was falsch läuft, kann es aber nicht retten.
U.A. auch weil die Einsicht (in dem Punkt) nicht bei mir aufflackern muss.

Auch Serenifly hat hier mehrfach versucht, zu vermitteln, dass beginTransmission() nichts mit dem I2C Bus tut, sondern erst endTransmission() die Dinge, die zu tun, sind erledigt.

Und ja, liebster michael_x, so sieht es viel besser aus.

Ein Lob aus deiner Feder, hmmm. Danke :wink:

Auch hätte ich vielleicht sagen sollen dass beginTransmission() auch nur einen Sendevorgang startet

Das darf man eben nicht wörtlich nehmen und denken jede Übertragung (egal ob Senden oder Empfangen) müsste zwischen begin und end eingeschlossen werden. Wenn man es weiß ist es klar, aber den Fehler sieht man bei I2C Anfängern immer wieder. Deshalb gebe ich die Schuld teilweise schon den API Entwicklern, die hier weniger verwirrende Methoden-Namen vergeben hätten sollen.

Schlimmer finde ich, dass in einem Transmission Block mehrere Write erlaubt sind, aber in einem onRequest Handler nur ein Write.
Auch, dass die Slave Ereignis Handler im ISR Kontext laufen, führt oft zu Debug - Sondersitzungen.

Die Doku ist an den Stellen arg knapp gehalten.

Also dann sollte das Skript so aussehen, damit es konform ist? ...hoffentlich ist jetzt mal mein Groschen gefallen, ich habe dem Tisch wirklich einen festen Stoff gegeben...

//Test for the Magnetic Compass Arduino for MA
#include <Wire.h>
int slave_adress = 12;
int statusofend = 0;

void startup();
void powerdown();

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("Online");
  startup();
  Serial.println("Startup done");
}

void loop() {
  if (Serial.readString() == "12"){
    powerdown();  
  }
  Wire.beginTransmission(slave_adress);
  Wire.write(0x11);
  
  Wire.endTransmission(false);          //Der Empfehlung nach eingefügt
  //Wire.beginTransmission(slave_adress); //Der Empfehlung nach eingefügt
  
  Wire.requestFrom(slave_adress, 2, true);
  

  while(Wire.available() == 0);
  int x = Wire.read();
  
  //Wire.endTransmission();               //Der Empfehlung nach eingefügt
  
  Serial.print("Receved Value for X = ");
  Serial.println(x);
  Serial.print("Receved binary Value for X = ");
  Serial.println(x, BIN);
  Serial.println("loop done");
  
}

void startup(){
  Wire.beginTransmission(slave_adress);
  Serial.println("Transmission begin");
  Wire.write(0x31);
  Serial.println("Write Adress");
  Wire.write(0b00000010);
  Serial.println("Data written");
  statusofend = Wire.endTransmission(true); //Hier scheitert das Skript. 
  Serial.println(statusofend);          //Es lief bisher noch nie weiter.
  Serial.println("Transmission ended");
  Serial.println("Done with startup");
}

void powerdown(){
  Wire.beginTransmission(slave_adress);
  Wire.write(0x31);
  Wire.write(0);
  Wire.endTransmission();
}

Wenn das jetzt stimmt, dann muss ich sagen, dass ich wirklich Mühe mit den References der Wire Library hatte. Ich verstehe ja, dass man alles gerne kurz und knackig halten würde, jedoch ist das wie erwähnt wurde nicht sonderlich förderlich für Anfänger. Bevor ich mich hier reingestürzt hatte, habe ich einige Videos zu I2C auf Youtube angeschaut und das Datasheet gelesen.
Aus den Videos habe ich "gelernt" dass eine I2C Kommunikation im Prinzip immer so aussehen müsste:

Start vom Master | 7Bit Adresse vom Master | R/W bit | Acknowledgement | Registeradresse | Acknowledgment | 1 Byte Write/Read | Acknowledgment | Stop vom Master

Daraus entwickelte dann sich meine fälschliche Erwartungshaltung, dass in der Library ein Befehl für nur für den Start und Stop da sein müsste, eine Write-Funktion um jeweils 8bit zu senden, eine Read-Funktion um den Input zu lesen und eine Funktion um zu überprüfen, ob ein Acknowledgment stattgefunden hatte. Ich würde behaupten, dass daraus dann dieses "komische" Skript entstanden ist und mein schwehrfälliger Gröschen. Zumindest habe ich nicht diese "inkonsistenz" erwartet, dass man fürs Auslesen lediglich eine Funktion braucht, fürs schreiben aber gleich 2.

Naja, damit funktioniert der Code noch immer nicht. Es scheitert immernoch am Wire.endTransmission() im STARTUP.

Wire.requestFrom(slave_adress, 2, true);
  

  while(Wire.available() == 0);

Wenn du 2 Bytes anforderst, wird Wire.available() == 0 niemals true werden.
Die Schleife ist also flüssiger als Wasser.
Überflüssig.

int x = Wire.read();
Soweit mir bekannt, liest read nur 1 Byte, kein int.
(die Doku gibt mir recht)

Also:
Du liest von den angeforderten 2 Byte nur 1 Byte aus.

Naja, damit funktioniert der Code noch immer nicht. Es scheitert immernoch am Wire.endTransmission() im STARTUP.

Dazu kann ich erstmal nichts sagen...
Denn ich kann das nicht testen und ausmessen.

Läuft denn der Scanner mittlerweile?

Ich habe mehrere male den Arduino resetet und auch meinen Arduino Uno durch einen Arduino Mega ersetzt mit dem selben Ergebnis.
Übrigns verwende ich die Geekcreit-Arduino-Kopien nicht original Arduinos.

Alles 5V?
Aber der Sensor 3,3V.
Du wirst einen Levelshifter brauchen, damit du das stabil bekommst.

combie:
Soweit mir bekannt, liest read nur 1 Byte, kein int.
(die Doku gibt mir recht)

Also:
Du liest von den angeforderten 2 Byte nur 1 Byte aus.

Danke für den Hinweis. Dann werde ich mir da mal noch überlegen, wie ich das lösen werde.
Mal so nebenbei, im Datasheet steht, dass die gelesenen Werte von -8192 bis +8292 gehen und um "two's complement und little endian format abgespeichert werden. Wenn ich mich nicht täusche ist das die selbe Art, wie bei einem Int die Zahlen abgespeichert werden oder? Dann sollte ich doch einfach mit Bitmath die zwei Bytes, die ich bekomme zusammenfügen können.

combie:
Läuft denn der Scanner mittlerweile?Alles 5V?
Aber der Sensor 3,3V.
Du wirst einen Levelshifter brauchen, damit du das stabil bekommst.

Facepalm Ah das hat's gelöst, danke.(Ich hab mal nur einen 5V I2C Slave angeschlossen und der Scanner hat geklappt.)
Ich glaube bei diesem Problem hätte man mich nicht wie einen Anfänger sondern wie eine Oma ansprechen sollen: "Haben sie denn die Kabel auch richtig angeschlossen... :wink:

Dann werde ich mir mal einen Levelshifter besorgen müssen. Hast du/ihr eine Empfehlung?

Ach, es gibt so viele...
Hier ist so einer: https://www.ebay.de/itm/123201538816

Ich glaube bei diesem Problem hätte man mich nicht wie einen Anfänger sondern wie eine Oma ansprechen sollen: "Haben sie denn die Kabel auch richtig angeschlossen... :wink:

Wir sehen hier nur das, was du zeigst.
Leider hast du keinen Schaltplan gezeigt.
Also, auch keine Anweisung in die Richtung.

Tipp zum Umgang mit Annahmen:
Versehe Annahmen mit Wahrscheinlichkeiten!
Zwischen 0 und 1
Alle logisch verknüpften annahmen miteinander multiplizieren

Beispiel:
Annahme 1: Ich habe I2C verstanden = 0,5
Annahme 2: Ich habe Wire verstanden = 0,5
Annahme 3: Der elektrische Aufbau ist korrekt = 0,5

Auf diesen Annahmen baut das Programm auf.
Annahmen 4: Das Programm arbeitet korrekt = 0,5 * 0,5 * 0,5 = 0,125

In diesem Beispiel wird das Programm nur mit viel Glück (sofort) funktionieren.