I²C Adapter für 20 x 4 LCD läuft nicht - was tun?

Weil seit Gestern so richtig der Wurm drin ist, wundert es mich nicht, dass das nun auch nicht läuft...

Heute Mittag kam endlich das 20 x 4 Display (ebay 160987231865). Der I²C-Adapter (ebay111071225263) war die Tage schon eingedrudelt. In Problemerwartung habe ich die beiden Komponenten nicht direkt verlötet, sondern eine Buchsenleiste auf das Display gelötet. Das war eine gute Entscheidung, denn ich musste erst mal einige Potistellungen testen, bis der Kontrast stimmte. SCL und SDA sind jeweils über 4,7 K auf 5 V gelegt. SCL geht auf A5 und SDA auf A4. So zumindest habe ich es den Beschreibungen im Netz entnommen. Ein I²C Scan ergab 0x27 als Adresse. Der Adapter antwortet also schon mal. Hintergrundbeleuchtung leuchtet und Kontrast stimmt. Aber der Rest...

Nun habe ich zuerst mal eine Beispieldatei aufspielen wollen.

//DFRobot.com
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display


void setup()
{
  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
}

Das Display geht an und in der ersten Zeile etwa beim 5. Zeichen Blinkt das Zeichen vollflächig im knappen Sekundentakt. Ein Reset ergibt das gleiche Blinken nur an anderer Stelle. Es scheint so, als sei da etwas falsch angeschlossen.

Also habe ich ein wenig im Forum gesucht und auch einige englischsprachige Beiträge gefunden. Aber die haben mir nicht weiter geholfen. Hat jemand eine Idee, wo das Problem liegen könnte?

edit:

Gebe ich das hier von Macherzin ein:

/* LCD-Modul 1602 I2C (http://www.dfrobot.com/index.php)

   Einfaches Beispiel aka "Hello World"
   
   Pinbelegung (Rueckseite des Moduls links nach rechts):
   
   1602 Pin 1 VCC --> Arduino +5V
   1602 Pin 2 GND --> Arduino GND
   1602 Pin 3 SCL --> Arduino Pin analog 5
   1602 Pin 4 SDA --> Arduino Pin analog 4
   
   2012-10-03 Rev. 0.1
   fribbe fuer macherzin.net
 */
 
#include <Wire.h> // binde Bibliothek Wire ein
#include <LiquidCrystal.h> // binde Bibliothek LiquidCrystal_I2C ein

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 2 Zeilen

void setup()
{
  lcd.init(); // initalisiere LCD 
  lcd.backlight(); // Hintergrundbeleuchtung an
  lcd.print("Hello macherzin"); // oder irgend etwas anderes ...
}

void loop()
{
  // diesmal nix zu tun
}

// haben fertig

kommt auch eine Fehlermeldung:

sketch_jul16b.cpp:22:1: error: ‘LiquidCrystal_I2C’ does not name a type
sketch_jul16b.cpp: In function ‘void setup()’:
sketch_jul16b.cpp:26:3: error: ‘lcd’ was not declared in this scope
#include <LiquidCrystal.h> // binde Bibliothek LiquidCrystal_I2C ein

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 2 Zeilen

Ich weiß nicht wie das hier ist, aber normalerweise haben Header und Klasse den gleichen Namen. Ich würde das so lesen, dass LiquidCrystal.h die normale, parallele Lib ist. Da kannst du dann nicht danach versuchen die I2C Klasse zu instantiieren, wenn der Header nicht korrekt eingebunden ist.

Ich verwende diese Lib:
http://www.dfrobot.com/image/data/DFR0154/LiquidCrystal_I2Cv1-1.rar

Und da sieht das so aus wie bei deinem ersten Beispiel:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C _lcd(0x27, 20, 4);

Das Blinken kommt vom Cursor. Das kann man mit blink()/noBlink() an- und ausschalten, und cursor()/noCursor() ist der Unterstrich. Die sollten aber standardmäßig beide deaktiviert sein. Du kannst mal mit setCursor(...) ausprobieren ob die Spalten- und Zeilen Adressen stimmen.

Gelegenheitsbastler:
#include <LiquidCrystal.h> // binde Bibliothek LiquidCrystal_I2C ein

Wenn Du im Code schreibst, dass Du die Library "LiquidCrystal" einbindest und im Kommentar dahinter schreibst, dass Du die "Library LiquidCrystal_I2C" einbinden wolltest, dann passen Code und Kommentar nicht ganz zusammen.

Ein Programm macht immer das, was Du programmierst, und nicht das, was Du kommentierst.

Wenn Du mit einem Array über seine Größe hinausschreibst dann überschreibst Du irgendwelche Variablen die irgend etwas machen oder bedeuten. Da ist es möglich daß darum der DC18B20 oder das I2C Display nicht funktioniert.

Grüße Uwe

Da bin ich ja froh, dass ich die Quelle des falschen Codes sofort mit angegeben habe :wink:

Ich habe es geändert.

/* LCD-Modul 1602 I2C (http://www.dfrobot.com/index.php)

   Einfaches Beispiel aka "Hello World"
   
   Pinbelegung (Rueckseite des Moduls links nach rechts):
   
   1602 Pin 1 VCC --> Arduino +5V
   1602 Pin 2 GND --> Arduino GND
   1602 Pin 3 SCL --> Arduino Pin analog 5
   1602 Pin 4 SDA --> Arduino Pin analog 4
   
   2012-10-03 Rev. 0.1
   fribbe fuer macherzin.net
 */
 
#include <Wire.h> // binde Bibliothek Wire ein
#include <LiquidCrystal_I2C.h> // binde Bibliothek LiquidCrystal_I2C ein

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 2 Zeilen

void setup()
{
  lcd.init(); // initalisiere LCD 
  lcd.backlight(); // Hintergrundbeleuchtung an
  lcd.print("Hello macherzin"); // oder irgend etwas anderes ...
}

void loop()
{
  // diesmal nix zu tun
}

// haben fertig

Nun kommen keine Fehler mehr beim Kompilieren, aber das Display zeigt trotzdem nichts an.

Auch mit der Lib aus dem Link ändert sich daran nichts. Es scheint also etwas anderes zu sein. Kalte Lötstelle schließe ich übrigens aus.

Frank

edit:
@Uwe: Danke für die Info. Das werde ich im Sketch ändern, bzw. alle Ventilatoren anschließen und ansteuern. Soll ja auch in Zukunft so laufen. Ich habe das Display im Moment alleine am Uno hängen. Wenn ich eins inzwischen gelernt habe, dann ist es, jede Komponente für sich zum Laufen zu bringen, bevor man alles zusammen packt. Dann ist die Fehlersuche einfacher.

hallo frank,
schreibe malt im Setup hinter der zeile lcd.init eine zeile lcd.begin(20,4);
gruß
ardubu

Das sieht jetzt so aus:

/* LCD-Modul 1602 I2C (http://www.dfrobot.com/index.php)

   Einfaches Beispiel aka "Hello World"
   
   Pinbelegung (Rueckseite des Moduls links nach rechts):
   
   1602 Pin 1 VCC --> Arduino +5V
   1602 Pin 2 GND --> Arduino GND
   1602 Pin 3 SCL --> Arduino Pin analog 5
   1602 Pin 4 SDA --> Arduino Pin analog 4
   
   2012-10-03 Rev. 0.1
   fribbe fuer macherzin.net
 */
 
#include <Wire.h> // binde Bibliothek Wire ein
#include <LiquidCrystal_I2C.h> // binde Bibliothek LiquidCrystal_I2C ein

LiquidCrystal_I2C lcd(0x27,20,4);  // setze LCD auf 16 Zeichen und 2 Zeilen

void setup()
{
  lcd.init(); // initalisiere LCD 
  lcd.begin(20,4);
  lcd.backlight(); // Hintergrundbeleuchtung an
  lcd.print("Hello macherzin"); // oder irgend etwas anderes ...
}

void loop()
{
  // diesmal nix zu tun
}

// haben fertig

Eine Änderung hat sich nicht ergeben.

begin() ist nicht nötig, da das von init() aufgerufen wird:

void LiquidCrystal_I2C::init(){
	Wire.begin();
	_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
	begin(_cols, _rows);  
}

Hast du mal sowas wie setCursor(3,2) gemacht und geschaut ob du den Cursor setzen kannst?

hallo frank,
am anfang hattest du geschrieben, das die hintergrundbeleuchtung funktioniert und der Kontrast stimmt.
wie konntest du den Kontrast kontrollieren, wenn du auf dem Display nichts siehst?
gruß
ardubu

Es ist nicht so das gar nichts geht. Der Cursor blinkt aus irgendeinem Grund, obwohl er eigentlich aus sein sollte. Deshalb habe ich ja gefragt ob die Spalten- und Zeilenadressierung klappt.

Es mag für Dich eine überflüssige Frage sein: Was sagt Dir, dass dieses Schnittstellen-Board mit der LiquidCrystal_I2C-Bibliothek kompatibel ist? Auf der Ebay-Seite ist nichts davon vermerkt, die Bilder sind mit weggekratzter Chip-Bezeichnung eingestellt, somit ist keinerlei Hinweis vorhanden, mit welchem Protokoll das Ding funktioniert. Bei 2.40 € pro Modul könnte es auch sein, dass nicht einmal ein funktionierender Chip drauf ist.

Nach diesem Forum-Eintrag dürfte es sich bei Deinem Modul um ein Stück Hardware handeln, das nur mit der im Post erwähnten Bibliothek funktioniert und mit den "normalen" Libs nicht zum Laufen zu kriegen ist.

http://forum.arduino.cc/index.php?topic=157817.0

Heureka, das war der zielführende Tip.

Damit läuft es jetzt:

/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 NEW TYPE Marked "Arduino-IIC-LCD GY-LCD-V1"
 terry@yourduino.com */
/*-----( Import needed libraries )-----*/ 
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>  // F Malpartida's NewLiquidCrystal library

/*-----( Declare Constants )-----*/
  // Define I2C Address for the PCF8574A 
//---(Following are the PCF8574 pin assignments to LCD connections )----
// This are different than earlier/different I2C LCD displays
#define BACKLIGHT_PIN  7
#define En_pin  4
#define Rw_pin  5
#define Rs_pin  6
#define D4_pin  0
#define D5_pin  1
#define D6_pin  2
#define D7_pin  3

#define  LED_OFF  0
#define  LED_ON  1

/*-----( Declare objects )-----*/  
LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  lcd.begin (20,4);  // initialize the lcd 
// Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,NEGATIVE);
  lcd.setBacklight(LED_ON);
}// END Setup

void loop()   /*----( LOOP: RUNS OVER AND OVER AGAIN )----*/
{

// Reset the display  
  lcd.clear();
  delay(1000);
  lcd.home();
  
// Print our characters on the LCD
  lcd.backlight();  //Backlight ON if under program control
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print("Hello, world!");
  delay(1000);
  lcd.setCursor(0,1); //Start at character 0 on line 1
  lcd.print("16 by 2 Display");
  delay(8000);
} // END Loop

Wie kann ich denn jetzt noch ein zweites Display ansteuern? Reicht es dafür aus, den Sketch nochmal zu kopieren (nicht die Libs und Loop und delay werden auch beachtet), unten einzufügen und dann die Zeile "#define I2C_ADDR 0x27" auf die Adresse des zweiten Displays anzupassen? Oder ist das zu kurz gedacht?

Frank

Dazu müsstest du die Display-Adresse ändern. Auf der Rückseite sind da drei Lötpunkte (ABC). Wenn man einen davon überbrückt ändert sich die Adresse.

Hier gibts ne Tabelle dazu:
http://www.dfrobot.com/wiki/index.php/I2C/TWI_LCD1602_Module_(SKU:_TOY0046)#Address_Setting

Alle offen ist dann wahrscheinlich HHH, also 0x27. Bei meinem geht das mit Jumpern und da ist es genauso.

Das ist etwas zu kurz gedacht. Du musst ein zweites LCD Objekt erstellen, das die andere Adresse als ersten Parameter mitkriegt.

Das Modul musst Du entsprechend modifizieren, indem Du die Lötbrücken anpasst (ich nehme an, das hast Du bereits herausgefunden).

Nachdem Du das entsprechende I2C_ADDR2 definiert hast, sollte der Code

LiquidCrystal_I2C  lcd2(I2C_ADDR2,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

das neue Objekt erzeugen. Das solltest Du genau wie das erste Initialisieren und kannst dann mit Ausgaben beginnen.

Nein, nur Lötbrücke geht nicht. Du brauchst auch noch einen Draht von VCC.

Man kann die von 20 bis 27 nummerieren.

Hier mal die Adressen:

20:
A0 Lötbrücke
A1 Lötbrücke
A2 Lötbrücke

21:
A0 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.
A1 Lötbrücke
A2 Lötbrücke

22:
A0 Lötbrücke
A1 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.
A2 Lötbrücke

23:
A0 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.
A1 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.
A2 Lötbrücke

24:
A0 Lötbrücke
A1 Lötbrücke
A2 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.

25:
A0 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.
A1 Lötbrücke
A2 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.

26:
A0 Lötbrücke
A1 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.
A2 keine Brücke, Draht von VCC an Kontakt nahe Poti löten.

27:
A0 keine Brücke, kein Draht von VCC.
A1 keine Brücke, kein Draht von VCC.
A2 keine Brücke, kein Draht von VCC.

Gilt aber nur für dieses I2C Modul.

Micky

Sobald ich die Zeit dafür habe, werde ich das testen. Vielen Dank an Micky für die sehr ausführliche Beschreibung. Die wird gleich mal ausgedruckt.

Frank