Forum: Mikrocontroller und Digitale Elektronik ATtiny85 und MCP23017 liefert NACK


von Philipp M. (mani_phi)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

dies ist mein erster Forenbeitrag hier, also bitte zerfleischt mich 
nicht gleich. Leider habe ich über die Suchfunktion keinen passenden 
Thread gefunden, daher erstelle ich einen Neuen.

Zur Zeit versuche ich den ATtiny85 auf einem Adafruit Trinket 3.3V mit 
einem MCP23017 zum Laufen zu kriegen. Was später daraus wird ist nicht 
wichtig, da es bereits an den Anfängen scheitert.

Zur Schaltung: Einen Plan habe ich nicht extra angehängt, da die 
Schaltung recht minimalistisch ist. Vom ATtiny-PB0 geht das SDA Signal 
mit 1k Pull Up zu MCP23017-Pin13. Das SCK Signal geht von ATtiny-PB2 mit 
1k Pull Up zu MCP23017-Pin12. Das \Reset an MCP23017-Pin18 ist mit 1k 
auf Vdd gesetzt. Ich habe bereits verschiedene Widerstandswerte ohne 
Erfolg probiert. Die DC-Spannungen habe ich bereits mit einem Multimeter 
validiert.

Entschieden habe ich mich für die SoftI2CMaster.h als Library. Diese 
soll ja flüssig laufen und ist schön klein. Der Code, den ich benutze 
ist minimalistisch. Den I2C-Bus definieren, initieren und mit zwei Bytes 
testen.

Nun zu meinem Problem. Ich bekomme vom MCP23017 immer ein NACK zurück, 
bzw. der MCP23017 reagiert nicht. Hier bin ich mir unsicher.

Im Anhang findet ihr einen Screenshot von dem mit Scope gemessenem I2C 
Bus. Daraus leite ich auch meine Schlussfolgerungen und 
Problemstellungen ab. Man sieht sehr schön wie der ATtiny85 den Bus 
bedient. Dann bleibt der Bus beim letzten Bit HIGH. Es gibt ein NACK. 
Auch sehe ich (ihr leider nicht) meine Debug-Schleife auslösen und die 
LED blinkt! Es ist also ein NACK erfolgt.

Könnt ihr mir sagen, was ich in meinem Beispiel falsch mache und wie ich 
den MCP23017 zum Laufen bekomme? Gibt es eine andere Möglichkeit, außer 
anderes IC, zu testen, ob mein IC vielleicht kaputt ist?

Hier im folgenden der von mir verwendete Code:
1
// DEFINE
2
// define I2C pins/ports
3
#define SCL_PIN 2
4
#define SCL_PORT PORTB
5
#define SDA_PIN 0
6
#define SDA_PORT PORTB
7
// define I2C bus options
8
#define I2C_TIMEOUT 1000                  // after 1s, if slave is not answering, I2C functions will time out
9
#define I2C_FASTMODE 1                    // I2C bus frequency is now 400kHz
10
11
//INCLUDE
12
//include libraries
13
#include <SoftI2CMaster.h>
14
15
//VARIABLES
16
int led = 1;                              // debug onboard led
17
bool check_bit = true;                    // bit to check I2C bus
18
19
//CODE
20
void setup() {
21
  // initialize #ledpin as output
22
  pinMode(led, OUTPUT);                   // use led for debugging
23
  // initialize I2C bus
24
  i2c_init();                             // + check for bus lockup
25
  // start I2C communication
26
  check_bit = i2c_start(0b01000001);      // start bus: OP-Code(0100) + ADDR(000) + Read-Bit(1)
27
  if(check_bit == false){
28
    for(int i=0;i<=20;i++){
29
        digitalWrite(led, HIGH);          // debug blink if NACK
30
        delay(50);
31
        digitalWrite(led, LOW);
32
        delay(50);
33
    }
34
  }
35
  i2c_write(0b10110010);                  // send 8bit example word (does not make sense!!!)
36
  i2c_stop();                             // send stop condition
37
}
38
39
void loop() {
40
  digitalWrite(led, HIGH);                // just blink when setup is over
41
  delay(500);
42
  digitalWrite(led, LOW);
43
  delay(500);
44
}

Solltet ihr mehr Infos brauchen, fragt bitte einfach.

Vielen Dank für eure Hilfe und Grüße!

von S. R. (svenska)


Lesenswert?

Philipp M. schrieb:
> Nun zu meinem Problem. Ich bekomme vom MCP23017
> immer ein NACK zurück, bzw. der MCP23017 reagiert
> nicht. Hier bin ich mir unsicher.

Prüfe die Klassiker:
- ist der MCP korrekt angeschlossen?
--- Hat er Spannung, Masse und seinen Kondensator?
- hast du SCL und SDA nicht vertauscht?
--- Miss nochmal nach. :-)
- ist der Chip funktionsfähig?

Und dann gibt's noch Software:
- stimmt die I2C-Adresse?
--- Welche Spannung liegt an A0, A1, A2 an?

Die Adresse scheint aber zu stimmen, wobei ich einfach 0x40/0x41 
geschrieben hätte. Oder, wenn man auf die 7 Bit-Adressierung steht, 
i2c_setup((0x20 << 1) | I2C_READ);

von Philipp M. (mani_phi)


Lesenswert?

Hey Svenska, vielen Dank für deine schnelle Antwort.

S. R. schrieb:
>
> Prüfe die Klassiker:
> - ist der MCP korrekt angeschlossen?

Die Pinbelegung habe ich mehrfach kontrolliert.

> --- Hat er Spannung, Masse und seinen Kondensator?

Was für einen Kondensator? Einen Puffer-Cap am VDD?
Den habe ich weg gelassen, da ich direkt über den gepufferten USB vom 
Trinket speise.

> - hast du SCL und SDA nicht vertauscht?
> --- Miss nochmal nach. :-)

Bestimmt schon 8x gemacht :D

> - ist der Chip funktionsfähig?

Kennst du eine einfache Methode das zu kontrollieren, außer einen Ersatz 
zu nehmen?

> Und dann gibt's noch Software:
> - stimmt die I2C-Adresse?
> --- Welche Spannung liegt an A0, A1, A2 an?
>
> Die Adresse scheint aber zu stimmen, wobei ich einfach 0x40/0x41
> geschrieben hätte. Oder, wenn man auf die 7 Bit-Adressierung steht,
> i2c_setup((0x20 << 1) | I2C_READ);

Die liegen alle hart an Ground. Damit ich da keine Fehler mache, habe 
ich auch extra die 0b... Darstellung gewählt, ist infacher zu denken.

In den kommenden Tagen werde ich noch einmal die Schaltung neu aufbauen 
und wahrscheinlich das IC tauschen...

von Vermutung (Gast)


Lesenswert?

Ich würde auf ein I2C Timingproblem tippen.
Während der steigenden SDA Flanken kommt schon nahezu zeitgleich die SCL 
Flanke.

von S. R. (svenska)


Lesenswert?

Philipp M. schrieb:
> Was für einen Kondensator? Einen Puffer-Cap am VDD?

Ja, jeder CMOS-Chip möchte seinen eigenen Kondensator (um die 100nF) 
zwischen Vcc und GND. Die USB-Spannung mag zwar gepuffert sein, sie ist 
aber zu weit weg.

Zum Timing kann ich nichts sagen außer:
Versuch's einfach mal deutlich langsamer.

von Philipp M. (mani_phi)


Lesenswert?

Vermutung (Gast) schrieb:
>Ich würde auf ein I2C Timingproblem tippen.
>Während der steigenden SDA Flanken kommt schon nahezu zeitgleich die SCL
>Flanke.

S. R. schrieb:
>Zum Timing kann ich nichts sagen außer:
>Versuch's einfach mal deutlich langsamer.

Gehe ich dann richtig in der Annahme, dass ich in der Library Code 
umschreiben muss?
Deutlich langsamer mmmhhh... Der MCP23017 ist eigentlich bis zu 1.7MHz 
ausgelegt.

Vielleicht liegt es ja auch am Cap, da das IC die steilen Flanken nicht 
schafft, weil USB nicht genug Spitzenstrom liefern kann.

Mal schauen, wann ich dazu komme. Ich danke euch auf jeden Fall schon 
für eure Hilfe. Das sind gute Tipps.

von Frank L. (Firma: Flk Consulting UG) (flk)


Angehängte Dateien:

Lesenswert?

Hallo,
so einfach lässt sich mit dem Teil nicht arbeiten. Bevor Du etwas lesen 
oder schreiben kannst muss das Teil erst initialisiert werden.

Ich habe Dir mal ein paar Codeschnipsel von mir angehangen. Ich arbeite 
zwar nur mit dem Outputkanälen aber der Rest sollte dann auch klar 
werden.

Gruß
Frank

: Bearbeitet durch User
von Philipp M. (mani_phi)


Lesenswert?

Moin Frank, erstmal danke für deine Antwort. Leider verstehhe ich nicht 
ganz, wie sie mir helfen soll.

Frank L. schrieb:
> Hallo,
> so einfach lässt sich mit dem Teil nicht arbeiten. Bevor Du etwas lesen
> oder schreiben kannst muss das Teil erst initialisiert werden.

Genau das versuche ich ja. Ich schicke den OP-Code + Addresse + R/W-Bit. 
Das ist im Prinzip diese Stelle aus deinem Code:

void Channel_init(void)
{
  if (!Channel_device_exist) return;
  // Port A as output
  i2c_start(MCP23017_ADR + I2C_WRITE);
        ...
Allerdings folgt darauf bereits ein NACK. Das IC antwortet also nicht 
auf seine Initialisierung.

> Ich habe Dir mal ein paar Codeschnipsel von mir angehangen. Ich arbeite
> zwar nur mit dem Outputkanälen aber der Rest sollte dann auch klar
> werden.

Wo kommt Channel_device_exist her?

von Frank L. (Firma: Flk Consulting UG) (flk)


Lesenswert?

Hallo Phillip,

sorry, dann hatte ich den Text missverstanden.

Zu Deine Frage, das Channel_device_exist kommt aus einem anderen 
Bereich, bei dem ich zuerst prüfe, welche I2C Devices vorhanden sind. 
Kannst Du also ignorieren.

Ansonsten, bin ich auch ratlos. Bei mir läuft das Teil super stabil und 
ohne Probleme. Allerdings benutze ich kein SoftI2C und einen Mega328

Bei mir sind auch SCA und SCL ohne Pullup mit dem MC verbunden. Den Sinn 
bei Dir dahinter habe ich nicht verstanden.

Ansonsten, würde ich es mal mit diesen zusätzlichen Einstellungen 
versuchen.

#define I2C_TIMEOUT 0
#define I2C_NOINTERRUPT 0
#define I2C_FASTMODE 0
#define FAC 1
#define I2C_CPUFREQ (F_CPU/FAC)

Wobei ich nicht weiß, mit welcher IDE Du arbeitest. Vielleicht ist auch 
nur F_CPU bei Dir in der IDE nicht definiert.

Gruß
Frank

von Philipp M. (mani_phi)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

in den letzten Tagen habe ich die Schaltung erneut zusammen gebaut, neu 
gecoded und eure Ratschläge ausprobiert. Vielen, vielen Dank noch 
einmal.

S. R. schrieb:
> Ja, jeder CMOS-Chip möchte seinen eigenen Kondensator (um die 100nF)
> zwischen Vcc und GND. Die USB-Spannung mag zwar gepuffert sein, sie ist
> aber zu weit weg.

Dieser Hinweis hat es vermutlich gebracht. 10µF an Vdd. Nun funktioniert 
der Bus. Siehe Anhang.


Frank L. schrieb:
> Ansonsten, bin ich auch ratlos. Bei mir läuft das Teil super stabil und
> ohne Probleme. Allerdings benutze ich kein SoftI2C und einen Mega328

Der Mega328 hat soweit ich das verstanden habe ein eingebautes 
I2C-Modul. Da ist die Ansteuerung einfacher.

> Bei mir sind auch SCA und SCL ohne Pullup mit dem MC verbunden. Den Sinn
> bei Dir dahinter habe ich nicht verstanden.

Dann benutzt der Mega328 interne Pull-Ups. Ohne funktioniert der Bus 
nicht. Siehe bspw. Wikipedia. Habe ich auch bereits in der Praxis 
nachgestellt.

> Ansonsten, würde ich es mal mit diesen zusätzlichen Einstellungen
> versuchen.
>
> #define I2C_TIMEOUT 0
> #define I2C_NOINTERRUPT 0
> #define I2C_FASTMODE 0
> #define FAC 1
> #define I2C_CPUFREQ (F_CPU/FAC)

Diese Einstellungen haben das Problem nicht verbessert. Vielleicht 
benutze ich sie auch falsch.

> Wobei ich nicht weiß, mit welcher IDE Du arbeitest. Vielleicht ist auch
> nur F_CPU bei Dir in der IDE nicht definiert.

Zur Zeit verwende ich die Arduino IDE und dort wird (vermutlich) über 
den ausgewählten Programer die CPU Frequenz gesetzt.

Jetzt kann ich erst einmal weitermachen.
Danke und bis später vielleicht mal.

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.