LCD am I2C Bus

OP #3575682
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
OP #3575724
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
OP #3575907
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
OP #3576113
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
Gast #3576121
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.
OP #3576146
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
#3576182
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.
Gast #3576183
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?
#3576190
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
OP #3576369
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
OP #3576455
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
Angehängte Dateien:
#3576472
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.
OP #3576553
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
Angehängte Dateien:
#3576565
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.
OP #3576873
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
Angehängte Dateien:
#3577180
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.
OP #3577649
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren