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?
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.
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.
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.
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?
Hast du zum Schreiben der Register mal die Deviceadresse 0x50 getestet?
Ja auch diese hab ich schon getestet, auch das hat nicht funktioniert.
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
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?
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); |
mr.Moe schrieb: > die Adresspins liegen A2= GND, A1= GND, A0= SCL und was soll dieser Unsinn? ich bin hier raus
:
Bearbeitet durch User
Joachim B. schrieb: > und was soll dieser Unsinn? Laut Datenblatt ist das eine gültige Adress-Konfiguration! RTFM!
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.
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.
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?
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 ...
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?
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).
hm ja dann werde ich das mal machen müssen. Und noch danke an alle die sich mit meinem Problem befasst haben.
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
Ja hatte ich bereits ausprobiert. Hat nichts gebracht. Jetzt besorge ich mir nen logikanalysator und schau mir mal die signale an.
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.
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
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
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.