Hi, ich hab hier ein LCD von Pollin(Bestellnr 120 420) welches ich per PCF 8574P steuere. Das LCD ist wie folgt an den PCF 8574P angebunden: DB4 - P0 DB5 - P1 DB6 - P2 DB7 - P3 RS - P4 RW - P5 E - P7 Die Initialisierung, Löschen, Kursorsteuerungen funktionieren ohne Probleme, jedoch werden einige Buchstaben nicht richtig dargestellt. Ich möchte ein L auf den LCD anzeigen und übermittle dazu: 94h 1ms Pause 00h 1ms Pause 9Ch 1ms Pause 00h Auf den LCD bekomme ich allerdings ein D angezeigt, obwohl hierfür eig folgendes übermittelt werden müsste: 94h 1ms Pause 00h 1ms Pause 94h 1ms Pause 00h Dieser Fehler findet sich auch bei einigen anderen Zeichen, jedoch nicht bei allen. Über Hinweise oder auch Lösungsvorschläge würde ich mich freuen. Pyromane
Du toggelst neben dem EN auch das Command/Data usw. Versuch einfach mal, bei der Datenübertragung nur Bit 7 (EN)zu toggeln, also: 94h 1ms Pause 14h 1ms Pause 9Ch 1ms Pause 1Ch Wenn ich mich recht erinnere, werden die Daten mit fallender Flanke übernommen. Habe gerade mal in meinen I2C Routinen (PIC) nachgesehen. Da mache es ich so ähnlich: ; lcd_config: ; Bit D0 to D3 are directly written to PCF8574(A) after being IORed with nibble data D4-D7 ; D0 = EN, default to H ; D1 = RW, default to L (write to LCD) ; D2 = RS, default to L (will be modified in LCD_Command/LCD_Data) ; D3 = Display-Backlight, set to L (on) ... iorwf lcd_temp, W call IIC_Put andlw 0xfe ; clear enable bit call IIC_Put
Wahrscheinlich ist eine der Datenleitungen von PCF8574 zum Display nicht richtig angeschlosen. tippe mal auf DB7. Schau dir mal die binäre Codierung der Zeichen 'L' und 'D' an.
Die Pausen kannst Du Dir normalerweise sparen. I2C ist langsam genug (außer bei Clear/Home).
Danke für die Antworten Ago schrieb: > 94h > 1ms Pause > 14h > 1ms Pause > 9Ch > 1ms Pause > 1Ch Es erscheint auf dem LCD leider wieder ein D Skript Kiddy schrieb: > Wahrscheinlich ist eine der Datenleitungen von PCF8574 zum Display nicht > richtig angeschlosen. Alle Pins wurden durchgemessen. Skript Kiddy schrieb: > Schau dir mal die binäre Codierung der Zeichen 'L' und 'D' an. L = 0100 9 D = 0100 0100 (Leerstellen wurden zu besseren Übersicht hinzugefügt) Klaus 2m5 schrieb: > Die Pausen kannst Du Dir normalerweise sparen. I2C ist langsam genug > (außer bei Clear/Home). Danke für die Info.
L = 0100 1100 D = 0100 0100 Die beiden unterscheiden sich nur in einem Bit. Das würde ich als Grundlage für die Fehlersuche ansetzen. Schreib mal 1100 1100 = 0xCC als Zeichen auf das Display. Wenn mit dem DB7 was nicht stimmt müsste dabei ein 'D' auf dem Display erscheinen. Denn Bit 3 und Bit 7 des Zeichens werden ja über DB7 übertragen. Gruß Das Skriptende Kind
Ich hab folgendes übertragen 9Ch 00h 9Ch 00h und das Zeichen im Anhang erhalten. Anmerkung: "Display aus" benötigt den DB7 und dieser Befehl wird problemlos ausgeführt.
Gerald O. schrieb: > Ich hab folgendes übertragen > 9Ch > 00h > 9Ch > 00h > und das Zeichen im Anhang erhalten. OK. Dann scheint es ein Software-Problem zu sein. Kannste du mal deine Sourcen Posten?
Ich verwende die AVR-NET-IO mit Ethersex Firmware. Die I2C Befehle werden von einem AutoIT Skript per TCP an die AVR-NET-IO übermittelt. Der Debug Modus in der Ehtersex Firmware ist aktitviert und somit kann ich sicher sein das die I2C Befehler richtig übertragen werden. Keine elegante Lösung aber ich habe leider gerade keinen Zugriff auf einen Brenner. :/ AutoIT Skript dennoch posten?
$tab0data ist ein Input Feld $cm* listet die übermittelten und empfangenen Befehle/Nachrichten auf _BinaryToHexString ist eine Funktion um Binärwerte in hexadezimale Zahlen zu wandeln, die Funktion wurde schon mehrfach mit Diversen Tool gegengeprüft.
1 | $laenge = stringlen(GUICtrlRead($tab0data)) |
2 | if $laenge > 0 Then |
3 | if $laenge > 20 Then |
4 | $data = StringLeft(GUICtrlRead($tab0data), 20) |
5 | Else |
6 | $data = GUICtrlRead($tab0data) |
7 | EndIf |
8 | |
9 | $data2 ="" |
10 | for $t=1 to $laenge ;jeden Buchstaben im String |
11 | $asciicode=asc(stringmid($data,$t,1)) ;in asciicode umwandeln |
12 | for $i=7 to 0 step -1 ;asciicode in bits |
13 | if bitand($asciicode,2^$i) then |
14 | $data2&="1" |
15 | else |
16 | $data2&="0" |
17 | endif |
18 | next |
19 | next |
20 | |
21 | For $i = 1 To (($laenge * 2) - 1) +1 |
22 | $zw1 = StringLeft($data2, (4*$i)) |
23 | $zw1 = StringRight($zw1, 4) |
24 | $zw2 = "1001" & $zw1 |
25 | $zw3 = _BinaryToHexString($zw2) |
26 | |
27 | ;Enable ein + Befehl übermitteln |
28 | $bef = "pcf8574x set 1 0 " & $zw3 |
29 | TCPSend($socket, $bef & @CRLF) |
30 | sleep(1) |
31 | $recv = TCPRecv( $socket, 2048) |
32 | If $recv <> "" Then |
33 | GUICtrlSetData($cmd, " < " & $bef & @CRLF & " > " & $recv & @CRLF, true) |
34 | endif |
35 | |
36 | ;Enable aus |
37 | $bef = "pcf8574x set 1 0 00" |
38 | TCPSend($socket, $bef & @CRLF) |
39 | sleep(1) |
40 | $recv = TCPRecv( $socket, 2048) |
41 | If $recv <> "" Then |
42 | GUICtrlSetData($cmd, " < " & $bef & @CRLF & " > " & $recv & @CRLF, true) |
43 | endif |
44 | sleep(20) |
45 | Next |
46 | EndIf |
Super kommentiert. Na mal schauen, ob es Jemanden gibt, der sich das bei der Hitze antut.
Boah... :-) Also wenn ich das richtig überblicke, enthält $data2 den kompletten String data, und zwar jeweils 8 "Bit" als String aus 0 und/oder 1... For $i = 1 To (($laenge * 2) - 1) +1 $zw1 = StringLeft($data2, (4*$i)) $zw1 = StringRight($zw1, 4) $zw2 = "1001" & $zw1 $zw3 = _BinaryToHexString($zw2) ... For $i = 1 To (($laenge * 2) - 1) +1 $zw1 = StringMid($data2, (4*$i)-3, 4) $zw2 = _BinaryToHexString($zw1) ;Enable ein + Befehl übermitteln $bef = "pcf8574x set 1 0 9" & $zw2 ... ;Enable aus $bef = "pcf8574x set 1 0 1" & $zw2 ...
Oder gleich so (ohne Garantie natürlich, habe aber die internen Funktionen genutzt (lt. http://www.autoitscript.com/autoit3/docs/ ). $data = GUICtrlRead($tab0data) $laenge = StringLen($data) if $laenge > 0 Then if $laenge > 20 Then $laenge = 20 $data = StringLeft($data, 20) EndIf $data2 ="" ; Das wird unser Hex-String for $t=1 to $laenge ;jeden Buchstaben im String $asciicode=asc(StringMid($data,$t,1)) ;in asciicode umwandeln $data2 &= Hex($asciicode, 2) ;und dann in hex (2stellig) next For $i = 1 To ($laenge * 2) $zw1 = StringMid($data2, $i, 1) ;Enable ein + Befehl übermitteln $bef = "pcf8574x set 1 0 9" & $zw1 TCPSend($socket, $bef & @CRLF) sleep(1) $recv = TCPRecv( $socket, 2048) If $recv <> "" Then GUICtrlSetData($cmd, " < " & $bef & @CRLF & " > " & $recv & @CRLF, true) endif ;Enable aus $bef = "pcf8574x set 1 0 1" & $zw1 TCPSend($socket, $bef & @CRLF) sleep(1) $recv = TCPRecv( $socket, 2048) If $recv <> "" Then GUICtrlSetData($cmd, " < " & $bef & @CRLF & " > " & $recv & @CRLF, true) endif sleep(20) Next EndIf
Vielen Dank für die Antworten Ago schrieb: > Also wenn ich das richtig überblicke, enthält $data2 den kompletten > String data, und zwar jeweils 8 "Bit" als String aus 0 und/oder 1... Ja, $data2 enthält den Wert aus $data in binärer Form Ago schrieb: > $zw1 = StringMid($data2, (4*$i)-3, 4) Danke, hatte ich lange gesucht Ago schrieb: > ;Enable ein + Befehl übermitteln > $bef = "pcf8574x set 1 0 9" & $zw2 Kurze Erklärung: pcf8574x set I2C Adressen PCF8574/PCF8574A wert Ich verwende den PCF8574 mit A0 = 1, A1+A2 = 0 daraus ergibt sich dann folgendes: pcf8574x set 1 0 wert wert ist in meinem Fall $zw3 Ich habe den gesamten Code mit Kommentaren versehen
1 | $laenge = stringlen(GUICtrlRead($tab0data)) ;Länge der Daten feststellen |
2 | if $laenge > 0 Then ;prüfen ob Daten vorhanden sind |
3 | if $laenge > 20 Then ;Anzeige auf 20 Zeichen limitieren und in $data speichern |
4 | $data = StringLeft(GUICtrlRead($tab0data), 20) |
5 | Else |
6 | $data = GUICtrlRead($tab0data) ;direkt in $data speicher, da kleiner als 20 Zeichen |
7 | EndIf |
8 | |
9 | $data2 ="" ;Variable anlegen, wird binär $data enthalten |
10 | for $t=1 to $laenge ;jeden Buchstaben im String |
11 | $asciicode=asc(stringmid($data,$t,1)) ;in asciicode umwandeln |
12 | for $i=7 to 0 step -1 ;asciicode in Bits |
13 | if bitand($asciicode,2^$i) then |
14 | $data2&="1" |
15 | else |
16 | $data2&="0" |
17 | endif |
18 | next |
19 | next |
20 | |
21 | For $i = 1 To (($laenge * 2) - 1) +1 ;Daten fürs übermitteln aufbereiten |
22 | $zw1 = StringMid($data2, (4*$i)-3, 4) ;Nibble filtern |
23 | $zw2 = "1001" & $zw1 ;um Steuerdaten erweitern |
24 | $zw3 = _BinaryToHexString($zw2) ;binäre Daten in hex wandeln |
25 | |
26 | ;Enable ein + Befehl/Daten übermitteln |
27 | $bef = "pcf8574x set 1 0 " & $zw3 ;I2C Befehl erstellen |
28 | TCPSend($socket, $bef & @CRLF) ;Befehl an AVR-NET-IO übermitteln |
29 | sleep(1) |
30 | $recv = TCPRecv( $socket, 2048) ;Antwort speichern |
31 | If $recv <> "" Then ;Befehl + Antwort anzeigen |
32 | GUICtrlSetData($cmd, " < " & $bef & @CRLF & " > " & $recv & @CRLF, true) |
33 | endif |
34 | |
35 | ;Enable aus |
36 | $bef = "pcf8574x set 1 0 00" ;I2C Befehl(=enable aus) erstellen |
37 | TCPSend($socket, $bef & @CRLF) ;Befehl an AVR-NET-IO übermitteln |
38 | sleep(1) |
39 | $recv = TCPRecv( $socket, 2048) ;Antwort speichern |
40 | If $recv <> "" Then ;Befehl + Antwort anzeigen |
41 | GUICtrlSetData($cmd, " < " & $bef & @CRLF & " > " & $recv & @CRLF, true) |
42 | endif |
43 | sleep(20) |
44 | Next |
45 | EndIf |
Edit: die Funktion Hex() hatte bei mir leider nicht den gewünschten Effekt gebracht.
Gerald O. schrieb: > Ago schrieb: >> ;Enable ein + Befehl übermitteln >> $bef = "pcf8574x set 1 0 9" & $zw2 > Kurze Erklärung: > pcf8574x set I2C Adressen PCF8574/PCF8574A wert > Ich verwende den PCF8574 mit A0 = 1, A1+A2 = 0 daraus ergibt sich dann > folgendes: > pcf8574x set 1 0 wert > wert ist in meinem Fall $zw3 So wie ich das sehe, entspricht zw3 in deinem Fall auch "nur" dem 8-Bit Wert in Hexform, oder? Da du ja die "1001" + 4-Bit Nibble als Hexzahl rüberschiebst, sendest du also immer "pcf8574x set 1 0 9x" wobei x dem Hex-nibble entspricht. Nichts anderes sollte bei $bef = "pcf8574x set 1 0 9" & $zw2 passieren. $zw2 enthält ja bei mir direkt den Hexwert aus $data2. $bef = "pcf8574x set 1 0 00" ;I2C Befehl(=enable aus) erstellen Wenn das "00" das Byte ist, welches an den PCF ausgegeben wird, dann änderst du auch gleichzeitig mit dem Enable das "RS", wechselst also vom Daten in den Command-Modus (während das 2. Nibble ja eigentlich noch übertragen werden soll). Das kann nicht gehen.
Ich habe in der Zwischenzeit noch mal bezüglich LCDs nachgelesen. Man darf nur den Enable Pin toggelen, mein Fehler :/ Ich werde die Initialisierung und die restlichen Teile entsprechend anpassen, hoffe danach ist der Fehler verschwunden, auf jeden Fall melde ich mich danach noch einmal(wahrscheinlich morgen). Vielen Dank für die Infos und Hinweise.
Gerald O. schrieb: > Ich habe in der Zwischenzeit noch mal bezüglich LCDs nachgelesen. Man > darf nur den Enable Pin toggelen, mein Fehler :/ Genau das stand in der ersten Antwort. Gerald O. schrieb: > Ago schrieb: >> 94h >> 1ms Pause >> 14h >> 1ms Pause >> 9Ch >> 1ms Pause >> 1Ch > Es erscheint auf dem LCD leider wieder ein D Hat doch angeblich nicht funktioniert.
Leider hat auch das Überarbeiten des Skriptes nicht den gewünschten Effekt gezeigt und es wurden immer noch falsche Buchstaben angezeigt. Ich habe mal die gesamten Großbuchstaben versucht und bin auf folgendes gekommen: SOLL IST SOLL IST H @ 0100 1000 0100 0000 J B 0100 1010 0100 0010 L D 0100 1100 0100 0100 M E 0100 1101 0100 0101 N F 0100 1110 0100 0110 O G 0100 1111 0100 0111 X P 0101 1000 0101 0000 Z R 0101 1010 0101 0010 Nachdem ich mein Multimeter auf den betreffenden Pin gehängt habe und das Skript erneut laufen lassen habe war der Fehler auf einmal weg. >> Kapazitives Problem, Aus Interesse versuchte ich dann noch mein altes Skript, welches auch Fehlerfrei funktionierte. Vielen Dank für die zahlreichen Tipps und auch Lösungsvorschläge.
Das stand schon in Antwort #2: Skript Kiddy schrieb: > Wahrscheinlich ist eine der Datenleitungen von PCF8574 zum Display nicht > richtig angeschlosen. > > tippe mal auf DB7.
Klaus 2m5 schrieb: > Das stand schon in Antwort #2: > > Skript Kiddy schrieb: >> Wahrscheinlich ist eine der Datenleitungen von PCF8574 zum Display nicht >> richtig angeschlosen. >> >> tippe mal auf DB7. Ich hatte an den PINs eine Pegel von 4,95V gemessen, jedoch sagt das leider nichts über die Flanken aus. Nebenbei wurde "Display aus" immer ordnungsgemäß ausgeführt und dieser Befehl benötigt DB7.
Gerald O. schrieb: > Klaus 2m5 schrieb: >> Das stand schon in Antwort #2: >> >> Skript Kiddy schrieb: >>> Wahrscheinlich ist eine der Datenleitungen von PCF8574 zum Display nicht >>> richtig angeschlosen. >>> >>> tippe mal auf DB7. > > Ich hatte an den PINs eine Pegel von 4,95V gemessen, jedoch sagt das > leider nichts über die Flanken aus. Bei deinen Wartezeiten bis zum Toggeln des E-Pins sind die Flanken ziemlich egal. Ich tippe eher auf eine kalte Lötstelle oder sowas ähnliches. Wenn du jetzt mit deinem Multimeter draufgehst, schliesst du den Kontakt, der ansonsten offen ist.
Karl heinz Buchegger schrieb: > Bei deinen Wartezeiten bis zum Toggeln des E-Pins sind die Flanken > ziemlich egal. Ich tippe eher auf eine kalte Lötstelle oder sowas > ähnliches. Wenn du jetzt mit deinem Multimeter draufgehst, schliesst du > den Kontakt, der ansonsten offen ist. Sehe ich auch so. Keiner kann vorhersagen, was bei einer instabilen hochohmigen Verbindung passiert und wann das Signal am Empfänger tatsächlich dem gesendeten entspricht oder wann nicht.
Karl heinz Buchegger schrieb: > Bei deinen Wartezeiten bis zum Toggeln des E-Pins sind die Flanken > ziemlich egal. Ich tippe eher auf eine kalte Lötstelle oder sowas > ähnliches. Wenn du jetzt mit deinem Multimeter draufgehst, schliesst du > den Kontakt, der ansonsten offen ist. Ich greife das Signal mit Klemmen am DB7 ab, sobald ich die Messleitungen am Multimeter abstecke tritt der Fehler wieder auf. Beim übertragen der Werte 94h 14h an den PCF8574 merkte ich einen kurzzeitigen Spannungseinbruch auf 3,6V am BD7, jedoch nicht an den anderen PINs. Leider ist das Multimeter zu träge um genaueres zu sagen. Wünsche noch einen schönen Abend Gruß Pyromane
Pullups an die PCF-Ausgänge. Also 4k7 (oder irgendwas zwischen 1k und 15k) zwischen + und jede der acht Leitungen zwischen PCF und LCD.
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.