LCD gibt keine Werte in der Loop Schleife aus

Hallo,

habe ein LCD 162C LED von reichelt.

Verwendeter Kontroller:

KS0066U

Habe das Beispiel Programm hier aus dem Forum schon aufgespielt und das funktioniert.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}
void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
}

Nun wollte ich gerne eine Ausgabe in der void loop () programmieren.

Wenn ich dort eine Ausgabe vornehme, wird am Display nichts mehr angezeigt.

Kann das am Kontroller liegen, dass dies kein HD44780 ist?

Habe auch schon die library mal ausgetauscht.

Ändert nichts.

Anbei mein Code

#include <LiquidCrystal.h>

#include <VirtualWire.h>    // you must download and install the VirtualWire.h to your hardware/libraries folder



#undef int
#undef abs
#undef double
#undef float
#undef round

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
void setup()
{
    lcd.begin(16, 2);
    Serial.begin(9600);    
      
// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(8);           // We will be receiving on pin 4 i.e the RX pin from the module connects to this pin. 
    vw_rx_start();                      // Start the receiver 
}
 
void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    
    // Daten-Variable, die die empfangenen Daten hält
    char SensorDataTemp[VW_MAX_MESSAGE_LEN+1];
    int temperature;
    int humidity;
    
    if (vw_get_message(buf, &buflen)) // check to see if anything has been received
    {
      int i;
       // Message with a good checksum received.
       memset(SensorDataTemp, 0, VW_MAX_MESSAGE_LEN+1); // Das ganze Array mit 0en füllen
        for (i = 0; i < buflen; i++)
      {
          Serial.print((char)buf[i]);                     // the received data is stored in buffer
          SensorDataTemp[i]=(char)buf[i];
       }
    }
   // Char-Variable terminieren
   SensorDataTemp[VW_MAX_MESSAGE_LEN+1] = '\0';

   sscanf(SensorDataTemp, "s=%*d&t=%d&h=%d&v=%*d", &temperature, &humidity);
    
 
   lcd.setCursor(2, 0);
   lcd.print("Temp:");
   lcd.setCursor(8, 0);
   lcd.print(temperature/100);
   lcd.setCursor(12, 0);
   lcd.print("°C");
   lcd.setCursor(0, 1);
   lcd.print("Hum:");
   lcd.setCursor(8, 1);
   lcd.print(humidity/100);
   lcd.setCursor(12, 1);
   lcd.print("%");

   delay(2000);
}

habe folgendes rausgefunden:

Wenn ich den Code

// Initialise the IO and ISR
   /* vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(8);           // We will be receiving on pin 4 i.e the RX pin from the module connects to this pin. 
    vw_rx_start();                    // Start the receiver 
    */

auskommentiere, werden mir die Daten auf dem Display ausgegeben.

Können sich die Funktionen gegenseitig beeinflußen / stören?

Versuch mal einen anderen Pin für den “vw_set_rx_pin”.
Da ich Displays bisher immer mit i2c ansteuer, kenne ich das Problem nicht, aber testen kann man es.
Am Controller liegt es meiner Meinung nach nicht.

Das ändern des PINs bringt nichts.

Habe mal nach und nach die Empfangszeilen auskommentiert.

Als ich vw_setup(2000); auskommentiert habe, hat es funktioniert.

Habe dann mal die Anzahl der Bits pro Sekunde bis auf 0 reduziert.

Erst bei 0 hat es funktioniert.

Dann habe ich vw_setup(2000); mal an unterschiedliche Stellen im Code kopiert.

Wenn ich das vw_setup(2000); nach lcd.begin(16,2) kopiere, funktioniert es.
Schon sehr komisch.

Hat jemand eine Erklärung dafür?

void setup()

{

    
   // Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    //vw_setup(2000);               // Bits per sec
    vw_set_rx_pin(8);             // We will be receiving on pin 4 i.e the RX pin from the module connects to this pin. 
    vw_rx_start();                // Start the receiver 

    lcd.begin(16, 2);
    Serial.begin(9600); 
    vw_setup(2000);
    //lcd.begin(16, 2);
  
}

Hardtacker:
Kann das am Kontroller liegen, dass dies kein HD44780 ist?

Wein Dein oben gepostetetes Testprogramm funktioniert, dann wohl kaum.

Sondern dann liegt es eher an Buffer-Overflows wie diesem hier:

    char SensorDataTemp[VW_MAX_MESSAGE_LEN+1];
...
   SensorDataTemp[VW_MAX_MESSAGE_LEN+1] = '\0';

Ein Array, das für eine Anzahl von “VW_MAX_MESSAGE_LEN+1” Array-Elementen deklariert wird, hat als höchsten verfügbaren Array-Index VW_MAX_MESSAGE_LEN, denn alle C-Arrays arbeiten mit einem nullbasierten Index.

Mit dem Code

SensorDataTemp[VW_MAX_MESSAGE_LEN+1] = '\0';

schreibst Du also genau ein Zeichen AUSSERHALB des deklarierten Arrays “irgendwo ins RAM”, wo womöglich eine andere wichtige Variable mit einer Null überschrieben wird.

Hallo,

was für eine “VirtualWire” verwendest du?
Ich vermute, dass die schon recht alt ist und das Problem verursacht.

Bei mir sieht es in der Loop so aus, teste es mal.
in “StringReceived” steht der empfangene Wert.

Die Variable “char StringReceived[10];” habe ich global deklariert.

void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)) {
    for (i = 0; i < buflen; i++) {
      StringReceived[i] = char(buf[i]);
    }
    LCD.print(StringReceived);
  }
  memset(StringReceived, 0, sizeof(StringReceived));
  delay(5);
}

Und diese Zeile

vw_set_ptt_inverted(true);    // Required for RX Link Module

brauchst du vermutlich nicht, die ist für einen bestimmten Empfängertyp.

Nur so aus Neugier:

Für was ist das delay(5) ?

ElEspanol:
Nur so aus Neugier:
Für was ist das delay(5) ?

Gute Frage.
Ich kann es leider nicht sagen, da ich das auch so aus einem Beispiel der Library genommen habe und in der Kürze stört es nicht.
Kann evtl. auch entfallen, habe es aber nicht getestet.

Hast du eine Idee?

Naja, wenn du es so übernommen hast, könnte der Schöpfer des Sketches vielleicht gemeint haben, gib dem RAM etwas Zeit, um ein paar Speicherstellen zu schreiben.

Oder kleine Pause, um den Buffer wieder zu füllen.

Aber für all das sind 5 ms sehr lange und vor allem mW unnötig.

Deswegen ja meine Neugier.

Ich werde es an der Stelle, wo ich es entnommen habe, mal nachlesen und auch ohne testen.

Hallo,

@ Jurs:

char SensorDataTemp[VW_MAX_MESSAGE_LEN+1];
...
SensorDataTemp[VW_MAX_MESSAGE_LEN+1] = '\0';

Ich schreibe hier nicht außerhalb des Arrays.

Meine Daten die ich empfangen kann, haben eine maximale Länge von VW_MAX_Message_Len.

Sagen wir mal das der Wert 50 ist. Sprich meine Daten können max 50 Zeichen haben.

Nun definiere ich eine neue Variable SensorDataTemp die 51 Zeichen groß ist ( VW_MAX_Message_Len +1)
Somit ist das ein klar definierter Bereich für die neue Variable und diese kann ich dann auch mit \0 als Zeichenkette beenden.

Oder sehe ich das falsch?

@ HotSystems: Ich denke auch dass das eine Zeitverzögerung ist, um die Daten zu verarbeiten.

Der maximale Index ist VW_MAX_MESSAGE_LEN

z.B. char array[4 + 1] geht von 0-4. 0, 1, 2, 3, 4 = 5 Einträge

Hardtacker:
@ HotSystems: Ich denke auch dass das eine Zeitverzögerung ist, um die Daten zu verarbeiten.

Zwischenzeitlich habe ich es getestet und das delay kann ich auch weglassen.

Hast du denn den Code, so wie ich ihn gepostet habe, mal eingesetzt, der funktioniert bei mir so hervorragend. Die Länge des zu übertragenden Textes legst du in der globalen Variable fest.

Werde morgen deinen Code testen.

Melde mich dann wieder.

@ Hotsystems:

Habe mal deinen Code eingefügt für den Empfänger.

Musste deinen Code leicht modifizieren, da er LCD.print nicht kannt.

Der Code sieht wie folgt aus:

#include <VirtualWire.h>    // you must download and install the VirtualWire.h to your hardware/libraries folder
#include <LiquidCrystal.h>

#undef int
#undef abs
#undef double
#undef float
#undef round

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

char StringReceived[10];
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
   
   // Daten-Variable, die die empfangenen Daten hält
char SensorDataTemp[VW_MAX_MESSAGE_LEN+1];
int temperature;
int humidity;
 
void setup()
{

   
  // Initialise the IO and ISR
   vw_set_ptt_inverted(true);    // Required for RX Link Module
   //vw_setup(2000);               // Bits per sec
   vw_set_rx_pin(8);             // We will be receiving on pin 4 i.e the RX pin from the module connects to this pin. 
   vw_rx_start();                // Start the receiver 

   lcd.begin(16, 2);
   Serial.begin(9600); 
   vw_setup(2000);
   //lcd.begin(16, 2);
 
}

void loop()
{


 if (vw_get_message(buf, &buflen)) {
   int i;
   for (i = 0; i < buflen; i++) {
     StringReceived[i] = char(buf[i]);
   }
   lcd.print(StringReceived);
 }
 memset(StringReceived, 0, sizeof(StringReceived));
 delay(5);
}

Ich nutze die Liberary:

#include <VirtualWire.h>
#include <LiquidCrystal.h>

die mit der IDE 1.6.5 mitgeliefert wird.

Konnte nun dein Programm übersetzen, es wird aber nichts angezeigt.

Gruß,

Hardtacker

Hardtacker:
Habe mal deinen Code eingefügt für den Empfänger.
Musste deinen Code leicht modifizieren, da er LCD.print nicht kannt.

Ich habe ja auch nur die Loop gepostet, das war die Deklaration des LCD nicht drin.

Der Code sieht wie folgt aus:

Und den hast du nicht richtig übernommen.

Ich habe den jetzt nochmal komplett reingesetzt.
Einiges kann raus, was nicht gebraucht wird.

#include <VirtualWire.h>    // you must download and install the VirtualWire.h to your hardware/libraries folder
#include <LiquidCrystal.h>

/*
#undef int
#undef abs
#undef double
#undef float
#undef round
*/

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

char StringReceived[10];

// Daten-Variable, die die empfangenen Daten hält
//char SensorDataTemp[VW_MAX_MESSAGE_LEN + 1];
//int temperature;
//int humidity;


void setup()
{

  // Initialise the IO and ISR
//  vw_set_ptt_inverted(true);    // Required for RX Link Module, wird nur für einen "Transceiver" benötigt.
  //vw_setup(2000);               // Bits per sec
  vw_set_rx_pin(8);             // We will be receiving on pin 4 i.e the RX pin from the module connects to this pin.
  vw_rx_start();                // Start the receiver

  lcd.begin(16, 2);
  Serial.begin(9600);
  vw_setup(2000);
  //lcd.begin(16, 2);

}

void loop()
{

  uint8_t buf[VW_MAX_MESSAGE_LEN];            // diese Zeilen müssen in die Loop
  uint8_t buflen = VW_MAX_MESSAGE_LEN;        // diese Zeilen müssen in die Loop

  if (vw_get_message(buf, &buflen)) {
    int i;
    for (i = 0; i < buflen; i++) {
      StringReceived[i] = char(buf[i]);
    }
    lcd.print(StringReceived);
    
    Serial.println(StringReceived);           // Anzeig im Monitor, prüfe mal ob was angezeigt wird.
    
  }
  memset(StringReceived, 0, sizeof(StringReceived));
  //delay(5);
}

Ich nutze die Liberary:

#include <VirtualWire.h>
#include <LiquidCrystal.h>

die mit der IDE 1.6.5 mitgeliefert wird.

Das ist soweit ok.

Konnte nun dein Programm übersetzen, es wird aber nichts angezeigt.

Das kann ich mir aktuell nicht erklären.

Bei mir funktioniert der Code so, nur dass ich ein I2C-LCD einsetze, das macht aber kein unterschied, was die Funktion betrifft.

Läuft denn dein Sender und sendet der auch was richtiges?

vw_set_ptt_inverted(true); // Required for RX Link Module
//vw_setup(2000); // Bits per sec
vw_set_rx_pin(8); // We will be receiving on pin 4 i.e the RX pin from the module connects to this pin.
vw_rx_start(); // Start the receiver

du solltest lieber die erste statt der zweiten Zeile auskommentieren

ardubu:
du solltest lieber die erste statt der zweiten Zeile auskommentieren

Versteh ich nicht.

vw_set_ptt_inverted(true);

Die wird nur bei einem Transceiver (Sender/Empfänger) benötigt.
//Required for DR3100
Soweit mir bekannt ist, benutzt der TO nur einen Empfänger.

Die wird nur bei einem Transceiver (Sender/Empfänger) benötigt.
Soweit mir bekannt ist, benutzt der TO nur einen Empfänger.

eben drum.

vw_set_ptt_inverted(true);

benötigt er nicht

//vw_setup(2000);

aber schon

Ok, dann hab ich dich falsch verstanden, sorry.

Die Zeile hat er aber weiter unten drin stehen. Also das ist ok.