Forum: Mikrocontroller und Digitale Elektronik I2C-LCD von sainsmart - keine Anzeige


von Michael L. (ml-kuen)


Angehängte Dateien:

Lesenswert?

Hallo,

versuche seit einiger Zeit mein serielles Display LCD2004 (PCF8574T + 
2-zeiliges LCD) von sainsmart mit AVR-Studio 4 und den Quellen von Peter 
Fleury (http://homepage.hispeed.ch/peterfleury/avr-software.html) zum 
leuchten zu bringen.
Nach dem ersten Fehlversuch habe ich meinen Uno mal mit dem 
I2clcd-Beispiel des Arduino ausprobiert. Da funktioniert das Display 
einwandfrei.
Ich wollte dadurch feststellen, ob die Adresse (0x27) richtig ist.

In AS4 habe ich beide Varianten (twimaster und i2cmaster) ausprobiert 
und das hex-File jeweils mit meinem AVRISP-mkII und Burn-O-Mat geflasht. 
Mit dem AS-Debugger habe ich noch kontrolliert, ob bei der 
I2C-Softwarevariante die richtigen I/O-Ports angesprochen werden. Auch 
andere Ports habe ich schon verwendet. Im Debugger sah das alles recht 
gut aus.

Das Testprogramm ist eine Kopie aus dem Inet:
1
#include <stdbool.h>
2
#include <stdint.h> 
3
#include <avr/pgmspace.h>
4
#include "main.h"
5
#include <util/delay.h>
6
#include "i2clcd.h"
7
#include "i2cmaster.h"
8
9
char string_flash[] PROGMEM = "Hello Flash!";
10
11
int main(void)
12
{
13
  char string1[] = "Hello World!";
14
15
  i2c_init();
16
  lcd_init();
17
18
    lcd_light(true);
19
  lcd_print(string1);
20
  lcd_nextline();
21
    lcd_print_P(PSTR("I2CLCD V0.11"));
22
23
    // always set all three parameters  (ON/OFF) when using this command
24
  lcd_command(LCD_DISPLAYON | LCD_CURSORON | LCD_BLINKINGON);
25
    _delay_ms(1000);
26
27
    lcd_command(LCD_CLEAR);
28
    _delay_ms(2);
29
    lcd_print_P(string_flash);
30
    lcd_printlc_P(2, 2, string_flash);
31
32
    //-  Endless loop
33
  
34
    while (1) {
35
    
36
    }
37
}

Hat jemand eine Idee, woran es liegen könnte?
..hänge noch das Projekt mit dran.

Gruß

von Michael L. (ml-kuen)


Lesenswert?

Ja ok, habe verstanden. Wenn niemand mit mir reden möchte, dennoch einen 
Status meinerseits.
Ich hatte vergessen die Pullups anzuschließen. Wie groß müssen die 
eigentlich sein? Ich habe mal 1,6k genommen. Ausserdem habe ich meinen 
Logic-Sniffer ausgegraben und das Protokoll analysiert, denn das Display 
wird nun zwar initialisiert und zeigt ein einheitliches blau ohne die 
Rechtecke in der ersten Zeile, aber Zeichen werden nicht ausgegeben. Das 
geht auch aus den Analyserdaten hervor. Da wiederholen sich die Codes 
Start, Adresse (0x27), NACK und Stop. Daten und ACK sind nirgendwo zu 
sehen. Und das ist nun mein zweites Problem.

Gruß

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

die Pullups können auch mehrere Kiloohm sein, falls der I2C-Takt nicht 
zu hoch ist.

Der PCF scheint sich nicht angesprochen zu fühlen. Gernaueres zu den 
Einstellungen der Adresse steht im Datenblatt.

MfG

: Bearbeitet durch User
von Michael L. (ml-kuen)


Lesenswert?

Wie schon oben erwähnt, funktioniert das Display an den TWI-Ports mit 
der selben Adresse unter Arduino einwandfrei. Die Abschlußwiederstände 
wurden bei TWI vermutlich nicht benötigt, weil die Ports das intern 
erledigen.
Die Adressbits am PCF8574T (NXP/Philips) habe ich geprüft und das 
Datenblatt bestätigt mir auch die eingetragene Hardwareadresse 27h.

Auszug:
1
Pin conn.  |                        |Addr. of PCF8574|
2
A0  A1  A2 |A6 A5 A4 A3 A2 A1 A0 RW |Write  |  Read  |7-Bit Hex without RW
3
--------------------------------------------------------------------------
4
VDD VDD VDD| 0  1  0  0  1  1  1  - |  4Eh  |   4Fh  |                 27h

Komisch, dass dort wieder mit read/write-Adressen gehandelt wird wo doch 
eigentlich klar ist, dass das R/W-Bit nicht zur Adresse gehört. TI sieht 
dass allerdings anders. Na ja - sicherheitshalber habe ich es auch schon 
mit 4E probiert - ohne Erfolg.

Irgend etwas muss an den Ports allerdings schon passieren, da sich wie 
beschrieben die Anzeige anders verhält als ohne Ansteuerung. Nur an den 
Abschlusswiederständen wird es wohl nicht liegen. Ich denke, ich muss 
noch ein bischen sniffen. Die Portbelegung vom PCF zum LCD stimmt 
zumindest - habe ich durchgepiepst!

Gruß - und Danke für deinen Kommentar!

: Bearbeitet durch User
von Michael L. (ml-kuen)


Lesenswert?

Na dass war 'ne Geburt. Habe die Probleme nun beseitigen können.

Punkt 1:
Die Lib von Peter Fleury arbeitet mit der 8-Bit I2C-Adresse, So dass ich 
meine gesniffte Adresse 0x27 einmal nach links schieben musste. Dadurch 
erhält man 0x4E, die Adresse mit der es funktioniert.

Punkt 2:
Hatte die Spannungsversorgung des Displays irrtümlicherweise auf dem 
Arduino neben den 5V-Pin an 3,3V angeschlossen. Muss wohl doch mal zum 
Optiker :-( Dadurch auch die komische Anzeige, von der ich berichtete.
Übrigens taten der PCF8574 und der Display-Controller auch bei 3,3V 
ihren Job, nur konnte man den Kontrast nicht mehr weit genug aufdrehen. 
Das da schon "was ging" konnte ich ja mit meinem I2C-Sniffer erkennen.

Erkenntniss aus dieser Episode: In Zukunft sorgfältiger arbeiten!

Michael L.

von M. K. (sylaina)


Lesenswert?

Michael L. schrieb:
> Die Abschlußwiederstände
> wurden bei TWI vermutlich nicht benötigt, weil die Ports das intern
> erledigen.

Die sind auch bei TWI nötig, merkt man in der Regel wenn man mehr als 
nur ein Display am I2C hat.
Die Größe der Pullups ist aber zu berechnen. Für eine Busgeschwindigkeit 
≤ 100 kHz gilt

und für eine Busgeschwindigkeit > 100 kHz

Oft kann man sich aber, wenn man nur das Display am TWI betreibt, die 
Pullups sparen ;)

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

Du hast die Methode des genaueren Hinsehens angewandt und warst damit 
erfolgreich! Wie die Adressangabe gemeint ist, ist nicht immer 
eindeutig.

Wenn nur ein Busteilnehmer dran hängt, kann man auch alle Adressen 
durchzahlen lassen und schauen, bei welcher Ack als Antwort kommt. Das 
Ack meldet entweder das Programm oder man sieht es auf dem 
Oszilloskopbild.

Mit freundlichem Gruß

von Kurt (kurtcontroller)


Lesenswert?

Hallo Michael,

ich habe dieses Modul.
http://www.ehajo.de/baus%C3%A4tze/bedrahtete-baus%C3%A4tze/i%C2%B2ci2ctwi-lcd-adapter-arduino-kompatibel.html

Arduino funktioniert mit I2C-Addr = 3F.

Es muss für eigene Anwendung mit AtmelBoard's auf I2C-Addr = 7Eh 
geändert werden.

Getestet habe ich Atmega8 und I2C Lib von Peter Fleury. Es funktioniert.

Gruß
Kurt

: Bearbeitet durch User
von Michael L. (ml-kuen)


Lesenswert?

Danke an alle für die Hinweise!

die Formeln kann ich gut gebrauchen um es "perfekt" zu machen. Nur 
braucht man dazu auch die Kapazität der Busleitung. Die lässt sich 
vermutlich je nach Länge und anderen Gegebenheiten gut abschätzen. 
Zumindest bekommt man schon mal einen Richtwert für die Pullups auch 
wenn der Bus bei mir sehr kurz ist. Mit meinen angesetzten 1,6 kOhm lag 
ich da garnicht so verkehrt. Aus der Formel für den kleinsten Wert 
errechnet man bei 100 kHz etwa 1,53 kOhm. Vorausgesetzt die 
resultierende Einheit ist kOhm. Aber welche Einheit muss ich denn für 
die Buskapazität benutzen?

Gruß
Michael

von aSma>> (Gast)


Lesenswert?

Servus,
wie du schon gemerkt hast, hat der i2c Bus ein paar Spezifikationen 
eingeführt wie, max. Stromfluß und max. Buskapazität usw.

Jedes Kabel/Leiterbahn hat eine bestimme Kapazität pro Länge. Dafür gibt 
es einfach Faustformeln bzw. Datenblätter. Weiterhin besitzt jeder 
Busteilnehmer auch eine Eingangkapazität (Datenblatt)...

Als Faustformel sagt man 100khz 10k und 400khz 4,7k. Bei kurzen Kabel 
(<20cm) und wenig Busteilnehmer. Um konkrete Aussagen machen zu können 
brauchst ein Oszilloskop.

von Bus Fan (Gast)


Lesenswert?

Abstand im Bus - ist ein Problem. Man kann auch ein Problem draus 
machen. Mein Bus geht ohne Probleme bis ca. 3 bis 5m. Nehme ich 
zusätzliche IC Treiber geht es bis ca 30m unnd in der grossen Version 
bis ca. 300m. Als Widerstände benutze ich meistens 4,7k.

von Joachim B. (jar)


Lesenswert?

Michael L. schrieb:
> Danke an alle für die Hinweise!
>
> die Formeln kann ich gut gebrauchen um es "perfekt" zu machen

ja die doofe beiderseitige Adressbetrachtung nervt, aber ich habe meinen 
Frieden gemacht durch shifts

mal andere Formeln

ich verwende immer
1
#if (ARDUINO>0)
2
  DEBUG_PRINTLN(F(" -> Scanning..."));
3
4
  byte error, address;
5
  int nDevices=0;
6
  for(address = 1; address < 127; address++ ) 
7
  { // The i2c_scanner uses the return value of
8
    // the Write.endTransmisstion to see if
9
    // a device did acknowledge to the address.
10
    Wire.beginTransmission(address);
11
    error = Wire.endTransmission();
12
13
    if (error == 0)
14
    { DEBUG_PRINT(F("I2C device found at address 0x"));
15
      if (address<16) 
16
        DEBUG_PRINT(F("0"));
17
      DEBUG_PRINT_DEC_HEX(address,HEX);
18
      DEBUG_PRINT(F("; "));
19
      if (address<64) 
20
        DEBUG_PRINT(F("0"));
21
      DEBUG_PRINT_DEC_HEX(address,BIN);
22
      DEBUG_PRINT(F("x; << 0x"));
23
      DEBUG_PRINT_DEC_HEX((address<<1),HEX);
24
      DEBUG_PRINT(F("; "));
25
      if ((address<<1)<128) 
26
        DEBUG_PRINT(F("0"));
27
      DEBUG_PRINT_DEC_HEX((address<<1),BIN);
28
      
29
      switch(address<<1)
30
      { 
31
        case 0x40:
32
          i2c_test_flags|=(1<<I2C_TASTATUR_8574);
33
          _i2c_key=' ';
34
          DEBUG_PRINTLN(F(" PCF8574  Tastatur"));
35
          break;
36
        case 0x70:
37
          i2c_test_flags|=(1<<I2C_TASTATUR_8574A);
38
          _i2c_key='A';
39
          DEBUG_PRINTLN(F(" PCF8574A Tastatur"));
40
          break;
41
        case 0x78:
42
          DEBUG_PRINTLN(F(" I2C OLED         "));
43
          break;
44
        case 0xA0:
45
          DEBUG_PRINTLN(F(" I2C EEPROM       "));
46
          i2c_test_flags|=(1<<I2C_EEPROM);          
47
          break;
48
        case 0xD0:
49
          Wire.beginTransmission(DS1307_ID);
50
          printIIC(0x3F);
51
          (Wire.endTransmission()) ? i2c_test_flags|=(1<<I2C_RTC_3231) : i2c_test_flags|=(1<<I2C_RTC_1307);
52
          #ifdef DEBUG
53
          (i2c_test_flags&(1<<I2C_RTC_3231)) ? Serial.println(F(" DS3231 RTC ")) : Serial.println(F(" DS1307 RTC "));
54
          #endif
55
          break;
56
        default:
57
          DEBUG_PRINTLN(F(""));
58
          break;
59
      }
60
      nDevices++;
61
    }
62
    else if (error==4) 
63
    { DEBUG_PRINT(F("Unknow error at address 0x"));
64
      if (address<16) 
65
        DEBUG_PRINT(F("0"));
66
      DEBUG_PRINTLN_DEC_HEX(address,HEX);
67
    }    
68
  }
69
  if (nDevices == 0)
70
    DEBUG_PRINTLN(F("No I2C devices found"));
71
  else
72
    DEBUG_PRINTLN(F("done"));
73
  DEBUG_PRINTLN(F(""));
74
#else
75
  // hier könnte die fleury LIB für AVR Studio rein
76
#endif // #if (ARDUINO>0)

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.