Hallo!
Ich verwende ein 4x20 Zeichen LCD mit HD44780-Controllerchip und
4Bit-Datenübertragung. Angesteuert wird es über einen ATMega8.
Prinzipiell funktioniert die komplette Schaltung und die Ansteuerung des
Displays auch einwandfrei, alles wird zu Beginn richtig angezeigt (Text,
Variablen, usw.).
Nach einiger Zeit werden aber am Display immer wieder mal komische
Zeichen anstatt dem richtigen Text angezeigt und manchmal "stürzt" es
dann auch ab (Es werden nur mehr volle Kästchen in der 1. und 3. Zeile
angezeigt, wie wenn es noch nicht initialisiert ist).
Das Datenkabel zwischen ATMega8 und LCD ist ein normales Flachbandkabel.
Ist es vielleicht hier auch empfehlenswert ein geschirmtes Rundkabel zu
verwenden oder ist das mehr vernachlässigbar?
Im Anhang habe ich die essentiellen Programmteile der Ansteuerung des
Displays hinzugefügt, oben die Include-Datei für das LCD und danach die
einzelnen Unterprogramme in der main.c.
Ich hoffe Ihr könnt mir dabei helfen, was der Grund dafür sein kann.
Mfg Koksi
Koksi schrieb:> Das Datenkabel zwischen ATMega8 und LCD ist ein normales Flachbandkabel.
Wie lang?
> Ist es vielleicht hier auch empfehlenswert ein geschirmtes Rundkabel zu> verwenden oder ist das mehr vernachlässigbar?
Meine Kabel sind so um die 20cm lang. Das von dir geschilderte Verhalten
hab ich noch nie gesehen.
Nur zur Info damit keine Verwirrung entsteht, ich hab mich jetzt im
Mikrocontroller-Forum angemeldet ;-)
Interessant wäre für mich, ob die Ansteuerung des LCD's prinzipiell in
Ordnung ist, oder ob irgendwo so etwas wie zeitliche Flaschenhälse
entstehen können, die dann die Kommunikation mit dem LCD
beeinträchtigen?
so ausm Bauch raus würde ich sagen man muss dazwischen den anable
toggeln oder?
30cm Kabellänge sollten noch ok sein.
Stürzt nur das LCD ab, oder auch der µC?
Ich hatte mal versehendlich den ADC-Prescaler auf 1 bei 3,6864MHz und
der µC ist sporadisch nach n paar Stunden betrieb eingefrohren.
Gruß Knut
Hab die Initialisierungsroutine von einem Beispielprogramm übernommen
und wenn ich das richtig verstanden habe, geht es bei den 3 Befehlen
hintereinander einfach nur darum, eine Art Verzögerung für das Display
einzubauen, da es bei der 4Bit-Initialisierung länger braucht um die
Befehle abzuarbeiten (wenn man das Busy-Flag nicht abfragt).
Es stürzt nur das LCD ab, der µC läuft weiter und hat nichts.
Das LCD verhält sich einmal früher, einmal wieder später, wie wenn es
irgendwie resettet wird oder Ähnliches, da es danach am Display genauso
aussieht, wie beim Einschalten der Spannung...
mfg Koksi
Zeig doch mal den Rest des Programms.
Vielleicht ist es gar nicht das LCD, sondern du hast einen
Programmfehler und in Wirklichkeit resettet der AVR.
Das könntest du testen, wenn du noch irgendwo eine LED anschliessen
kannst.
Die LED schaltest du gleich am Anfang in main() ein und nach der
kompletten Initialisierung vor dem sei wieder aus.
Und dann beobachtest du, ob die LED während des Programmlaufs kommt.
Edit: Ne, Quatsch. Du hast ja die Intialisierungsbalken am LCD. Das LCD
wird definitiv resettet. Nur: Softwaremässig schaffst du das so nicht.
Irgendwas in der Versorgungsspannung? Eventuell mal am LCD einen 10µF
Elko an die Versorungsspannung hängen?
Wackelkontakt irgendwo?
Schlechte Lötstelle?
Wenn die Hardware stimmt und das Display erst nach einiger Zeit falsche
Zeichen ausgibt, würde ich mal davon ausgehen, das du es irgendwo
geschafft hast ne "Variable" überlaufen zu lassen.
Oder du eine Schleife nicht richtig beendest und oder dabei eine
Variable nicht richtig zurückgesetzt wird.
Letztendlich sind das natürlich keine Variablen sondern irgendwelche
Register-Overflows, wo dann müll bei raus kommt.
Hab mal jetzt das gesamte Programm angehängt. Die Programmlogik mit Ein-
und Ausgängen funktioniert und ich steuer da ja auch was an, also der µC
kanns vom Aufhängen oder Resetten schon mal nicht sein, weil sonst würde
der Sollwert auch resettet werden, was es aber nicht tut.
Wackelkontakt und schlechte Lötstelle hab ich schon alles kontrolliert,
das passt alles. Es passiert auch, wenn die ganze Schaltung im
Versuchsaufbau ruhig am Tisch liegt.
Einen Kondi in der Nähe des LCD's hab ich zur Zeit nicht, die Nächsten
liegen bei den Versorgungspins des µC und Ausgangsseitig des 7805 mit
10uF, 1uF und 100nF parallel.
Kann es sein dass eine nebenbeilaufende Leitung in die Datenleitung so
derart reinstört, dass sich das LCD verabschiedet? Es ist eine normale
12V-Leitung, die ein nachgeschaltenes Leistungsrelay mit ein paar 100mA
schaltet (dass beim Ausschalten die Spannungsspitze Schuld ist???).
Wolfgang Kogler schrieb:> Kann es sein dass eine nebenbeilaufende Leitung in die Datenleitung so> derart reinstört, dass sich das LCD verabschiedet? Es ist eine normale> 12V-Leitung, die ein nachgeschaltenes Leistungsrelay mit ein paar 100mA> schaltet (dass beim Ausschalten die Spannungsspitze Schuld ist???).
Oha.
Relais ist immer ein heißer Kandidat.
setz als ADC1_Wert mal 1024 ein. Das ist der maximal mögliche Wert.
Pjysikalisch wird der zwar nicht vorkommen können, trotzdem sollte man
damit als Maximalwert rechnen. Bricht dir aus irgendeinem Grund die
Referenzspannung am ADC ein, dann kommt der Wert nämlich vom ADC.
Tut man das, dann kommt 200 raus. 200 passt nicht mehr in ein char[3]
Du hast SRAM genug. Ob es jetzt brach liegt, oder ob du hier ein bischen
großzügig bist und auch im Fehlerfall (Wert aus irgendeinem Grund zu
hoch) die Arrays nicht überläufst, spielt für den µC keine Rolle.
In eigener Sache. Beim nächsten Projekt
Du solltest ein bischen mehr mit else-if arbeiten. Dein Stil ist
ziemlich schwer zu lesen und auf Korrektheit zu prüfen. Man muss ständig
komplette Zeilen vergleichen um sich zu überzeugen, dass Abfragen
wirklich identisch sind.
das hier
1
voidAusgang_setzen(void)
2
{
3
if(PD0_PD1_Motor==1)PORTD|=(1<<PD0);
4
if(PD0_PD1_Motor==1)PORTD|=(1<<PD1);
5
if(PD2_PD3_PD4_Lampe==1)PORTD|=(1<<PD2);
6
if(PD2_PD3_PD4_Lampe==1)PORTD|=(1<<PD3);
7
if(PD2_PD3_PD4_Lampe==1)PORTD|=(1<<PD4);
8
if(PD5_Lampe_Temperatur_OK==1)PORTD|=(1<<PD5);
9
10
if(PD0_PD1_Motor==0)PORTD&=~(1<<PD0);
11
if(PD0_PD1_Motor==0)PORTD&=~(1<<PD1);
12
if(PD2_PD3_PD4_Lampe==0)PORTD&=~(1<<PD2);
13
if(PD2_PD3_PD4_Lampe==0)PORTD&=~(1<<PD3);
14
if(PD2_PD3_PD4_Lampe==0)PORTD&=~(1<<PD4);
15
if(PD5_Lampe_Temperatur_OK==0)PORTD&=~(1<<PD5);
16
}
könnte zb auch so aussehen
1
voidAusgang_setzen(void)
2
{
3
if(PD0_PD1_Motor){
4
PORTD|=(1<<PD0);
5
PORTD|=(1<<PD1);
6
}
7
else{
8
PORTD&=~(1<<PD0);
9
PORTD&=~(1<<PD1);
10
}
11
12
if(PD2_PD3_PD4_Lampe){
13
PORTD|=(1<<PD2);
14
PORTD|=(1<<PD3);
15
PORTD|=(1<<PD4);
16
}
17
else{
18
PORTD&=~(1<<PD2);
19
PORTD&=~(1<<PD3);
20
PORTD&=~(1<<PD4);
21
}
22
23
if(PD5_Lampe_Temperatur_OK==1)
24
PORTD|=(1<<PD5);
25
else
26
PORTD&=~(1<<PD5);
27
}
noch ein bischen Makro-Magie drübergestreut und wir sind bei
Das hat dann codemässig schon eine ganz andere Qualität.
TURN_ON( LAMPEN_PORT, LAMPE_TEMP_OK );
erzählt dir in 2 Monaten beim Lesen des Codes einfach viel mehr als
PORTD |= (1 << PD5);
denn an dieser Stelle sind PORTD bzw. PD5 im Grunde technisch bedingte
Nebensächlichkeiten. An dieser Stelle ist die Bedeutung wichtig. Und die
Bedeutung ist nun mal, dass die Lampe eingeschaltet bzw. ausgeschaltet
wird, die anzeigt, dass die Temperatur im erlaubten Bereich ist.
TURN_ON( LAMPEN_PORT, LAMPE_TEMP_OK );
drückt genau das aus. Hier steht mehr oder weniger im Klartext, dass die
Lampe eingeschaltet wird, obwohl es vom Compiler genau gleich übersetzt
wird, wie die Variante in der die Ports und Bits direkt dort stehen.
@ Karl Heinz: Danke für die programmiertechnischen Hilfestellungen!
Werde die char in Zukunft größer machen, ist mir dabei nie etwas
aufgefallen, dürfte im Bezug auf das Glück gehabt haben derweil :)
Über das mit den Ausgängen beschalten hab ich mir nie etwas dabei
gedacht, da ich das gleich am Anfang immer geschrieben hab und dann im
Programm mit den einzelnen Variablen nur mehr gearbeitet habe. Kann
verstehen dass es schwierig zu lesen ist für jemanden, der das Programm
zum ersten Mal liest ;)
Wenn das Problem das Relay ist, wie kann ich dieses Problem dann
ausmertzen? Geschirmte Leitung? Oder was anderes? Die Leitung selber ist
ein paar cm neben der LCD-Datenleitung, ich kann die beiden aber nicht
mehr umverlegen, da alles in einem geschlossenem Metallgehäuse eingebaut
ist und der Platz zu klein ist.
Welche Tipps gibt es prinzipiell um die Datenübertragung störungsfreier
in Zukunft zu gestalten?
mfg Koksi
Wolfgang Kogler schrieb:> @ Karl Heinz: Danke für die programmiertechnischen Hilfestellungen!
Es tut mir leid, dass ich dir beim eigentlichen Problem nicht weiter
helfen kann. Ich hab keine Idee mehr, was es noch sein könnte. Am
ehesten tippe ich noch auf Versorgungsspannung, Relais oder irgendsowas
in die Richtung.
Gibt es einen Zusammenhang, zwischen Abstürzen und dem Schalten des
Relais?
> mehr umverlegen, da alles in einem geschlossenem Metallgehäuse eingebaut> ist und der Platz zu klein ist.
Kannst du das Relais probehalber einfach mal komplett abtrennen (Kabel
ablöten). Wenns dann ein paar Tage störungsfrei funktioniert, ist das
schon ein Hinweis, dass du auf der richtigen Spur sein könntest.
> Welche Tipps gibt es prinzipiell um die Datenübertragung störungsfreier> in Zukunft zu gestalten?
Die Störungen an der Quelle unterdrücken. Das ist immer das besser, als
wie wenn man hinten nach Klimmzüge machen muss.
> Gibt es einen Zusammenhang, zwischen Abstürzen und dem Schalten des> Relais?
Ich sage mal in ca. 50% der Fälle schaltet gerade das Relay, bei den
anderen schaltet eigentlich gar nichts sonst.
>> mehr umverlegen, da alles in einem geschlossenem Metallgehäuse eingebaut>> ist und der Platz zu klein ist.>> Kannst du das Relais probehalber einfach mal komplett abtrennen (Kabel> ablöten). Wenns dann ein paar Tage störungsfrei funktioniert, ist das> schon ein Hinweis, dass du auf der richtigen Spur sein könntest.
Kann man sagen, dass es generell etwas bringt, eine geschirmte Leitung
für das LCD zu verwenden? Für diese eine Schaltung könnte ich wenigstens
das noch ändern.
>> Welche Tipps gibt es prinzipiell um die Datenübertragung störungsfreier>> in Zukunft zu gestalten?>> Die Störungen an der Quelle unterdrücken. Das ist immer das besser, als> wie wenn man hinten nach Klimmzüge machen muss.
Wie kann ich solche Störungen noch unterdrücken?
Derweil geht der Ausgangspin des µC zu einem ULN2003A Darlington-Array
(oder zu einer normalen Transistoranschaltung, je nachdem..) und dann zu
den Relays mit je einer Freilaufdiode.
Ich hab mal versuchsweise Alu-Folie rund um das Datenkabel gewickelt, um
einen beidseitig offenen Schirm zu "simulieren". Die Störungen sind
tatsächlich um 70% zurückgegangen. Ich schätze wenn der Schirm
beidseitig auf Masse liegt werden die Störungen noch weniger.
Wie sieht normalerweise Eure LCD-Ansteuerung aus? Irgendwelche
Besonderheiten, die mir auch helfen könnten?
Wolfgang Kogler schrieb:> Alu-Folie rund um das Datenkabel gewickelt ...> Die Störungen sind tatsächlich um 70% zurückgegangen.
Du hast irgendeinen feudalen Bock im Aufbau...
> Wie sieht normalerweise Eure LCD-Ansteuerung aus?
Normal, eben... Aber wie sieht deine aus?
Zeig doch mal den dazu passenden Schaltplan.
Und mach ein paar (brauchbare) Fotos von deinem Aufbau...
> Irgendwelche Besonderheiten, die mir auch helfen könnten?
Nichts, was nicht im Datenblatt stünde.
Hier ist der Schaltplan von dem Aufbau auf der Platine.
Die Schaltung selber ist in einem Metallgehäuse eingebaut.
K5 und K6 sind die beiden Relais, welche das Leistungsrelay schalten.
Die Motorleitungen, welche vom Leistungsrelay weggehen, sind alle
ausserhalb des Metallgehäuses, d.h. keine Motorleitung in der Nähe
(wegen Störung).
Hallo,
bei mir hat schon folgendes geholfen:
- Versorgunsspannung VCC des Display's über einen 330 Ohm Widerstand
ansteuern.
- Der Metallrahmen des Display's darf keine Verbindung zum Metallgehäuse
haben.
> - Versorgunsspannung VCC des Display's über einen 330 Ohm Widerstand> ansteuern.> - Der Metallrahmen des Display's darf keine Verbindung zum Metallgehäuse> haben.
Aha, das ist ja interessant, muss ich mir merken. Kannst du mir auch
sagen warum das so ist, zwecks Verständnis... ;)
> Aha, das ist ja interessant, muss ich mir merken. Kannst du mir auch> sagen warum das so ist, zwecks Verständnis
Bei mir wurden Leistungsschütze im gleichen Schaltschrank geschaltet.
Und da hatte ich auch das Problem, dass irgendwann der Displaytext
durcheinander kam. Der ATMega machte mir kein Problem - aber der
Displaycontroller. Besser wurde es, als der Metallrahmen des Display's
nicht mehr leitend mit dem Schaltschrank verbunden war. Da der
Schaltschrank an PE liegt ist eine Masseschleife entstanden die mir dann
wohl die Probleme gemacht hat.
Eine Erklärung warum die Störungen mit einem 330 Ohm-Widerstand in VCC
des Display's zu 100% beseitigt werden konnten, habe ich nicht.
Zusätzliche Abblockkondensatoren haben bei mir nichts bewirkt.
Danke Jürgen für deine ausführlichen Schilderungen deiner Erkenntnisse,
werde diese sicherlich in den nächsten Schaltungsentwurf einfliessen
lassen und dank auch an Karl Heinz, der mir einige neue
Programmiertechniken geschildert hat. Auf dieses Forum ist halt
Verlass... ;-)
Falls jemand noch weitere Erkenntnisse bezügliches dieses Thema hat,
würde ich mich noch gerne freuen.
mfg Koksi
@ Wolfgang:
Kannst Du nicht mal testweise einen Widerstand in die VCC-Leitung des
Display's hängen um zu schauen, ob sich etwas ändert? Kann natürlich
sein, dass Du den Widerstand etwas kleiner wählen musst, da wohl das
4x20 Zeichen Display etwas mehr Strom benötigt als bei mir das 2x16
Zeichen Display. Mich würde nämlich sehr interessieren, ob dies auch bei
Dir hilft.
Gruß
Jürgen
Die Symthomatik hatte ich auch, habs auch lange nicht hinbekommen.
Nun betreibe ich das programm mit einem kleinen schönheitsfehler aber
dafür habe ich mit dem display keine probleme mehr.
Ich schalte einfach im programm das display kurz ab, schalte das relais
und schalte es danach einfach wieder ein.
ist halt für etwar 2 sekunden keine displayanzeige aber ich kann damit
leben :-)
lg
Das ist ja interessant, anscheinend haben doch mehr Personen dieses
Problem auf irgendeine Weise...
Zusammengefasst würde das dann so aussehen:
Wenn das LCD aus heiterem Himmel komische Zeichen anzeigt und/oder
komplett abstürzt, der µC aber weiterläuft ohne Fehler, können einer
oder mehrere Punkte von der folgenden Liste eventuell weiterhelfen:
-) Externe Störungen von Motor, Relais, usw. beseitigen
-) Kondensator in der Nähe des LCD
-) Widerstand in die Versorgungsleitung
-) Metallrahmen des Displays isoliert aufbauen
-) Kabellänge am Besten unter 10cm
Hatte mal was ähnliches,
ganz wilde Zeichen sehr schnell abwechselnd. Ich hatte damals
wahrscheinlich einen Softwarefehler in 4 Bit Modus. Und zwar wurde da
das High und Low nibble vertauscht. Entweder ein Programmfehler oder ein
Timing war zu kurz, sodass das Display ein Nibble nicht mitbekam. Der
Fehler verschwand dann nach einigen Stunden aber wieder und tauchte
genauso wieder auf.
Gruß,
Tubie