[erledigt] LCD (20x4) ändert nach einiger Zeit eigenes Zeichen

Hallo Gemeinde,

in einem Projekt (Atmega328-StandAllone) verwende ich das LCD 2004 mit dem Chipsatz HD44780 und I2C Ansteuerung.
Die normale Anzeige (Text und Daten) funktioniert fehlerfrei.

Da ich in dem Projekt Daten per Funk (433 MHz) empfange, habe ich in der Anzeige ein kleines Symbol (Antenne) als eigenes Sonderzeichen erstellt.
Dieses Zeichen soll immer angezeigt werden, wenn der Empfänger Daten empfängt.

Die Deklaration des Symbols:

byte antenne[8] = { B00100, B10101, B01110, B00100, B00100, B00100, B00100, B00000 };

Im Setup:

   lcd.createChar(1, antenne);
void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    int i;
    lcd.setCursor(0, 0);
    lcd.write(byte(1));
    for (i = 0; i < buflen; i++)
    {
      StringReceived[i] = char(buf[i]);
    }
    delay(500);
    lcd.setCursor(0, 0);
    lcd.print(" ");
    lcd.setCursor(0, 2);
    lcd.print("Rec.: ");
    lcd.print(StringReceived);
  }
}

Leider tritt nach einiger Zeit (unterschiedlich, mal Minuten, mal Stunden später) der Fehler auf, dass dieses Symbol der Antenne nicht mehr richtig angezeigt wird.
Statt der Antenne wird (teilweise) der komplette Kasten ausgefüllt, so als ob alle Bytes mit einer "1" gefüllt sind.

Die Anzeige des Symbols ist erst wieder richtig, nachdem ich einen anderen Sketch hochgeladen habe.
Nach erneutem Aufspielen des vorherigen Codes stimmt die Anzeige wieder.
Ein einfacher Reset reicht nicht.
Auch ein ändern der Position hat auf dieses Fehlverhalten keinen Einfluss.

Verwende ich statt des eigenen Symbols ein im LCD vorhandenes Symbol, tritt der Fehler nicht auf.

Wo liegt das Problem oder was mache ich hier falsch?
Danke für eure Tipps.

Edit:
Delay geändert!

Hallo,

entweder überschreibst du in der Zeile das Symbol später mit Datenmüll, dann sollte eigentlich ein Reset reichen, oder die Spannungsversorgung macht Mist oder irgendwo anders gibts einen falschen Befehl der den Displayspeicher an der Stelle überschreibt. Die I2C Verbindung ist stabil und fehlerfrei? Ins blaue hinein übertragen würde ich nicht, machen aber viele.

Hallo,

ich kann mich Doc_Arduino nur anschließen. Ich habe selbst auch schon meine Erfolge mit LCD & I2C mit eigenen Zeichen - und Fehler habe ich bisher keine gehabt. Sogar der Anschluß eines 4x4 Keypad via I2C läßt keine Störungen durchkommen. Ich vermute eher, dass aus irgend einer Ecke der diversen LIBs (oder eigenen Programmteilen) irgendwie irgendwo eine Umdefinition der Bytes für das Sonderzeichen stattfindet - und übertragen wird. Bei Funk-Sachen bin jedoch immer hellwach. Kennst du den Spruch "Hochfrequenz geht seltsame Wege"? Besonders aus diesem Bereich kann ich mir vorstellen, dass irgendwelche unerwünschten Nebenwirkungen in deine I2C-Verdrahtung einfließen. Aber wie gesagt - alles nur Vermutungen.

Gruß, Rudi

Nachsatz...
Keine Ahnung ob das irgendwelche Auswirkungen hat: An anderer Stelle im Forum hat man mir beigebracht, dass man den "Cast" anders schreibt, nämlich >> lcd.write( (byte)1 ) an Stelle von lcd.write( byte(1) )
Als zustätzliche "Spielerei" würde ich mal versuchen, auch ein anderes Zeichen (z.B. Speicherstelle 0 oder 2) zu benutzen. Nur so als eventuelle Eingrenzung des Fehlers...

Danke für eure Antworten.

Doc_Arduino:
entweder überschreibst du in der Zeile das Symbol später mit Datenmüll, dann sollte eigentlich ein Reset reichen, oder die Spannungsversorgung macht Mist oder irgendwo anders gibts einen falschen Befehl der den Displayspeicher an der Stelle überschreibt.

Nein, die Zeile wird an keiner anderen Stelle beschrieben.

Die I2C Verbindung ist stabil und fehlerfrei? Ins blaue hinein übertragen würde ich nicht, machen aber viele.

Ja, I2C ist stabil. mit Pullups versehen und die Leitung hat nur eine Länge von ca. 10 cm.

Was meinst du mit "Ins blaue hinein übertragen würde ich nicht, machen aber viele."?

RudiDL5:
ich kann mich Doc_Arduino nur anschließen. Ich habe selbst auch schon meine Erfolge mit LCD & I2C mit eigenen Zeichen - und Fehler habe ich bisher keine gehabt. Sogar der Anschluß eines 4x4 Keypad via I2C läßt keine Störungen durchkommen. Ich vermute eher, dass aus irgend einer Ecke der diversen LIBs (oder eigenen Programmteilen) irgendwie irgendwo eine Umdefinition der Bytes für das Sonderzeichen stattfindet - und übertragen wird.

Mit I2C hatte ich bisher nie Probleme und das Display funktioniert sonst ja prima. Was die Libs betrifft, die setzte ich in dieser Kombination (Wire, LiquidCrystal_I2C, RCSwitch und VirtualWire) auch in anderen Projekten problemlos ein. Auch da arbeite ich mit selbst definierten Zeichen.

Bei Funk-Sachen bin jedoch immer hellwach. Kennst du den Spruch "Hochfrequenz geht seltsame Wege"? Besonders aus diesem Bereich kann ich mir vorstellen, dass irgendwelche unerwünschten Nebenwirkungen in deine I2C-Verdrahtung einfließen. Aber wie gesagt - alles nur Vermutungen.

Ein Funkproblem kann ich hier def. ausschließen. Es ist hier nur ein Empfänger verbaut, der die Signale alle fehlerfrei empfängt. Das zusätzliche Symbol wird ja hier erst erzeugt und angezeigt.

Keine Ahnung ob das irgendwelche Auswirkungen hat: An anderer Stelle im Forum hat man mir beigebracht, dass man den "Cast" anders schreibt, nämlich >> lcd.write( (byte)1 ) an Stelle von lcd.write( byte(1) )

Ich glaube zwar nicht, werde es aber testen.

Als zustätzliche "Spielerei" würde ich mal versuchen, auch ein anderes Zeichen (z.B. Speicherstelle 0 oder 2) zu benutzen. Nur so als eventuelle Eingrenzung des Fehlers...

Auch dieses werde ich probieren, kann ja parallel laufen. Platz ist vorhanden.

Danke nochmal für die Ideen.

   delay(100);

lcd.setCursor(0, 0);
   lcd.print(" ");

Musst du schnell gucken, dass du dein Symbol vorher noch siehst.

michael_x:
Musst du schnell gucken, dass du dein Symbol vorher noch siehst.

Das stimmt, habe beim übertragen einen Fehler reingebracht.

Soll "delay(500);" sein.

Aber so schlecht sind meine Augen noch nicht, auch mit 100 ms sieht man es nocht. :wink:

if (vw_get_message(buf, &buflen)) // Non-blocking   >>> !!!
  { 
    ...
    for (i = 0; i < buflen; i++)
    { StringReceived[i] = char(buf[i]); }
    delay(500);                                     <<< ???
    ...
  }
}

pfui ...
:wink:

Hallo,

Edit Fehler behoben. Na toll. Und wo war nun der Fehler?

Ich prüfe zumindestens beim I2C Zugriff auf die Register ob alles okay war.

bool write_RTC_DS3231_Register (int i2c_adresse, byte register_number, byte register_byte)
// Register beschreiben in der RTC
{
  bool error = false;                     // Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse);
  Wire.write(register_number);            // setzen auf Registernummer bzw. dort wo es losgehen soll
  Wire.write(decToBcd(register_byte));    // Byte in Register schreiben
  if (Wire.endTransmission() > 0 )  {  
    error = true;                         // I2C Busfehler
  } 
  return error;                           // return mit Status
}

Ok..ok.

Das Projekt ist nur dazu da, meine Funkdaten zu lesen und anzuzeigen.
Also ein Scanner zum prüfen meiner eigenen Projekte.

Hier ist ein "delay(500)" unkritisch, die Loop macht nix anderes als zu warten, bis etwas empfangen wird und das angezeigt wird.

Daher lass ich es auch drin. :slight_smile:

Der eigentliche Fehler ist leider noch vorhanden.

Ich hatte zuvor nur ein zu kleines "delay" im Sketch eingetragen.
Diesen Fehler habe ich beseitigt.

RudiDL5:
Keine Ahnung ob das irgendwelche Auswirkungen hat: An anderer Stelle im Forum hat man mir beigebracht, dass man den "Cast" anders schreibt
...

Es geht so oder so. Aber byte(1) sieht in C++ für die meisten Leute zu sehr nach einem Konstruktor aus. Bei den Klammern um den Datentyp sieht man sofort dass es ein Cast ist. Anders ist es einfach sehr schlecht lesbar.

Wobei heute meistens sowieso davon abgeraten wird überhaupt C Casts zu verwenden and statt dessen zu den C++ Casts wie static_cast zu greifen. Andererseits wird in der Arduino Welt viel häufiger als normal gecastet. Dadurch haben C Casts ihre Berechtigung.

Es geht so oder so. Aber byte(1) sieht in C++ für die meisten Leute zu sehr nach einem Konstruktor aus. Bei den Klammern um den Datentyp sieht man sofort dass es ein Cast ist

Aha, okay - na ja, als "C-Neuling" muss ich mich halt an das eine oder andere gewöhnen. Wie auch immer - ich kenne die recht harte Typen-Genauigkeit aus vielen Jahren Objekt-Pascal genau so, wie die (manchmal fatale) Typenfreiheit aus PHP oder sogar "Clipper"... Man(n) lernt halt nie aus und ich für mich überlege oftmals einmal mehr, welche Typen irgendwo verwendet werden sollen oder müssen - bevor ich mir selbst ins Knie schieße :slight_smile:

Ja, C ist irgendwo dazwischen. Das hat sowohl Vorteile als auch Nachteile. Manche Dinge werden einfacher und es ermöglicht nette Tricks, aber man kann auch großen Unsinn damit machen.

statt cast kannst du auch sowas verwenden

const char ANTENNE = 1;

lcd.write(ANTENNE);

// Alternativ das Zeichen in einem String
lcd.write("\x01 ");  // hex Code
lcd.write("\001 ");  // oder jede oktal-Zahl möglich

Hallo,

vielen Dank für eure Tipps.
Ich habe die jetzt mal umgesetzt und muss abwarten, was passiert.
Ein "cast" gelassen und eins als "hex Code" eingesetzt.

Also das "delay" habe ich drin gelassen, da dies hier absolut nicht stört.

... sollte auch nur 'n kleiner Joke sein :wink:

Daumendrück dass du deinen Zeichenfehler findest. Dennoch bin ich bei HF-Sachen wachsamer als üblich. Auch im UHF-Band können bei schlecht abgeschirmten Empfängern oder ungünstigen Verdrahtungen wilde Schwingungen durch ZF-Oszillatoren auftreten. Ich hoffe ich lese vom Erfolgserlebnis.

Gruß, Rudi

RudiDL5:
... sollte auch nur 'n kleiner Joke sein :wink:

Daumendrück dass du deinen Zeichenfehler findest. Dennoch bin ich bei HF-Sachen wachsamer als üblich. Auch im UHF-Band können bei schlecht abgeschirmten Empfängern oder ungünstigen Verdrahtungen wilde Schwingungen durch ZF-Oszillatoren auftreten. Ich hoffe ich lese vom Erfolgserlebnis.

Ja...ok und danke.
Ich hasse auch die delays, nur wo es absolut nicht nötig ist, lass ich die drin.

Was HF betrifft, habe ich jahrelange Erfahrung (Hobby und Beruf) und kann wirklich sagen, das ist hier nicht das Problem.

Aktuell lass ich mir gleichzeitig 2 eigene und ein originales Symbol anzeigen und seit einigen Stunden keine Aussetzer.

Ich fand es nur merkwürdig, weil ich solchen Fehler bisher nicht kannte und mit anderen Displays dieser auch auftrat.

Ich werde berichten.

Okay. Na ja, HF-Merkwürdigkeiten kenne ich aus dem Amateurfunk, da haben wir schon die übelsten Dinge erlebt.

... und mit anderen Displays dieser auch auftrat.

Oups, das fühlt sich ja fast so an wie mein winziges Kupfer-Krümelchen letztens auf meinem LCD-Streifenraster-Shield... Da habe ich fast in die Tischkante beißen können :smiley:

Da bin ich jetzt aber besonders gespannt wie diese Sache ausgeht!

lcd.write(byte(1));

schreibe ich so:

lcd.print(char(f));

und definiert wird:

byte ant[8] = {
  B11011,
  B11111,
  B11111,
  B01010,
  B01010,
  B11111,
  B11111,
  B11011 };

Dann noch ins Display geschickt:

lcd.createChar(f, ant);

Da alles ratlos scheint kannste das ja mal ausprobieren.

schreibe ich so:

lcd.print(char(f));

und warum schreibst du nicht

char f = 1; // eventuell sogar const char ;)

Irgendwie musst du[b] f [/b]doch sowieso definieren und initialiseren.
Warum nicht gleich richtig, damit du dir das cast sparen kannst ?