Due LCD hd44780 come unico grande LCD

Ciao a tutti, uso da circa 20 anni LCD SMARTIE un software per visualizzare informazioni pc ed altro su piccoli LCD tipo hd44780 e simili, sono riuscito a trovare esempi di sketch per interfacciarmi con arduino e con varie modifiche sono tornati funzioanti, vorrei però aggiungere un altro lcd hd44780 con interfaccia I2C così da risparmiare pin e sono riuscito anche ad aggiungerlo e scriverci un messaggio, quindi deduco che il tutto funziona, solo che LCD SMARTIE riesce a gestire un solo LCD alla volta, ci sarebbe il modo di far vedere ad arduino 2x LCD hd44780 20x4 come un unico grande LCD 40x4 ? cè qualcuno che può darmi una mano

grazie a tutti

Buongiorno, h3rm3s80
Benvenuto nella sezione Italiana del forum :slight_smile:

Cortesemente, leggi attentamente il REGOLAMENTO di detta sezione:
[REGOLAMENTO] Come usare questa sezione del forum
(... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15)
e poi, come da suddetto regolamento (punto 16.7), fai la tua presentazione IN CODA ALL'APPOSITA DISCUSSIONE:
Presentazioni nuovi iscritti: fatevi conoscere da tutti! (Part 2)
spiegando bene quali esperienze hai in elettronica e in programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie
Gianluca

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento, nessuno ti risponderà (eventuali risposte, o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

P.P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...

Ciao, grazie del messaggio, ero in fase di scrittura, non riuscivo a trovare la sezione adatta alle presentazioni, colpa della poca presenza nei forum

Benvenuto, Luke :slight_smile:
Esistono anche gli LCD 40x4...
https://www.google.com/search?q=arduino+lcd+40x4
https://it.aliexpress.com/w/wholesale-lcd-display-40x4.html

Altrimenti puoi usare due LCD 20x4 I2C, semplicemente assegnando indirizzi diversi
https://www.google.com/search?q=arduino+2+lcd+i2c
Naturalmente poi dovrai gestire tu la scrittura dei primi 20 caratteri di ogni riga sul primo LCD e dei successivi sul secondo.

il mio intento è quello di aggiungere tanti lcd quanti ne occorrono con il limite di indirizzi naturalmente, sono aperto alla gestione della scrittura da parte di arduino e soprattutto se occorre posto lo sketch adesso funzionante

Comunque non poi allontanare molto gli LCD impunemente, eh! I fili devono essere corti.

Si, in questo momento ho cavi dupont di circa 15 cm e pare andare bene, non ho perdite di continuità dei dati, con i 15 cm riuscirei al massimo ad aggiungere 5/6 lcd all'occorrenza

questo è il codice che utilizzo funzionante, come posso gestire le linee dell'LCD?

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd2(0x23,16,2);
void setup()
{
  lcd2.init();                      // initialize the lcd 
  lcd2.backlight();
  Serial.begin(9600);
}

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;
  byte col;
  byte row;

  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;
      }
      lcd2.command(0b10000000 + temp);
      break;
    case 72:  //cursor home (reset display position)
      lcd2.command(2);
      break;
    case 74:  //show underline cursor
      lcd2.command(0b00001110);
      break;
    case 75:  //underline cursor off
    case 84:  //block cursor off
      lcd2.command(0b00001100);
      break;
    case 76:  //move cursor left
      lcd2.command(16);
      break;
    case 77:  //move cursor right
      lcd2.command(20);
      break;
    case 78:  //define custom char
      lcd2.command(64 + (serial_getch() * 8));  //get+set char address
      for (temp = 7; temp != 0; temp--)
      {
        lcd2.write(serial_getch()); //get each pattern byte // change to lcd.write(serial_getch()) from lcd.print(serial_getch())   Arduino IDE 1+
      }
      break;
    case 83:  //show blinking block cursor
      lcd2.command(0b00001111);
      break;
    case 86:  //GPO OFF
      //implement later
      break;
    case 87:  //GPO ON

      break;
    case 88:  //clear display, cursor home
      lcd2.command(1);
      break;
    case 152: //set and remember (doesn't save value, though)

    

    case 153: // Set backlight brightness (1 parameter, brightness)


      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 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 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 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.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.write(serial_getch()); //get each pattern byte // change to lcd.write(serial_getch()) from lcd.print(serial_getch())   Arduino IDE 1+
      }
      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 (1 parameter, brightness)


      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;
  }

  lcd2.write(rxbyte);  //otherwise a plain char so we print it to lcd, change to lcd.write(rxbyte) from lcd.print(rxbyte)   Arduino IDE 1+
  return;

  lcd.write(rxbyte);  //otherwise a plain char so we print it to lcd, change to lcd.write(rxbyte) from lcd.print(rxbyte)   Arduino IDE 1+
  return;
}```

Leggendo ancora in giro, ho trovato questo sketch, che pare dica ad arduino di continure a scrivere sul secondo LCD nel momento in cui finisce lo spazio sulla riga del primo con il corrispettivo del secondo lcd, ma non ho idea di come integrarlo

#include <LiquidCrystal.h>
LiquidCrystal lcd2(12, 11, 1, 2, 3, 4);
LiquidCrystal  lcd1(0, 10, 8, 7, 6, 5);

char * LargeText = "  Connecting 2 - 16*2 LCD with  Arduino by shashwat__raj.  ";
int iLineNumber = 1;                                                                
int  iCursor = 0;

void setup() 
{
  
  lcd1.begin(16, 2);                                                          
  lcd2.begin(16, 2);
  lcd1.clear();
  lcd2.clear();
  
}
void loop()  
{
  
  UpdateLCDDisplay();                                                              
  delay(160);                                                                      
  lcd1.clear();
  lcd2.clear();
  delay(60);
  
}

void UpdateLCDDisplay()
{
  int iLenOfLargeText = strlen(LargeText);                                         
  if (iCursor == (iLenOfLargeText - 1) )                                            
{
   iCursor = 0;
}
  lcd1.setCursor(0,iLineNumber);
  lcd2.setCursor(0,iLineNumber);
  if(iCursor < iLenOfLargeText - 32)                                             
{
  for (int iChar = iCursor; iChar < iCursor + 16 ; iChar++)
{
  lcd1.print(LargeText[iChar]);
}
  for (int iChar = iCursor + 16 ; iChar < iCursor + 32 ; iChar++)
{
  lcd2.print(LargeText[iChar]);
}
}
  else
{
  for (int iChar = iCursor; iChar < (iLenOfLargeText - 1) ; iChar++)           
{
  if(16 > (iChar - iCursor))
{
  lcd1.print(LargeText[iChar]);
}
  else
{
  lcd2.print(LargeText[iChar]);
}
}
  for (int iChar = 0;  iChar <= 32 - (iLenOfLargeText - iCursor); iChar++)       
{
  if(16 > (32  - (iLenOfLargeText - iCursor)))
{
  lcd2.print(LargeText[iChar]);
}
  else
{
  if( ((32 - (iLenOfLargeText - iCursor)) - 16) >=  iChar)
{
  lcd1.print(LargeText[iChar]);
}
  else
{
  lcd2.print(LargeText[iChar]);
}
}  
}
}
  iCursor++;
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.