Forum: Mikrocontroller und Digitale Elektronik I2C Expander reagiert nicht


von mr.Moe (Gast)


Lesenswert?

Hallo zusammen,
ich möchte einen MAX7313 (Port Expander) über I2C ansprechen.
Für den Anfang möchte ich einfach alle Ports als Ausgänge konfigurieren
und dann auf Low schalten.
Dazu habe ich dieses kleine Skript geschrieben.


*****************************************************************
#include <Wire.h>

#define SDA 21
#define SCL 22

void einschalten(void);

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA, SCL, 100000);
}

void loop() {
  for(int i=1; i<=255; i++){
    Wire.beginTransmission(i);
    Wire.write(0x06);               //Port Konfiguration P7-P0
    Wire.write(0x00);               //Ports sollen zu Outputs werden
    Wire.write(0x02);
    Wire.write(0x00);
    Wire.endTransmission(true);

    delay(100);

    if(i==255){
      Serial.println("neuer Durchlauf");
    }
      }
}
***************************************************

mit einem Scanner habe ich den Expander bereits gefunden, da hatte er 
die Adresse 0x28 (A0 auf SCL, A1 und A2 auf GND) die Adresse scheint 
also richtig zu sein. Wenn ich die Adresse direkt eingebe passiert aber 
auch nichts, deshalb die Schleife.
Im Datenblatt habe ich dann gelesen, dass immer zuerst das Command Byte 
gesendet werden muss um fest zu legen in welches Register geschrieben 
werden soll, dafür das 0x06.
Mit 0x02 will ich dann auf das Blink phase 0 Register zugreifen, dieses 
sollte nach dem Datenblatt für die Output logik Level zuständig sein 
wenn die Blinkfunktion deaktiviert ist.

SCL und SDA habe ich auch bereits an ein Oszi gehängt, diese senden 
auch.

Der Expander reagiert aber überhaupt nicht.
Kann mir jemand weiterhelfen?

von Jim M. (turboj)


Lesenswert?

mr.Moe schrieb:
> die Adresse 0x28

I2C Adressen sind wegen dem R/W Bit immer etwas ... speziell zu 
betrachten.

IIRC will Wire.beginTransmission() die komplette Adresse haben, also

Wire.beginTransmission((0x28<<1) | 1 );

oder

Wire.beginTransmission((0x28<<1) | 0 );

eins ist Lesen, die andere Variante schreiben über I²C. Ich bin grade zu 
faul nachzuschlagen ob Lesen die 1 oder die Null war.

Mit Glück ist eine sprechende Definition in Wire.h zu finden.

von mr.Moe (Gast)


Lesenswert?

Danke schon mal,

das mit den oder'n hat zwar noch nichts weiter gebracht, aber ich denke 
eigentlich auch, dass es an den Adressen liegt.
Aber deinem Tip mit der Bibliothek geh ich jetzt einfach mal nach.

von mr.Moe (Gast)


Lesenswert?

ne bringt micht nicht wirklich weiter

von Arduinoquäler (Gast)


Lesenswert?

mr.Moe schrieb:
> #define SDA 21
> #define SCL 22

Wenn es denn ein Arduino Mega sein soll dann muss es
1
#define SDA 20
2
#define SCL 21

heissen.

von mr.Moe (Gast)


Lesenswert?

Danke für die Info,
aber nein es handelt sich um ein ESP32

von Arduinoquäler (Gast)


Lesenswert?

mr.Moe schrieb:
> aber nein es handelt sich um ein ESP32

Und das kann man nicht gleich bei der Thread-Eröffnung schreiben?

Wie viele Dinge muss man noch vermuten bis alle relevanten
Randbedingungen offengelegt sind?

von Florian P. (ol1cr0n)


Lesenswert?

Hast du zum Schreiben der Register mal die Deviceadresse 0x50 getestet?

von mr.Moe (Gast)


Lesenswert?

Ja auch diese hab ich schon getestet, auch das hat nicht funktioniert.

von Arduinoquäler (Gast)


Lesenswert?

Pullup Widerstände vorhanden?

2x 2.2k oder 4.7k

von Joachim B. (jar)


Lesenswert?

mr.Moe schrieb:
> ich möchte einen MAX7313 (Port Expander) über I2C ansprechen.

welche Spannung bekommt dieser?

mr.Moe schrieb:
> auch das hat nicht funktioniert

evtl. hilft ein Levelshifter

auch solltest du ein I2C Sannerprogramm mal probieren

ABER je nach ESP32 werden verschiedene Pins genutzt, Heltec nutzt andere 
als Wemos Lolin32

Das musst du erst mal prüfen und richtig benutzen.

Es gibt so viele Fehlermöglichkeiten und ohne echte Infos von dir ist es 
nur Kaffeesatzleserei hier

: Bearbeitet durch User
von mr.Moe (Gast)


Lesenswert?

Ok also ich versuche noch mal alle relevanten Daten zusammen zu fassen.

verwendeter Controller= NODE MCU ESP 32

der Expander liegt an 3,3 V und GND

die Adresspins liegen A2= GND, A1= GND, A0= SCL

Pullup widerstände sind verbaut mit 10 kohm der Wert wurde wohl gemerkt 
vom Datenblatt so vorgeschrieben

Ein I2C Scanner habe ich bereits verwendet, es kam 0x28 heraus.


Ist sonst noch etwas relevant?

von Joe F. (easylife)


Lesenswert?

Trenne mal die 2 Register writes.
Ansonsten macht dir das etwas eigenwillig implementierte 
"auto-increment" einen Strich durch die Rechnung.
1
    Wire.beginTransmission(addr);
2
    Wire.write(0x06);               //Port Konfiguration P7-P0
3
    Wire.write(0x00);               //Ports sollen zu Outputs werden
4
    Wire.endTransmission(true);
5
6
    // evtl. delay hier
7
8
    Wire.beginTransmission(addr);
9
    Wire.write(0x02);
10
    Wire.write(0x00);
11
    Wire.endTransmission(true);

von Joachim B. (jar)


Lesenswert?

mr.Moe schrieb:
> die Adresspins liegen A2= GND, A1= GND, A0= SCL

und was soll dieser Unsinn?

ich bin hier raus

: Bearbeitet durch User
von Arduinoquäler (Gast)


Lesenswert?

Joachim B. schrieb:
> und was soll dieser Unsinn?

Laut Datenblatt ist das eine gültige Adress-Konfiguration!

RTFM!

von HildeK (Gast)


Lesenswert?

Joachim B. schrieb:
> und was soll dieser Unsinn?

Kannte ich auch noch nicht, aber es ist tatsächlich so, dass das Device 
mit den drei Adressbits und dem wahlweisen Anschluss dieser an VCC, GND, 
SCL oder SDA insgesamt 64 Adressen einstellbar sind.

von Joachim B. (jar)


Lesenswert?

Arduinoquäler schrieb:
> RTFM!

hatte ich, A0 an SCL echt jetzt?

OK habe noch mal nach A0 gesucht, so ein Teil ist mir bis jetzt noch 
nicht untergekommen, aber nun gut, der Rest gilt ja weiterhin.

bei 3,3V am MAX ist Levelshifter unnötig.
Ob die Pindefinition stimmt am seinem ESP kann ich hier nicht prüfen, 
wie geschrieben Heltec (mit OLED) und Wemos nutzen verschiedene.

Da muss sich der TO selber durchackern, oder ein anderer hat eine Idee.

von Arduinoquäler (Gast)


Lesenswert?

Joachim B. schrieb:
> OK habe noch mal nach A0 gesucht, so ein Teil ist mir bis jetzt noch
> nicht untergekommen, aber nun gut, der Rest gilt ja weiterhin.

Er hat ja bereits eine gültige Adresse herausgefunden, diese
gilt es nun einfach zu nutzen!

mr.Moe schrieb:
> Ein I2C Scanner habe ich bereits verwendet, es kam 0x28 heraus.

Schaffst du es nicht daraus die richtigen Schlüsse zu ziehen?

von HildeK (Gast)


Lesenswert?

mr.Moe schrieb:
> Pullup widerstände sind verbaut mit 10 kohm der Wert wurde wohl gemerkt
> vom Datenblatt so vorgeschrieben

Ich kann leider diese Aussage aus dem Datenblatt nicht entnehmen.
Dort steht:
A pullup resistor, typically 4.7kΩ,is required on SDA.
Das selbe nochmals für SCL.

Die 10k können funktionieren, müssen aber nicht - je nach Buslänge, 
Versorgungsspannung, Geschwindigkeit, Zahl der Teilnehmer.
Es hätte auch mich gewundert, wenn da 10k genannt worden wären ...

von mr.Moe (Gast)


Angehängte Dateien:

Lesenswert?

nein ich schaffe es nicht daraus die richtigen Schlüsse zu ziehen.

und zu der Frage der Pins: wie gesagt, diese senden ja auch, das habe 
ich bereits mit einem Oszi nachgewiesen.

und diese Schleife die ich ganz oben verwende, müsste da nicht früher 
oder später die richtige adresse mit dabei sein?

von mr.Moe (Gast)


Lesenswert?

ach und der anhang ist da jetzt wohl gerade noch mit reingerutscht

von Wolfgang (Gast)


Lesenswert?

mr.Moe schrieb:
> Wenn ich die Adresse direkt eingebe passiert aber
> auch nichts, deshalb die Schleife.

Dann nimm einen Logikanalysator und guck dem Bus auf die Finger, 
insbesondere auch auf das Ack-Bit (Sowohl mit Scanner, als auch mit 
deinem Programm).

von mr.Moe (Gast)


Lesenswert?

hm ja dann werde ich das mal machen müssen.

Und noch danke an alle die sich mit meinem Problem befasst haben.

von Joe F. (easylife)


Lesenswert?

Hast du denn jetzt mal ausprobiert, deine Register-Writes in 2 Portionen 
aufzuteilen?
Hintereinander 2 Writes auf 2 unterschiedliche Register funktioniert so 
nicht, stattdessen macht das IC ein "auto-inkrement", wobei da je nach 
Register auch mal ein Decrement stattfindet...

Beitrag "Re: I2C Expander reagiert nicht"

: Bearbeitet durch User
von Mr. Moe (Gast)


Lesenswert?

Ja hatte ich bereits ausprobiert. Hat nichts gebracht. Jetzt besorge ich 
mir nen logikanalysator und schau mir mal die signale an.

von Wolfgang (Gast)


Lesenswert?

Mr. Moe schrieb:
> Jetzt besorge ich mir nen logikanalysator und schau mir mal die signale an.

Auf einem DSO mit ein bißchen Speichertiefe und ordentlicher Triggerung 
sollte das auch alles zu sehen sein.

von Mr. Moe (Gast)


Lesenswert?

Ok danke für den tip ich muss einfach mal schauen was ich finde

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Da die Arduino Lib anscheinend keine Möglichkeit bietet, nach dem Senden 
der Startadresse das ACK Bit zu erfragen, ist es ziemlich sinnlos, da 
auch gleich noch Daten hinterher zu senden.

Die I2C Lib von Fleury hingegen erlaubt es, direkt das ACK abzufragen - 
damit findet man jegliche Devices recht zügig:
1
uint8_t theAck
2
3
void send_I2C(uint8_t Adresse) 
4
{
5
uint8_t ret;
6
  ret = i2c_start(Adresse+I2C_WRITE); // set device address and write mode
7
  if ( ret ) {
8
        /* failed to issue start condition, possibly no device found */
9
     i2c_stop();
10
     theAck = 0;
11
     }else {
12
 /* issuing start condition ok, device accessible */
13
      i2c_write(0x06);                // 
14
     i2c_write(0x00);                // 
15
     i2c_write(0x02);                // 
16
     i2c_write(0x00);                // 
17
   i2c_stop();                            // set stop conditon = release bus
18
       theAck = 1;
19
     }
20
}

: Bearbeitet durch User
von Arduinoquäler (Gast)


Lesenswert?

Matthias S. schrieb:
> Die I2C Lib von Fleury hingegen erlaubt es, direkt das ACK abzufragen

Dürfte für ihn schwierig werden, Matze.

mr.Moe schrieb:
> es handelt sich um ein ESP32

von Joachim B. (jar)


Lesenswert?

Arduinoquäler schrieb:
> Dürfte für ihn schwierig werden, Matze.
>
> mr.Moe schrieb:
>> es handelt sich um ein ESP32

aber die Quellen sind ja einsichtig, evtl. kann man die AVR Register zu 
ESP Register tauschen.
OK auf Registerebene habe ich noch nichts mit dem ESP32 gemacht, ist 
aber auch nur ein Prozzi, genauer gesagt derer 2 da gilt es dann 
rauszufinden welcher den I2C bearbeitet und wie man den verwenden kann.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Arduinoquäler schrieb:
> Dürfte für ihn schwierig werden, Matze.
>
> mr.Moe schrieb:
>> es handelt sich um ein ESP32

Ach ja richtig - mein Fehler.
Dann sollte man mal schauen, wie das beim ESP möglich ist, das ACK 
abzufragen.

von Arduinoquäler (Gast)


Lesenswert?

Joachim B. schrieb:
> evtl. kann man die AVR Register zu ESP Register tauschen.

Nö ... nicht so einfach.

Wenn der TO das könnte würde er nicht mit so einem trivialen
I2C Problem daherkommen und die Community hier auf Trab halten.

Bedenke dass es sich hier um eine Arduino Umgebung (Framework)
handelt mit der der TO arbeitet.

Alleine die Unterlassung mit einem Arduino Framework zu arbeiten
würde den TO glatt überfordern.

von Arduinoquäler (Gast)


Lesenswert?

Matthias S. schrieb:
> Dann sollte man mal schauen, wie das beim ESP möglich ist, das ACK
> abzufragen.

Gleiches leidiges Thema Arduino Framework.

Wenn es die Klasse (so wie sie ist) nicht hergibt muss man
die Klasse umschreiben bzw erweitern. Schon wieder ist einer
überfordert.

von Joachim B. (jar)


Lesenswert?

Arduinoquäler schrieb:
> Joachim B. schrieb:
>> evtl. kann man die AVR Register zu ESP Register tauschen.
>
> Nö ... nicht so einfach.

ich denke du hast Recht, bis vor Arduino habe ich im A-Studio auch nur 
mit dem AVR gearbeitet.

Ich weiss ja nicht mal ob der gcc den ESP Code kompiliert oder ob da was 
anderes eingebunden wird.

Auch kenne ich noch nicht mal die ESP Register, den Compiler, den 
Assembler.

Für jemanden der noch nie auf Registerebene am µC, egal welcher, wirds 
noch mal ne Ecke schwieriger, aber aus eigener Erfahrung nicht 
unmöglich.
Ob nun 6502, z80, 68k, LH5801, man kann sich einarbeiten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.