Forum: Mikrocontroller und Digitale Elektronik LCD am I2C Bus


von Achim S. (achims)


Lesenswert?

Hallo Gemeinde
mühe mich jetzt seit einigen Stunden ab, ein LCD (RN) mit einem PCF 8574 
zu betreiben. Leider geht ausser der Beleuchtung nicht viel (und einigen 
schwarzen Rechtecken).
Auch Goo.. tut sich damit sehr schwer. Findet zwar viel, aber (sehr) 
wenig zu gebrauchen. Könnte mir jemand weiterhelfen? Bin für jede Hilfe 
dankbar.
achim

von Max H. (hartl192)


Lesenswert?

Achim Seeger schrieb:
> (und einigen
> schwarzen Rechtecken).
Ist die gesamte erste Zeile schwarz?

Welches LCD hast du?

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>Könnte mir jemand weiterhelfen?

Wie soll man das jetzt machen?
Die Glaskugel befragen?

von Max H. (hartl192)


Lesenswert?

Schaltplan + Code könntest du auch posten.

von Harald (Gast)


Lesenswert?

Von sainsmart gibt's arduino libraries. Die kannst dir adapieren.

von Achim S. (achims)


Lesenswert?

Es ist nicht für Arduino, sonder als normaler Code in C gedacht. Das LCD 
und die Platine dazu mit dem PCF ist von Pollin (erster Versuch)
Atmega 32 16MHz
1
#define F_CPU 16000000 
2
#include "i2cmaster.h"  // Einbinden der i2cmaster.h 
3
#include "i2clcd.h"     // Einbinden der i2clcd.h 
4
int main(void) 
5
{                       // Hauptprogramm 
6
lcd_init();             // Starte I2CLCD 
7
lcd_command(LCD_CLEAR); // Leere Display 
8
lcd_wait_ms(30);        // Warte 30ms 
9
lcd_printlc(1,1,"Hallo Welt"); // Ausgabe an 1.Zeile, 1. Stelle 
10
while(1)
11
{ ... // Ab hier beginnt Hauptschleife 
12
} 
13
}
Mit diesen Stück soll es schon gehen. Leider unklar. Es fehlt die 
Adresse, I2C init, _delay usw.
Die beiden Datein habe ich eingebunden. Leider ist das schon eines der 
besten was tante Goo zu bieten hat (unverständlich)
achim

von Mike (Gast)


Lesenswert?

Achim Seeger schrieb:
> Die beiden Datein habe ich eingebunden

Und was ist met den zugehörgien C-Dateien?

Und damit delay funktioniert, sollte auch delay.h einbezogen werden.

von Harald N. (haraldn)


Lesenswert?

Ach so. Sollte trotzdem nicht so schwer zu adaptieren sein!? Jedenfalls 
ist das Board von Pollin und das von Sainsmart sehr gleich aufgebaut.

von Achim S. (achims)


Lesenswert?

Hallo Harald
werde es mir gleich ansehen. Vielleicht finde ich die Sttelle die ich 
vergessen habe
Nach den beiden C Datein werde ich gleich schauen, eigentlich sund sie 
mit drin, schaue zur Vorsicht noch mal nach.
achim

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

Habe weiter gesucht. Schaut es euch mal an.
In meinem Programm verwende ich diese Zeile
1
lcd_printlcd(1,1,"Hallo Welt");

Als Fehlermeldung bekomme ich die Datei i2clcd genannt.
Dann wird meine Zeile aus dem kleinen Programm genannt. Verstehe leider 
den Zusammenhang nicht
achim

von Mike (Gast)


Lesenswert?

Achim Seeger schrieb:
> Als Fehlermeldung bekomme ich die Datei i2clcd genannt.
> Dann wird meine Zeile aus dem kleinen Programm genannt. Verstehe leider
> den Zusammenhang nicht

Immerhin kennst du den genauen Wortlaut der Fehlermeldung.

von Achim S. (achims)


Lesenswert?

Kein Problem, anbei die Fehlermeldungen:

Error  2  'LCD_BL_PIN' undeclared (first use in this function)
Error  1  'OFF' undeclared here (not in a function)
Warning  3  each undeclared identifier is reported only once for each 
function it appears in  ...\i2clcd.c

Habe mir die Stellen in der i2clcd.c angesehen. Komme damir aber auch 
nicht weiter
achim

von holger (Gast)


Lesenswert?

Wo ist der komplette Code?

Wenn das in diesen Minihäppchen hier so weiter
geht dauert das ja sonst bis 2030.

von Ronny S. (phoenix-0815)


Lesenswert?

Achim Seeger schrieb:
> lcd_printlc(1,1,"Hallo Welt"); // Ausgabe an 1.Zeile, 1. Stelle

Achim Seeger schrieb:
> lcd_printlcd(1,1,"Hallo Welt");

von Achim S. (achims)


Lesenswert?

Im Moment habe ich nur das kleine Stückchen Code. Gehe langsam ran. 
Möchte nur das ansprechen des LCD erst mal begreifen.
Die i2clcd.c habe ich aus dem netz. Soll so wie sie funktionieren.
Leider scheint die Ausbeute im Netz nicht gross zu sein. Viele haben die 
gleiche Frage gestellt. Einiges habe ich in Basic gefunden. Damit ist 
wohl Tante Goo .. am Ende.
Hat wirklich keiner ein kleines Stück für mich? Alle sprechen darüber, 
aber scheinbar gibt es das Problem schon länger.
Ist zeit was zu machen.
achim

von holger (Gast)


Lesenswert?

>Die i2clcd.c habe ich aus dem netz.

Das du das nicht selber programmiert hast ist klar.

>Soll so wie sie funktionieren.

Tut es aber nicht. Wo ist die i2c_init()?
Wie kommst du darauf das es ohne geht.

von Achim S. (achims)


Lesenswert?

Es geht nicht ohne, ist klar. Habe dierste Version reingestellt. Danach 
sieht es so aus:
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/pgmspace.h>
4
#include <util/delay.h>
5
6
#include "i2cmaster.h"              // Einbinden der i2cmaster.h
7
#include "i2clcd.h"            // Einbinden der i2clcd.h
8
9
int main(void)
10
{                         // Hauptprogramm
11
  
12
  i2c_init();
13
  lcd_init();                        // Starte I2CLCD
14
  
15
  
16
  //lcd_command(LCD_CLEAR);          // Leere Display
17
  
18
          _delay_ms(30);      
19
  //lcd_wait_ms(30);                   // Warte 30ms
20
lcd_printlcd(1,1,"Hallo Welt");   // Ausgabe an 1.Zeile, 1. Stelle
21
  while(1)
22
  {
23
                                 // Ab hier beginnt Hauptschleife
24
  }
25
}
Fehler sind die selben
achim

von tommy (Gast)


Lesenswert?

Auf welche Adresse ist der PCF8574 mit den 3 Jumpern eingestellt?
Und welche Adresse verwendest Du in der Software?

von Klaus I. (klauspi)


Lesenswert?

Harald Nagy schrieb:
> Ach so. Sollte trotzdem nicht so schwer zu adaptieren sein!? Jedenfalls
> ist das Board von Pollin und das von Sainsmart sehr gleich aufgebaut.

Sainsmart sagt mir nichts? Das I2C-LCD Modul von Pollin ist aber etwas 
anders als diejenigen, die ich bisher von Ebay-China erhalten habe:
RS-Bit und Enable-Bit sind vertauscht
Das Bit für Hintergrundbeleuchtung wird invertiert verwendet

Bei der Adresse ist das letzte Bit für Lesen/Schreiben IMHO schon mit 
reingerechnet.

von holger (Gast)


Lesenswert?

>Fehler sind die selben
>Kein Problem, anbei die Fehlermeldungen:
>
>Error  2  'LCD_BL_PIN' undeclared (first use in this function)
>Error  1  'OFF' undeclared here (not in a function)

So, ich rate jetzt mal:
Warum hast du die beiden defines in der i2clcd.h gelöscht?

von Gerald B. (gerald_b)


Lesenswert?

Richtig, beim Pollin Modul sind RS und EN vertauscht.
Du mußt die normale I2C Lib patchen. Siehe hier: 
http://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/
Wenn man derlei Fallstricke einmal gemeistert hat, das Display über I2C 
zu betreiben, ist es recht easy zu handhaben. Auch wenn es direkt am µC 
geht, ziehe ich die I2C Lösung vor, da man das Display dann etwas vom µC 
abgesetzt montieren kann. 1m mit einem 4 pol. Kabel sind absolut kein 
Problem.

Gruß Gerald

von Achim S. (achims)


Lesenswert?

Hallo gerald
Danke für die Info. Werde gleich nachschauen. Bei dem Pollin ist ja 
nicht einmal der Prozessor angegeben.

Hallo Holger
ich habe in der i2clcd nichts gelöscht. Der Fehler kommt schon im ori.

Hallo Tommy
auf dem Modul habe ich 3x GND eingestellt, das müsste die x040 sein. In 
der Software sehe ich keine Einstellung, warum auch immer. Ist mir klar, 
das ohne nicht geht.

Da werde ich heute nochmal alles durchsuchen. Es muss doch einen Hinweis 
dazu geben. Ein Tut dazu ist schon fast ein Wunder. nicht gleich 
übertreiben.
achim

von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

Poste dein VOLLSTÄNDIGES Projekt mit allen Dateien.

von Georg G. (df2au)


Lesenswert?

Achim Seeger schrieb:
> In
> der Software sehe ich keine Einstellung

Dann zeig uns doch bitte mal deine i2clcd.h. Da würde ich die 
Einstellung vermuten.

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

Habe im Netz noch was anderes gefunden. Der Fehler ist aber der gleiche. 
Es scheint aus dieser Stelle zu kommen:
1
int backlight = OFF;
2
.....
3
void lcd_write_i2c(unsigned char value)
4
{
5
        i2c_start_wait(LCD_I2C_DEVICE+I2C_WRITE);
6
    
7
  if (backlight) {
8
    value |= (1 << LCD_BL_PIN);
9
  } else {
10
    value &= ~(1 << LCD_BL_PIN);
11
  }  
12
    
13
        i2c_write(value);
14
        i2c_stop();
15
}

Das Teil vom Code steckt in der angehängten Datei
achim

von Achim S. (achims)


Lesenswert?

Sorry vergessen:
Fehlerangebe durch Studio 6 in diesen 3 Zeilen:
1
int backlight = OFF;
2
3
value |= (1 << LCD_BL_PIN);
4
5
value &= ~(1 << LCD_BL_PIN);

achim

von Georg G. (df2au)


Lesenswert?

Achim Seeger schrieb:
> Es scheint aus dieser Stelle zu kommen:

Nochmal, ganz langsam geschrieben:
Wo hast du "OFF" definiert? In i2clcd.c oder i2clcd.h muss ein
#define OFF ...
stehen.
Und genauso muss irgendwo ein
#define LCD_BL_PIN ...
zu finden sein.
Wenn das nicht definiert ist, hat der Compiler keine Chance zu erkennen, 
was du von ihm verlangst.

Die von dir nicht gefundene I2C-Adresse des Boards findest du, indem du 
nach
#define LCD_I2C_DEVICE ...
suchst.

"grep" ist eine gute Hilfe bei diesen Suchereien in mehreren Dateien. 
Dr. Gurgel hilft dir bei dem Thema bestimmt.

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

Anbei auch die h datei. Ich habe das nicht definiert. Habe die beiden 
Datein so übernommen. Sollen so gehen.
Ganz zu Anfang habe ich das nachfolgende auskommentiert, ist aber wider 
raus
1
int backlight = OFF;
Was du sagst ist aber eine gute Idee (ganz vergessen). Werde alles 
durchsuchen, jetzt auch besonders die h datei. muss ja irgendwo stehen.
achim

von Georg G. (df2au)


Lesenswert?

Achim Seeger schrieb:
> Anbei auch die h datei

Dann habe ich eine traurige Nachricht für dich: Die Header Datei passt 
nicht 100% zur C-Datei. Da haben die Autoren etwas geschlampt.

Kontrolliere, ob deine Verdrahtung zu den Definitionen in der Header 
Datei passt. Und dann benamse den LCD_EMPTY_PIN um in LCD_BL_PIN - 
sofern du überhaupt Backlight verwendest.

Dann noch
#define ON 1
#define OFF 0
einfügen und es sollte funktionieren.

Allerdings sind die Chancen gut, dass noch mehr Macken in dem Beispiel 
sind.

Für die Zukunft: Poste dein komplettes Projekt mit allen Dateien. Dann 
geht es deutlich schneller.

: Bearbeitet durch User
von Achim S. (achims)


Lesenswert?

Danke dir Georg. Werde es so machen und über den Erfolg berichten.
Eigentlich hatte ich alles drin. Leider besteht die Sache bisher erst 
aus wenigen Sachen. Mache es aber so.
achim

von Achim S. (achims)


Lesenswert?

Hab da was komisches gefunden.
Diese Datein scheint es 2 mal zu geben. Beide mit der gleichen 
Versionsnummer. Unterschied ist gerade das backlight bzw die Abfrage 
dazu.
Das werde ich mal testen
achim

von Georg G. (df2au)


Lesenswert?

Achim Seeger schrieb:
> Diese Datein scheint es 2 mal zu geben

Dr. Gurgel wirft bei der Suche nach "i2clcd.h lcd_bl_pin" auf Anhieb die 
richtige Datei aus. Und da sieht man, dass deutlich mehr als nur dieser 
eine Pin geändert wurde. Du musst es schon an deine Hardware anpassen.

von Achim S. (achims)


Lesenswert?

AVR Studio zeugt keine Fehler mehr. Comp geht, jetzt geht es an Hardware
Ansonsten habe ich gesehen, eine Version stammt von 2006 un die andere 
von 2012
achim

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

Ich verwende jetzt das folgende Programm:
1
#define F_CPU 16000000UL
2
3
#include "i2cmaster.h"
4
#include <util/delay.h>
5
6
#define LCD_I2C_ADDRESS    0x40
7
8
#define ENABLE_MASK      0b01000000
9
#define DISABLE_MASK    0b10111111
10
#define COMMAND_MASK    0b00000000
11
#define DATA_MASK      0b00100000
12
13
#define INIT_4BIT_MODE    0b00000010
14
15
void write_to_pcf8574(char data)
16
{
17
  i2c_write(data);
18
  _delay_us(40);
19
  i2c_write(data | ENABLE_MASK);
20
  _delay_us(40);
21
  i2c_write(data & DISABLE_MASK);
22
  _delay_us(40);
23
}
24
25
void write_byte(char data, char mask)
26
{
27
  //write the high nibble first...
28
  char nibble = mask | ((data & 0xF0) >> 4);
29
  write_to_pcf8574(nibble);
30
  
31
  //...then the low nibble
32
  nibble = mask | (data & 0x0F);
33
  write_to_pcf8574(nibble);
34
}
35
36
void write_command(char data)
37
{
38
  write_byte(data, COMMAND_MASK);
39
}
40
41
void write_data(char data)
42
{
43
  write_byte(data, DATA_MASK);
44
}
45
46
void write_string(char* string)
47
{
48
  while (*string)
49
  {
50
    write_data(*string);
51
    *string++;
52
  }
53
}
54
55
void init_display()
56
{
57
  //turn on 4 bit mode
58
  write_to_pcf8574(INIT_4BIT_MODE);
59
  
60
  write_command(0x28);
61
  _delay_ms(50);
62
  write_command(0x0c);
63
  _delay_ms(50);
64
  write_command(0x06);
65
  _delay_ms(50);
66
  write_command(0x01);
67
  _delay_ms(50);
68
  write_command(0x0f);
69
  _delay_ms(50);
70
}
71
72
int main()
73
{
74
  i2c_init();
75
  i2c_start_wait(LCD_I2C_ADDRESS + I2C_WRITE);
76
  init_display();
77
  write_string("Hello World");
78
  i2c_stop();
79
80
  return 0;
81
}
damit bekomme ich einen blinkenden Strich oben links. Die beiden Datein 
vom i2clcd habe ich auch mit reingestellt. Diese unterscheiden sich zu 
meinen vorher genutzten Datein. Nach dem anderen Hinweis habe ich RS und 
EN (P4 und P7) getauscht. In der Datei i2clcd.h die Angaben geändert 
Leider ohne Erfolg bzw, das gleiche.
Was mache ich wieder falsch?
achim

von Georg G. (df2au)


Lesenswert?

Achim Seeger schrieb:
> Was mache ich wieder falsch?

Du hast das Schaltbild vergessen.

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

Sorry, hab ich vberschlafen, kommt sofort

von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

>    Schaltbild_Poll.docx (50 KB, 1 Downloads)

>Sorry, hab ich vberschlafen, kommt sofort

In der Tat, du hast das Thema Bildformate verschlafen.

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

noch mal anders

von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

>   Bild_Poll.png
>    100 KB, 1 Downloads

>noch mal anders

Immer noch Mist. Wie schafft man es, so einen verwaschenen Screenshot zu 
machen?

von Max H. (hartl192)


Lesenswert?

Falk Brunner schrieb:
> Wie schafft man es, so einen verwaschenen Screenshot zu
> machen?
Indem man ein verwaschenes Original nimmt

von Achim S. (achims)


Angehängte Dateien:

Lesenswert?

noch mal

von Achim S. (achims)


Lesenswert?

Nach der Schaltung des Herstellers ist die Belegung:

i2clcd.h      LCD
P0 - DB 4 -   11
P1 - DB 5 -   12
P2 - DB 6 -   13
P3 - DB 7 -   14
P4 - RS   -   4
P5 - R/W  -   5
P6 -
P7 - E -      6

von Georg G. (df2au)


Lesenswert?

Gängige Displays haben den E Anschluss an Pin 6. Wenn du das i2clcd.h so 
verwendet hast, wie du es gepostet hast, hast du es aber richtig und nur 
dein Beitrag von 18:30 ist falsch.

Und lass bei Gelegenheit die Masseverbindungen an 7-8-9-10 des Displays 
weg. Sie müssen nicht stören, sind aber überflüssig.

von Achim S. (achims)


Lesenswert?

Werde das mit 6 überprüfen. Von der Bauart kann ich 7,8,9,10 nicht frei 
lassen, sind als Lötstützpunkte ausgeführt.
Habe mir die Anleitung vom Display genommen, da ist was, muss es testen.
achim

von Achim S. (achims)


Lesenswert?

E ist auf 6
Es gibt in dem Vorspann zu der h die Angabe P7 - E aber bei der define 
steht Pin 6 auf E

von Achim S. (achims)


Lesenswert?

Daran lag es nicht. Hab leider keine Idee mehr dazu. Hat jemand ein 
Stück Code das läuft?
Vielleicht kann mir jemand damit weiterhelfen
achim

von Uwe (Gast)


Lesenswert?

Achim Seeger schrieb:
> damit bekomme ich einen blinkenden Strich oben links.
Kannst Du mal ein Foto davon (und von Deinem Aufbau) machen?

von i2c von Pollin (Gast)


Lesenswert?

das ist der Schaltplan von dem Pollin Adapter

von i2c von Pollin (Gast)


Lesenswert?

#define LCD_EMPTY_PIN 7
 #define LCD_E_PIN 6

von Achim S. (achims)


Lesenswert?

Ja, das ist der Schaltplan des Pollin Adapter.
Es blinkt das erste Zeichen oben links, abwechselnd  ein Strich unten 
oder das volle Quadrat (5x7). Der Aufbau entspricht genau dem Bild auf 
der Beschreibung von Pollin.
Sorry, was du da schreibst

i2c von Pollin schrieb:
> #define LCD_EMPTY_PIN 7
>  #define LCD_E_PIN 6

verstehe ich nicht. Muss ich da was ändern oder ..?
achim

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.