Hallo, folgendes Szenario: Ich verwende einen Arduino Nano und daran ist via I2C der Port Expander MAX7313 angeschlossen. Als PullUp Widerstände verwende ich je einen 4,7k Widerstand am I2C. Außerdem ist an dem I2C ein Display angeschlossen, welches auch einwandfrei funktioniert. Wenn ich einen x-beliebigen I2C Scanner verwende um die Adressen auszulesen, dann spuckt er mir für das Display 0x3C und für den Port Expander 0x20 aus. Das passt auch zu der Konfiguration der ADDR Pins (vom Port Expander), die ich allesamt auf GND gezogen habe. So weit so gut. Jetzt folgendes Problem: Ich möchte die Pins vom Port Expander als Outputs nutzen und mittels MOSFET ein Relais schalten. Hier der Code mit dem ich das mal getestet habe: ********************************************************************* #include <Wire.h> #define expander 0x20 //I2C Adresse void setup() { Serial.begin(9600); Wire.begin(expander); } void loop() { Serial.println("Pins HIGH schalten"); Wire.beginTransmission(expander); Wire.write(0x01); // Register als Output einstellen Wire.write(0xFF); // Alle Pins HIGH, B11111111 Wire.endTransmission(true); delay(3000); Serial.println("Pins LOW schalten"); Wire.beginTransmission(expander); Wire.write(0x01); // Register als Output einstellen Wire.write(0x00); // Alle Pins LOW, B00000000 Wire.endTransmission(true); delay(3000); } ********************************************************************* Ich habe auch schon unzählige Varianten neben dem Code getestet aber ich bekomme die Pins nicht beschaltet. Weder HIGH noch LOW. Hat hier jemand vielleicht Erfahrungen mit dem Port Expander und kann mir bezüglich der genannten Problematik helfen? Danke!
Zur Ergänzung lasse ich gerade mal auf eine andere Art und Weise mögliche Kombinationen durchlaufen.. siehe Anhang
Versuchs mal mit ersetze Wire.begin(expander); mit Wire.begin(); Dein Arduino soll der i2c master sein, nicht ein Slave.
Sascha R. schrieb: > Wire.begin(); ja besser ich vermisse deinen Zugriff auf die Configurations Register https://datasheets.maximintegrated.com/en/ds/MAX7313.pdf Table 5. Ports Configuration Registers -> Address code 0x06 du musst ja erst mal das device ansprechen dann das Register und dannn gehts erst weiter Ablauf: Wire.begin(); // generell nur im setup Wire.beginTransmission(DEIN_EXPANDER); printIIC(0x06); // z.B. Wire.endTransmission(); Wire.requestFrom( ( DEIN_EXPANDER ), 1); // um ein Byte zu lesen Wire.endTransmission(); nun weisst du wie deine Ports stehen, um sie zu ändern musst du schreiben mit etwas Übung klappt das schon das Beispiel für Register in der RTC und dann noch, kann gekürzt werden
1 | #if defined(ARDUINO)
|
2 | #if ARDUINO >= 100
|
3 | //check busy
|
4 | Wire.beginTransmission(DS1307_ID); |
5 | printIIC(STATUS_REGISTER); |
6 | Wire.endTransmission(); |
7 | Wire.requestFrom( ( DS1307_ID ), 1); // request Status Register 1 Byte |
8 | if ((readIIC() & 0x00ff) & (1<<BSY)) // auf busy pruefen mit 0x00ff unddieren weil Arduino 16 Bit liest aber nur 8 Bit kommen. |
9 | i2c_test_flags|=(1<<I2C_RTC_TEMP_BSY); // Flag busy setzen |
10 | else
|
11 | i2c_test_flags&=~(1<<I2C_RTC_TEMP_BSY); // Flag busy loeschen |
12 | Wire.endTransmission(); |
13 | if( !(i2c_test_flags&(1<<I2C_RTC_TEMP_BSY)) ) |
14 | { // read Temp |
15 | Wire.beginTransmission(DS1307_ID); // DS anwaehlen |
16 | printIIC(MSB_TEMP); // MSB Byte anwaehlen |
17 | Wire.endTransmission(); |
18 | Wire.requestFrom( ( DS1307_ID ), 2); // request temp Hi und Temp low 2 Byte |
19 | __temp = (readIIC() & 0x00ff); // mit 0x00ff unddieren weil Arduino 16 Bit liest aber nur 8 Bit kommen. |
20 | __temp <<= 8; |
21 | __temp |= (readIIC() & 0x00ff); // mit 0x00ff unddieren weil Arduino 16 Bit liest aber nur 8 Bit kommen. |
22 | Wire.endTransmission(); |
23 | #else
|
24 | #include "Arduino_<_100_undefiniert.h" //#warning gibt es ja in der Arduino Ide nicht |
25 | #endif // #if ARDUINO < 100
|
nur dummerweise habe ich noch nie unter Arduino Config Register beschrieben nur in C
1 | void alarm1_clr_rtc(void) |
2 | { unsigned char control, status; |
3 | if(_test_i2c_rtc) |
4 | { i2c_start_wait(DS3231+I2C_WRITE); // set device address and write mode |
5 | i2c_write(DS3231_ControlReg); // write address = DS3231_ControlReg |
6 | i2c_rep_start(DS3231+I2C_READ); // set device address and read mode |
7 | control = (i2c_readAck()&( 1<<A2IE )) | ( 1<<INTCN ); // nur A1IE löschen |
8 | status = i2c_readNak() & ~(1<<A1F); // nur A1F löschen |
9 | i2c_stop(); |
10 | |
11 | i2c_start_wait(DS3231+I2C_WRITE); // set device address and write mode |
12 | i2c_write(DS3231_ControlReg); // write address = DS3231_ControlReg |
13 | i2c_write( control ); |
14 | i2c_write( status ); |
15 | i2c_stop(); |
16 | }
|
17 | }
|
18 | |
19 | void alarm1_set_abs_rtc(UBYTE sekunde, UBYTE minute, UBYTE stunde, UBYTE tag) |
20 | { i2c_start_wait(DS3231+I2C_WRITE); // set device address and write mode |
21 | i2c_write(7); // 7 Control Sekunde zählt automatisch hoch mit jedem schreib |
22 | i2c_write(int2bcd(sekunde&0x7f)); // | A1M1 |
23 | i2c_write(int2bcd(minute&0x7f)); // | A1M2 |
24 | i2c_write(int2bcd(stunde&0x3f)); // | A1M3 |
25 | i2c_write(int2bcd(tag&0x3f)); // | A1M4 |
26 | i2c_stop(); |
27 | |
28 | i2c_start_wait(DS3231+I2C_WRITE); // set device address and write mode |
29 | i2c_write(DS3231_ControlReg); // write address = DS3231_ControlReg |
30 | i2c_write( (1<<A1IE)|(1<<INTCN) ); |
31 | i2c_stop(); |
32 | }
|
:
Bearbeitet durch User
Habe nochmal weiter rum getüftelt, es läuft aber nach wie vor nicht. Habe verschiedene Configs ausprobiert, hier ein Auszug.. #include <Wire.h> #define PE_ADD 0x20 // I2C-Addresse 0b0100000 #define printIIC(args) Wire.write((uint8_t)args) #define readIIC() Wire.read() void setup() { Serial.begin(9600); //Serielle Schnittstelle initialisieren Wire.begin(); //I2C Initialisierung delay(200); } void loop() { Serial.println("Pins HIGH schalten"); Wire.beginTransmission(PE_ADD); Wire.write(0x06); Wire.write(0x00); // Output Configuration Wire.endTransmission(true); Wire.beginTransmission(PE_ADD); Wire.write(0x02); Wire.write(0xFF); Wire.endTransmission(true); delay(3000); Serial.println("Pins LOW schalten"); Wire.beginTransmission(PE_ADD); Wire.write(0x02); Wire.write(0x00); Wire.endTransmission(true); delay(3000); Wire.beginTransmission(PE_ADD); Wire.write(0x02); Wire.write(0xFF); Wire.endTransmission(true); delay(3000); }
niwi04 schrieb: > Habe nochmal weiter rum getüftelt, es läuft aber nach wie vor nicht. wundert mich nicht, du hinkst im verstehen noch zurück > #define PE_ADD 0x20 // I2C-Addresse 0b0100000 > #define printIIC(args) Wire.write((uint8_t)args) > #define readIIC() Wire.read() > Serial.println("Pins HIGH schalten"); > Wire.beginTransmission(PE_ADD); > Wire.write(0x06); Basisadresse ist PE_ADD 0x20, du willst ein Register BESCHREIBEN! also +1 das LSB zur Basis Lesen/Schreiben ist für Schreiben +1 auch ist die Frage wie tickt das Teil? manche IC verwenden die 8 Bit Notation in DB dann müsste deine 0x20 Basis zur 0x40 werden +1 fürs Schreiben also 0x41 in Arduino wird aber in 7 Bit Notation gearbeitet also, dann müsste deine 0x20 Basis +1 fürs Schreiben also 0x21 werden kläre erst mal mit einem Scanner ab wann sich dein Teil meldet
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.