Hallo zusammen,
ich habe ein unerklärliches Problem mit einer Ansteuerung eines
PCF8574/HD44780 Displays auf einem Atmega328PB (nicht 328P!).
Auf meinem Aufbau mit einem Atmega328PB auf einer Expander-Platine
bekomme ich die TWI-Kommunikation nicht zum Laufen.
Entsprechenden Empfehlungen nach habe ich mit verschiedenen Pull-Ups
experimentiert und 330R serielle Widerstände eingefügt, nichts hilft.
Um Probleme mit meinem Code (AVR command line gcc) auszuschließen, habe
ich die Arduino-IDE gestartet und das Beispiel aus
https://github.com/mathertel/LiquidCrystal_PCF8574 auf mein Board
geladen.
Ich habe das Beispiel mit vielen Serial.print() Statements erweitert, so
dass ich ungefähr sehe, wo die Sache schief läuft.
Der Output sieht dann so aus, alle Beispiele soweit, bis der µC hängt.
Das geschieht recht schnell. Ein bis 5 Reboots, dann hängt der
Controller.
Jedes "==Start LCD==" steht für einen Reboot. BOD ist disabled, die
Spannung ist auch komplett stabil, hängt an einem kleinen Labornetzteil.
Das Board hat alle Kondensatoren nach Datenblatt und
den Hardware Design Considerations for AVR Controller
(https://ww1.microchip.com/downloads/en/appnotes/atmel-2521-avr-hardware-design-considerations_applicationnote_avr042.pdf)
Im Oszi kann ich den Triggerlevel auf 4,9V setzen, und bekomme keine
fallende Flanke.
Das letzte Beispiel zeigt, dass durch den Absturz sogar die serielle
Taktreferenz gestört werden kann.
Nun habe ich die TWI Kommunikation protokolliert und zum Spass den Code
auf einen Pololu A-Star 328PB geflasht, da ich so die TWI1 Kommunikation
mit einem gleichen Controller nachvollziehen kann.
Überraschung: Obwohl ich zum ersten Versuch noch keine Pullups verwendet
habe, TWI nur mit den internen Port-Pullups läuft, rennt der Sketch auf
dem A-Star sauber ohne Probleme.
Das Oszibild vom AStar sieht erschreckend aus, klar: die Pullups fehlen.
Aber es tut.
Bei meinem Board fällt mir nur auf, dass ich auf dem SDA-Kanal einen
kurzen Spike sehe, der auf dem A-Star nur zu sehen ist, wenn man durch
meinen Spike darauf aufmerksam wurde.
Was kann ich noch untersuchen, welche Tips habt ihr, wie ich weiter
vorgehen kann?
Beide Oszilloskopbilder sehen OK aus. Das erste deutet auf grenzwertig
schwache Pullups hin, es geht aber noch.
Der Spike kommt in dem Moment, wo der Master die SDA Leitung los lässt
jnd der Slave sie herunter zieht um das ACK Signal zu erzeugen.
Dazwischen ist eine kurze Lücke, wo SDA "in der Luft hängt" und durch
den Pullup hoch gezogen wird. Je stärker der Pullup ist, umso
ausgeprägter der Spike. Er bei der nächsten steigen Flanke an SCL muss
das ACK Signal sauber anliegen. Dafür ist noch reichlich Zeit übrig.
Insofern: Deine Bilder sehen gut aus. Ich sehe darin keine Störung.
Was ich testen würde: Statte Master und Slave beide mit Pullups aus.
Wenn die Kommunikation hängt, trenne due Verbindung (SDA und SCL)
zwischen Master und Slave im laufenden Betrieb. Wahrscheinlich bleibt
eine der getrennten Leitungen auf LOW hängen. Auf diese Seite (Master
oder Slave) ist der Fehler zu suchen.
Zum Gegentest könntest du den I2C Scanner Sketch verwenden. Wenn der
sich nie aufhängt, liegt ein Softwarefehler im den anderen Sketch nahe.
Hans W. schrieb:> Beide Oszilloskopbilder sehen OK aus. Das erste deutet auf grenzwertig> schwache Pullups hin, es geht aber noch.
Das ist ja gerade das, was mich irritiert. Ein grenzwertiges Signal und
die Sache läuft problemlos über Stunden.
> Der Spike kommt in dem Moment, wo der Master die SDA Leitung los lässt> jnd der Slave sie herunter zieht um das ACK Signal zu erzeugen.> Dazwischen ist eine kurze Lücke, wo SDA "in der Luft hängt" und durch> den Pullup hoch gezogen wird. Je stärker der Pullup ist, umso> ausgeprägter der Spike. Er bei der nächsten steigen Flanke an SCL muss> das ACK Signal sauber anliegen. Dafür ist noch reichlich Zeit übrig.> Insofern: Deine Bilder sehen gut aus. Ich sehe darin keine Störung.
Ok, dann ist der Spike auch nicht das Problem, sondern die Folge der
stärkeren Pullups.
> Was ich testen würde: Statte Master und Slave beide mit Pullups aus.> Wenn die Kommunikation hängt, trenne due Verbindung (SDA und SCL)> zwischen Master und Slave im laufenden Betrieb. Wahrscheinlich bleibt> eine der getrennten Leitungen auf LOW hängen. Auf diese Seite (Master> oder Slave) ist der Fehler zu suchen.
Ok, das werde ich versuchen, dürfte ein wenig schwierig werden, dem
Portexpander auf dem Display die Widerstände zu spendieren.
> Zum Gegentest könntest du den I2C Scanner Sketch verwenden. Wenn der> sich nie aufhängt, liegt ein Softwarefehler im den anderen Sketch nahe.
Der wird sich auch aufhängen, siehe meine Crash-Logs. Da findet ja schon
nach dem Wire.begin() ein Reset statt. Der verwendet ja auch die
Wire-Bibliothek und startet mit "Wire.begin();", was ich zu
"Wire1.begin()" ändern müsste.
Und ein Softwarefehler, der auf einem Board mit grenzwertigen Pullups
nicht auftritt?
Ich verstehe momentan noch nicht, warum sich manchmal der µC ein paarmal
resetted, bevor er hängt, manchmal jedoch gleich hängt.
Paredros schrieb:> Was kann ich noch untersuchen
Das Taktsystem (Quarz und Bürde-Kondensatoren). Der Quarzoszillator ist
nämlich einer der wesentlichen Unterschiede zwischen 328P und 328PB. Der
vom PB ist wesentlich "zickiger".
Sehr wahrscheinlich schwingt der hier gerade noch so. Das ist ganz
schlecht, würde er gar nicht schwingen, würde das als Ursache ja sofort
auffallen. Das "gerade noch so" fällt hingegen erst mal kaum auf, macht
aber den ganzen µC instabil und kann für die seltsamsten Fehlerbilder
sorgen.
> welche Tips habt ihr, wie ich weiter> vorgehen kann?
Bürde-Kondensatoren tauschen. Erst eine E-Stufe kleiner, dann eine E
Stufe größer als das, was aktuell verbaut ist. In eine der beiden
Richtungen sollte sich eine dramatische Verbesserung ergeben, in der
anderen hingegen wird das Teil wahrscheinlich garnicht erst anschwingen.
Ob S. schrieb:> Bürde-Kondensatoren tauschen. Erst eine E-Stufe kleiner, dann eine E> Stufe größer als das, was aktuell verbaut ist. In eine der beiden> Richtungen sollte sich eine dramatische Verbesserung ergeben, in der> anderen hingegen wird das Teil wahrscheinlich garnicht erst anschwingen.
OK, das ist einen Versuch wert, könnte das Hängenbleiben und die
serielle Taktverwirrung erklären. SCL1 liegt ja gerade neben XTAL1, ich
habe die beiden XTAL-Anschlüsse zwar so gut separiert wie möglich, ich
kann aber die räumliche Nähe nicht ausschließen. Da ist natürlich meine
CPU auf dem Breakout Board empfindlicher, als der A-Star, da XTAL1 und
SCLA dort auch erstmal parallel verlaufen, bevor es an die Pins geht.
Aktuell habe ich 33pF nach den oben erwähnten "Hardware Design
Considerations for AVR Controller" verbaut, dort werden 22-33 angegeben.
Ich hätte 20pF als nächstkleinere da, oder soll ich auf 18 oder gar 15
gehen?
Das Atmega328PB Datasheet schreibt was von 12pF-22pF.
Hallo,
das wird anders berechnet. Die internen Pads haben beim 'P' und 'PB'
gleiche 18pF laut Manual. Nimm erstmal für deine Bürden 22pF. 33pF sind
jedenfalls zu viel. Ob das jedoch den Spike eliminiert, weiß nicht so
richtig. Oder ist das ein Messfehler mit dem Tastkopf? Massefeder
vorhanden? Nimm einmal diese. Deine I2C Leitung ist wie lang?
Wenn er gar nicht taktet kommt CFD Kapitel 12 ins Spiel. Der 'PB' ist in
sofern schon besser, weil die "verfused" Angst gibt es nicht.
Paredros schrieb:> Das Oszibild vom AStar sieht erschreckend aus ...
Wie kommst du zu diesem Urteil?
Du musst das aus der Sicht der I2C-Spezifikation betrachten. Die Signale
sind völlig in Ordnung. Nach Spezifikation müssen die Daten auf SDA
einen stabilen Logikpegel besitzen, während SCL high ist - und das tun
sie.
Björn W. schrieb:> Macht denn ein 328PB wenn der Takt instabil wird oder ausfällt ein> Reset?
Interessante Frage. Ich kann hier nur mal soweit gehen, dass BOD
ausgeschaltet ist und auch kein WDT aktive ist. Ich habe jetzt einmal
1
2
ISR(BADISR_vect) {
3
// Catch unexpected interrupts to prevent reset
4
}
in den Code eingefügt, in der Annahme, dass der Reset durch eine mir
unbekannte Interruptquelle erzeugt wird. Ich vermute, es ist die
Serial-Library.
Mit diesem Catchall gibt es keine Resets mehr,
Der Output von sieht nun so aus:
1
2
==Start LCD==
3
Probing for PCF8574 on address 0x27...
4
after Wire.begin() ...
5
after beginTransmission() ...
6
End Transmission, Error-code is: 0
7
LCD found.
8
==Start LCD==
9
Probing for PCF8574 on address 0x27...
10
after Wire.begin() ...
11
after beginTransmission() ...
12
End Transmission, Error-code is: 0
13
LCD found.
14
status==0
15
status==1
16
status==2
17
status==3
18
status==4
19
status==5
20
status==6
21
status==7
22
status==8
23
status==9
24
status==10
25
status==11
26
status==12
27
status==13
sieht mal ganz nett aus, ABER auf dem Display ist nichts zu sehen. Der
serielle Port mit dem USB-seriell-Adapter ist tot, das Betriebssystem
kann nicht mehr kommunizieren.
Es wurden zwar viele status-Zeilen ausgegeben, bis irgendwas die
serielle Kommunikation getötet hat. Das Programm läuft weiter,
erkennbar an ein paar Reaktionen auf dem Display. Manchmal sogar
lesbarer Text, dann wieder lange nicht oder Bytemüll.
Was aber die Quelle für den Interrupt ist?
Also ich werde nun mal die Kondensatoren tauschen.
Paredros schrieb:> Bei meinem Board fällt mir nur auf, dass ich auf dem SDA-Kanal einen> kurzen Spike sehe
Dann lass dir einmal vom Logikanalysator erklären, was da passiert. Der
Spike wird wohl an der Stelle sitzen, wo der Master sein letztes Bit, in
dem gezeigten Fall ein Low, gesendet hat und dann den Treiber
abschaltet. Das Bit danach kommt vom Slave und ist das ACK-Bit. Die
Umschaltung ist eben nur endlich schnell und je nach dem, wie aggressiv
du den losgelassenen Bus mit den Pull-Ups hochreißt, siehst du einen
kurzen Peak oder eben nicht.
Paredros schrieb:> ABER auf dem Display ist nichts zu sehen...> erkennbar an ein paar Reaktionen auf dem Display.
Was jetzt, erscheint etwas auf dem Display oder nicht?
Ich hoffe, dir ist bekannt, dass es zahlreiche Varianten dieser
Display+I²C Adapter gibt. Du musst die Pins zwischen dem Adapter und dem
Display passend konfigurieren, wenn sie nicht zufällig der
Standardvorgabe entspricht.
In der locker-flockig einfachen Arduino Welt verbirgt man die wahre
Komplexität gerne - gibt mehr Likes.
So Kondensatoren auf 20pF reduziert, das Ergebnis ist niederschmetternd.
Weit unstabiler, es gibt sogar Resets, trotz Resethandler.
Meist hängt er jetzt nach kürzester Zeit.
1
==Start LCD==
2
Probing for PCF8574 on address 0x27...
3
after Wire.begin() ...
4
after beginTransmission() ...
5
End Transmission, Error-code is: 0
6
LCD found.
7
==Start LCD==
8
Probing for PCF8574 on address 0x27...
9
Start LCD==
10
Pr obing for PCF8574 on address 0x
oder so
1
==Start LCD==
2
Probing for PCF8574 on address 0x27...
3
after Wire.begin() ...
4
after beginTransmission() ...
5
End Transmission, Error-code is: 0
6
LCD found.
7
==Start LCD==
8
Probing for PCF8574 on address 0x27...
9
after Wire.begin() ...
10
after beginTransmission() ...
11
End Transmission, Error-code is: 0
12
LCD found.
13
==Start LCD==
14
Probing for PCF8574 on address 0x27...
15
after Wire.begin() ...
16
after beginTransmission() ...
17
End Transmission, Error-code is: 0
Und dann passiert -entgegen den vorigen Versuchen- gar nichts mehr.
Keine irgendwie gearteten Reaktionen auf dem Display.
Hans W. schrieb:> Paredros schrieb:>> ABER auf dem Display ist nichts zu sehen...>> erkennbar an ein paar Reaktionen auf dem Display.>> Was jetzt, erscheint etwas auf dem Display oder nicht?
Habe ich doch geschrieben: Fragmente von Text, die
Hintergrundbeleuchtung geht mal an und aus, Bytemüll etc. Einfach
Lebenszeichen. Die ich mit den kleineren Kondensatoren nun nicht mehr
habe.
> Ich hoffe, dir ist bekannt, dass es zahlreiche Varianten dieser> Display+I²C Adapter gibt. Du musst die Pins zwischen dem Adapter und dem> Display passend konfigurieren, wenn sie nicht zufällig der> Standardvorgabe entspricht.>> In der locker-flockig einfachen Arduino Welt verbirgt man die wahre> Komplexität gerne - gibt mehr Likes.
Wie gesagt: Auf dem A-Star Board rennt der Test stundenlang! hab es auch
spaßeshalber auf einen Nano (dann mit TWI0) gepackt, auch kein Thema.
Das Display ist es definitiv nicht, die Codes stimmen!
Edit: mein eigener Code hat mit der Arduino-Welt wenig zu tun, ich
schätze die Sachen jedoch als Referenz, weil weit verbreitet und
getestet. Daher bin ich ja auch zum Verifizieren aud das
Arduino-Beispiel umgestiegen.
Hallo,
eine grundlegende Frage.
Mit wieviel MHz soll dein 328PB takten?
Die Oszi Einstellung ist 10µs/DIV?
Ich frage deshalb, weil dein eingestellter I2C Takt im Code sind 10kHz.
1
Wire1.setClock(10000);
Laut Oszi ist die Periodendauer 10µs, was 100kHz sind.
100µs wären 10kHz.
Ist irgendwas falsch eingestellt?
Paredros schrieb:> So Kondensatoren auf 20pF reduziert, das Ergebnis ist niederschmetternd.> Weit unstabiler, es gibt sogar Resets, trotz Resethandler.
20pF sind aber auch mehrere Stufen unter 33pF, nicht eine, wie
empfohlen. Das könnte schon fast wieder zu wenig sein.
Allerdings zeigt die deutliche Änderung im Verhalten (jedenfalls unter
der Voraussetzung, dass du sonst nichts geändert hast) zumindest dies:
hier ist wirklich die Ursache der Probleme zu suchen.
Man könnte auch mal den Quarz umgehen, indem man einen externen
Taktgeber anschließt oder den internen R/C Oszillator verwendet. Dann
ist allerdings nicht mehr sicher, dass die serielle Baudrate gut genug
eingehalten wird. Ich denke, mit 2400 Baud stehen die Chancen besser als
mit den meisten höheren.
Ob S. schrieb:> 20pF sind aber auch mehrere Stufen unter 33pF, nicht eine, wie> empfohlen. Das könnte schon fast wieder zu wenig sein.>> Allerdings zeigt die deutliche Änderung im Verhalten (jedenfalls unter> der Voraussetzung, dass du sonst nichts geändert hast) zumindest dies:> hier ist wirklich die Ursache der Probleme zu suchen.
Da dachten wir das Gleiche! Ich nun auf 30pF gegangen und habe nach der
Erfahrung mit dem AStar die Pullups und die seriellen Widerstände
entfernt, und was soll ich sagen:
Die Sache läuft!
Sauber, wie auf dem AStar, auch wenn das Oszi nun die schwachen internen
Pullups zeigt.
OK, vielen Dank allen, die mich auf diese Sache hingewiesen haben.
Wenn due Pullup Widerstände ein Problem auslösen, hast du wahrscheinlich
eine mangelhafte Stromversorgung. Die kann auch den Oszillator zur
Mimose machen.
Veit D. schrieb:> Hallo,>> eine grundlegende Frage.> Mit wieviel MHz soll dein 328PB takten?> Die Oszi Einstellung ist 10µs/DIV?> Ich frage deshalb, weil dein eingestellter I2C Takt im Code sind 10kHz.>
1
Wire1.setClock(10000);
> Laut Oszi ist die Periodendauer 10µs, was 100kHz sind.> 100µs wären 10kHz.> Ist irgendwas falsch eingestellt?
Oops, das ist wohl ein Typo, den die Bibliothek aber wegsteckt (oder gar
ignoriert), denn wie das Oszi zeigt, taktet SCL mit 100kHz!
Wegen der Oszibilder habe ich da gar nicht im Code nachgesehen. Hab es
jetzt mit dem funktionierenden Setup auch mal auf 100000 gesetzt, kein
Unterschied im Oszi! ;-)
Mein eigener Code läuft nun auch!
Paredros schrieb:> Ich nun auf 30pF gegangen und habe nach der> Erfahrung mit dem AStar die Pullups und die seriellen Widerstände> entfernt, und was soll ich sagen:> Die Sache läuft!
Da er bei 33pF und 20pF nachweislich jeweils noch halbwegs schwingt, bei
33pF aber scheinbar etwas besser als bei 20pF, wäre wohl 27pF letztlich
der optimale Wert.
Ob S. schrieb:> Da er bei 33pF und 20pF nachweislich jeweils noch halbwegs schwingt, bei> 33pF aber scheinbar etwas besser als bei 20pF, wäre wohl 27pF letztlich> der optimale Wert.
Wenn der so sensibel auf die Bürde reagiert, dann stimmt das was nicht,
z.B. fehlende Entkopplungskondensatoren.
H. H. schrieb:> Wenn der so sensibel auf die Bürde reagiert, dann stimmt das was nicht,> z.B. fehlende Entkopplungskondensatoren.
Unzulänglichkeiten in der Versorgung erleichtern dem Oszillator
natürlich nicht seine Arbeit, sind also ebenfalls eine Überprüfung wert.
Allerdings: wenn die Bürden optimal gewählt sind, ist auch die Resistenz
gegen solche Unzulänglichkeiten optimal. Kann also definitiv nicht
falsch sein, hier die richtigen Werte zu wählen, insbesondere dann
nicht, wenn man den "Geht-Bereich" sowieso schonmal ausgeklingelt hat.
Außerdem: der 328PB-Oszillator ist auf LowPower optimiert und deswegen
tatsächlich vergleichsweise anspruchsvoll bezüglich der Anpassung der
Bürden. Das ist was ganz anderes als der "FullSwing"-Oszillator des
328P.
Ob S. schrieb:> Außerdem: der 328PB-Oszillator ist auf LowPower optimiert
Und erfordert deshalb die dazu passenden Quarze.
Die Bürde sollte eigentlich so ausgewählt werden, dass der Quarz
möglichst genau auf seiner Nennfrequenz schwingt.
> Auf meinem Aufbau mit einem Atmega328PB auf einer _Expander-> Platine_ bekomme ich die TWI-Kommunikation nicht zum Laufen.
Wie oft muss man dich noch um gute Fotos bitten?
330 Ohm seriell ist schon zu viel des Guten, ich empfehle 27-47 Ohm.
Hans W. schrieb:> Wenn due Pullup Widerstände ein Problem auslösen, hast du wahrscheinlich> eine mangelhafte Stromversorgung. Die kann auch den Oszillator zur> Mimose machen.
Ich kann es jetzt nicht sagen, ob die Kondensatoren alleine das Problem
gelöst haben oder nicht. Da ich aber ohnehin an der Stelle am Entlöten
war, hab ich gleich zwei Dinge auf einmal erledigt.
Die Stromversorgung kann es eigentlich nicht sein: Das Oszi zeigt
keinerlei Auffälligkeiten, ungefähr 20-30mV Ripple, der sich reduziert,
wenn ich den seriell-Adapter entferne. Überall an Vcc und AVcc sind
Stützkondensatoren, Das Netzteil ist stabil und könnte >8A, ist aber auf
120mA max gesetzt, aktuell zieht der µC mit Display und
Hintergrundbeleuchtung 36mA. Ohne Beleuchtung sind es 16mA.
Das Display hat da, wo es angeschlossen ist einen 22µF Elko und einen
100nF zum Sieben.
Während ich das schrieb, passierte, was nicht passieren soll. Ich schob
den laufenden Controller ein wenig weiter weg von mir, und die Probleme
waren zurück.
Jetzt hatte ich einen anderen Verdacht. Aus einem anderen Projekt einen
ebenfalls per Breakout-Bord gesockelten µC entnommen und diesen
programmiert. Heftig hin- und hergeschoben, berührt (der Atmega soll
verschiedenen Foreneinträgen ziemlich touchy sein), alles kein Problem.
Nun musste das Makroobjektiv ran. Ein Bild sagt mehr als viele Worte:
Das Reinigen mit Isopropanol un einem feinen Pinsel war wohl das
Problem. Nochmals mit kräftig Iso abgewaschen, mit eine feinen
Skalpellklinge die Stellen gereinigt (die ich mit Lupe und Lesebrille
gar nicht sehen kann) und wieder eingesetzt und programmiert.
Lasse das Teil nun über Nacht laufen, ich fürchte, ich habe zwei Tage an
den komplett falschen Stellen gesucht.
H. H. schrieb:> Die Bürde sollte eigentlich so ausgewählt werden, dass der Quarz> möglichst genau auf seiner Nennfrequenz schwingt.
Natürlich.
Wobei hier aber ein anderer Aspekt derselben Sache entscheidend ist. Nur
bei der Nennfrequenz erreicht man die maximale Amplitude, die mit der
durch den Oszillator gegebenen Energiezufuhr möglich ist. Und diese
Amplitude muss halt für einen sicheren Betrieb der Triggerstufe
ausreichen.
Kann man mit einem "FullSwing"-Oszillator mehr Energie in die Schwingung
pumpen, ist auch der Bereich deutlich breiter, in dem sich eine
Schwingung mit hinreichender Amplitude ergibt (wenn auch mit leicht
abweichender Frequenz).
Die leicht abweichende Frequenz macht den µC nicht instabil. Eine
unzureichende Amplitude hingegen schon.
> berührt (der Atmega soll verschiedenen Foreneinträgen ziemlich> touchy sein)
Was ist mit evtl. unbenutzten Pins, sind die auf Input mit Pullup oder
Output geschaltet? Ein unbeschalteter Input ohne Pullup darf nicht sein!
Ich fragte nach Foto_s_ (Plural = Mehrzahl) vom gesamten Aufbau.
Solange keine kommen, gibt es keine Antworten mehr!