HD44780 40X4 LCD an Smartie LCD Software betreiben

Servus!

Ich bin neu hier und hoffe ihr könnt mir weiterhelfen. Ich will ein LCD mit 40X4 Zeichen über ein Arduino Nano mit Daten von der Smartie LCD Software (http://lcdsmartie.sourceforge.net/) füttern. Dazu habe ich einen fertigen Sketch gefunden: http://waihung.net/lcd-smartie-through-arduino

Das ganze funktioniert auch ganz gut mit einem 20X2 Zeichen LCD.

Ich habe mir über reichelt folgendes LCD besorgt: LCD 404B BL: LCD-Modul, 4x40, H:4,9mm, bl - ws, m.Bel. bei reichelt elektronik

Wie ich an das verkabeln dran gegangen bin ist mir direkt aufgefallen das ich 2 Enable Pins habe. Nach langer Suche bin ich auf eine modifizierte Lib gestoßen (heisst auch LiquidCrystal.h) --> GitHub - jurs/liquidcrystal440: enhanced arduino liquidcrystal library

In meinem Code werden am Anfang wenn keine serielle Daten kommen alle 4 Zeilen korrekt angezeigt wie in dem Code angegeben. --> LCD ist also richtig verkabelt und funktioniert

Leider habe ich das Problem sobald die Smartie Software läuft wird nur das reinste "Zahlengulasch" angezeigt. Baudrate ist korrekt :wink:

Vielleicht hat ja jemand eine Idee wie ich es zum laufen bekomme. LG

Mein Code sieht folgender Maßen aus:

// include the library code:
#include <LiquidCrystal.h>

// these constants won't change.  But you can change the size of
// your LCD using them:
const int numRows = 40;
const int numCols = 4;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8,11,9,10,4,5,6,7);
// RS, RW, Enable, Enable2, 4,5,6,7 (Refer to the back of your LCD for details)


void setup() { 
  Serial.begin(9600);
  // set up the LCD's number of rows and columns: 
  lcd.begin(numRows, numCols);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("**LCD  SMARTIE**");
  lcd.setCursor(0,1);
  lcd.print("on Arduino");
  lcd.setCursor(0,2);
  lcd.print("Zeile 3 Test");
  lcd.setCursor(0,3);
  lcd.print("Zeile 4 Test");
}

byte serial_getch(){
  
  int incoming;  
  while (Serial.available()==0){}
	// read the incoming byte:
  incoming = Serial.read();

  return (byte) (incoming &0xff);
}

void loop(){

  byte rxbyte;
  byte temp;

  rxbyte = serial_getch();

  if (rxbyte == 254) //Matrix Orbital uses 254 prefix for commands
  {
    switch (serial_getch())
    {
    case 66: //backlight on (at previously set brightness)
      // not implemented				

      break;
    case 70: //backlight off
      // not implemented				
      break;
    case 71:  //set cursor position
      temp = (serial_getch() - 1);  //get column byte
      switch (serial_getch())  //get row byte
      {
        //line 1 is already set up
      case 2:
        temp += 0x40;
        break;
      case 3:
        temp += 0x14;
        break;
      case 4:
        temp += 0x54;
        break;
      default:
        break;
      }
      lcd.command(0b10000000 + temp);
      break;
    case 72:  //cursor home (reset display position)
      lcd.command(2);
      break;
    case 74:  //show underline cursor
      lcd.command(0b00001110);
      break;
    case 75:  //underline cursor off
    case 84:  //block cursor off
      lcd.command(0b00001100);
      break;
    case 76:  //move cursor left
      lcd.command(16);
      break;
    case 77:  //move cursor right
      lcd.command(20);
      break;
    case 78:  //define custom char
      lcd.command(64 + (serial_getch() * 8));  //get+set char address
      for (temp = 7; temp != 0; temp--)
      {
        lcd.print(serial_getch()); //get each pattern byte
      }
      break;
    case 83:  //show blinking block cursor
      lcd.command(0b00001111);
      break;
    case 86:  //GPO OFF
      //implement later
      break;
    case 87:  //GPO ON
      /*temp = serial_getch();
       				if (temp == 1)
       				{
       					GPO1 = GPO_ON;
       				}*/
      break;
    case 88:  //clear display, cursor home
      lcd.command(1);
      break;
    case 152: //set and remember (doesn't save value, though)
    case 153: //set backlight brightness
      //not implemented
      break;

      //these commands ignored (no parameters)
    case 35: //read serial number
    case 36: //read version number
    case 55: //read module type
    case 59: //exit flow-control mode
    case 65: //auto transmit keypresses
    case 96: //auto-repeat mode off (keypad)
    case 67: //auto line-wrap on
    case 68: //auto line-wrap off
    case 81: //auto scroll on
    case 82: //auto scroll off
    case 104: //init horiz bar graph
    case 109: //init med size digits
    case 115: //init narrow vert bar graph
    case 118: //init wide vert bar graph
      break;
    default:
      //all other commands ignored and parameter byte discarded
      temp = serial_getch();  //dump the command code
      break;
    }
    return;
  } //END OF COMMAND HANDLER

  //change accented char to plain, detect and change descenders
  //NB descenders only work on 5x10 displays. This lookup table works
  //  with my DEM-20845 (Display Elektronik GmbH) LCD using KS0066 chip.
  switch (rxbyte)
  {
    //chars that have direct equivalent in LCD charmap
    /*		case 0x67: //g
     			rxbyte = 0xE7;
     			break;
     		case 0x6A: //j
     			rxbyte = 0xEA;
     			break;
     		case 0x70: //p
     			rxbyte = 0xF0;
     			break;
     		case 0x71: //q
     			rxbyte = 0xF1;
     			break;
     		case 0x79: //y
     			rxbyte = 0xF9;
     			break;
     */  case 0xE4: //ASCII "a" umlaut
    rxbyte = 0xE1;
    break;
  case 0xF1: //ASCII "n" tilde
    rxbyte = 0xEE;
    break;
  case 0xF6: //ASCII "o" umlaut
    rxbyte = 0xEF; //was wrong in v0.86
    break;
  case 0xFC: //ASCII "u" umlaut
    rxbyte = 0xF5;
    break;

    //accented -> plain equivalent
    //and misc symbol translation
  case 0xA3: //sterling (pounds)
    rxbyte = 0xED;
    break;
    /*		case 0xB0: //degrees symbol
     			rxbyte = 0xDF;
     			break;
     */  case 0xB5: //mu
    rxbyte = 0xE4;
    break;
  case 0xC0: //"A" variants
  case 0xC1:
  case 0xC2:
  case 0xC3:
  case 0xC4:
  case 0xC5:
    rxbyte = 0x41;
    break;
  case 0xC8: //"E" variants
  case 0xC9:
  case 0xCA:
  case 0xCB:
    rxbyte = 0x45;
    break;
  case 0xCC: //"I" variants
  case 0xCD:
  case 0xCE:
  case 0xCF:
    rxbyte = 0x49;
    break;
  case 0xD1: //"N" tilde -> plain "N"
    rxbyte = 0x43;
    break;
  case 0xD2: //"O" variants
  case 0xD3:
  case 0xD4:
  case 0xD5:
  case 0xD6:
  case 0xD8:
    rxbyte = 0x4F;
    break;
  case 0xD9: //"U" variants
  case 0xDA:
  case 0xDB:
  case 0xDC:
    rxbyte = 0x55;
    break;
  case 0xDD: //"Y" acute -> "Y"
    rxbyte = 0x59;
    break;
    /*		case 0xDF: //beta  //mucks up LCDSmartie's degree symbol??
     			rxbyte = 0xE2;
     			break;
     */  case 0xE0: //"a" variants except umlaut
  case 0xE1:
  case 0xE2:
  case 0xE3:
  case 0xE5:
    rxbyte = 0x61;
    break;
  case 0xE7: //"c" cedilla -> "c"
    rxbyte = 0x63;
    break;
  case 0xE8: //"e" variants
  case 0xE9:
  case 0xEA:
  case 0xEB:
    rxbyte = 0x65;
    break;
  case 0xEC: //"i" variants
  case 0xED:
  case 0xEE:
  case 0xEF:
    rxbyte = 0x69;
    break;
  case 0xF2: //"o" variants except umlaut
  case 0xF3:
  case 0xF4:
  case 0xF5:
  case 0xF8:
    rxbyte = 0x6F;
    break;
  case 0xF7: //division symbol
    rxbyte = 0xFD;
    break;
  case 0xF9: //"u" variants except umlaut
  case 0xFA:
  case 0xFB:
    rxbyte = 0x75;
    break;
  default:
    break;
  }

  lcd.print(rxbyte);  //otherwise a plain char so we print it to lcd
  return;

Moin,

dejulian:
Ich will ein LCD mit 40X4 Zeichen über ein Arduino Nano mit Daten von der Smartie LCD Software (lcdsmartie.sourceforge.net/) füttern.

    case 74:  //show underline cursor

lcd.command(0b00001110);
      break;
    case 75:  //underline cursor off
    case 84:  //block cursor off
      lcd.command(0b00001100);
      break;

Zwei Dinge:
Nach case 75: habe ich mich nicht mehr mit dem Code beschäftigt. Auch, weil es später nicht besser wird.
Zu jedem case gehört ein break.

Und das sourceforge tatsächlich noch plain http ohne s unterstützt war mir auch neu.
Durch den slash am Ende kommt die Link-Automatik ins stottern.
richtig: http://lcdsmartie.sourceforge.net (ungesicherte Verbindung!)

Ungeachtet dessen, wenn Du via USB den Rechner mit dem Nano verbunden hast, kannst Du Serial an PIN 0/1 nicht benutzen.

Ich würde zunächst versuchen rauszubekommen,
a)was die Windows-Software wirklich raussendet, also z.B. mit einem Nullmodem Kabel am PC auf einer anderen Schnittstelle auslesen oder zumindest eine Doku suchen wo das beschrieben ist
b) dann über den Serial Monitor mal direkt die Kommandos zu senden und dann genau beschreiben bei welchem Kommando das Display was anzeigt versus was es anzeigen soll und ein Bild davon machen.

my_xy_projekt:
Zu jedem case gehört ein break.

Nicht unbedingt. Wenn man z.B. für verschiedene case-Fälle das Gleiche tun will, schreibt man die ohne break; untereinander - so wie im angegebenen Fall mit 75 und 84.

Gegebenenfalls noch ein [[fallthrough]]; um dem Compiler klarzumachen, dass das Absicht ist, und er keine Warnung generieren soll ( gibt's seit C++17 ).

Wie hast Du die Smartie - Software denn überhaupt konfiguriert? Normalerweise ist die dafür gedacht, dass die unterstützten Displays direkt am PC angeschlossen sind. Für den HD44780 ist da eigentlich ein parallel-Interface vorgesehen. Es werden offensichtlich auch bestimmte serielle Displays unterstützt, wobei sich die Software da an deren Protokoll anpassen wird.
Die Doku ist etwas rudimentär, was wirklich gesendet wird, habe ich da nicht gesehen. Es scheint einen 'Test Driver' zu geben, bei dem man das selbst beeinflussen kann.

MicroBahner:
Nicht unbedingt. Wenn man z.B. für verschiedene case-Fälle das Gleiche tun will, schreibt man die ohne break; untereinander - so wie im angegebenen Fall mit 75 und 84.

Jetzt wo's sagst....
Aber trotzdem fehlt am Ende ein schliessendes Klammerchen in der loop - man kann natürlich raten, das da tatsächlich Schluss sein soll, aber da steht noch ne Abbruchfunktion..

Sorry wegen dem "unsicheren" Link und dem kleinen Fehler mit dem / :wink:
Also wie gesagt der Sketch funktioniert mit einem kleineren Display (mit der Standart LiquidCrystal lib) wunderbar. Mit der seriellen Schnittstelle habe ich keine Probleme (wegen Pin 1 und 0) <-- Verstehe ich gerade auch nicht ganz, die Pins sind ja durch das LCD nicht belegt.

Der Tipp mit dem mitlesen der seriellen Daten ist schonmal ein guter Ansatz.

Ich hab auch mittlerweile den Ursprung von dem Sketch gefunden --> MilesBurton.com

Ich benutze die matrix.dll in Smartie LCD mit Angabe der seriellen Schnittstrelle bzw. Baudrate. Hätte ich einen Parallelport wäre es auch kein Problem, hab die Konstallation damals immer benutzt zu Win XP Zeiten. Ich weiss auch nicht wie es mittlerweile unter Win 10 ist den Parallel Port anzusprechen.

Zu dem Thema Smartie LCD finde ich in dem Arduino Forum auch unzählige Threads aber leider keinen in dem mein Problem erläutert wird.