Traslare scritte su LCD

Ciao a tutti...
Il mio problema è scritto in titolo...
Ho provato a cercare in lungo e in largo, ma sembra che nessuno abbia questo problema...

Sostanzialmente, devo TRASLARE tutta la schermata che mi appare nell' LCD a sinistra, e possibilmente farne entrare un altra da destra creando una sorta di effetto "scorrimento" da utilizzare per navigare tra varie pagine...
Il comando scroll non fa al caso mio perchè mi fa apparire le scritte nella parte destra dello schermo, mentre io vorrei farle "sparire" verso destra...

Ho provato a spostare tutto in un array, ma oltre a non riuscire a spostarne gli elementi verso sinistra, ho anche l'impressione che non funzioni perchè oltre alle scritte ho anche degli input nella schermata...

Sono convinto che non sia poi così complicato, ma sono giorni che ci sbatto la testa...

Sapete aiutarmi?

Ho cancellato il mio post precedente perché forse ho trovato qualche cosa che fa per te ed il post precedente era quindi inesatto ...

... il controller per LCD classico (HD44780 e compatibili), prevede tra i suoi comandi, un comando chiamato "Cursor or Display Shift" che è così descritto:

Cursor or display shift shifts the cursor position or display to the right or left without writing or reading display data (Table 7). This function is used to correct or search the display. In a 2-line display, the cursor moves to the second line when it passes the 40th digit of the first line. Note that the first and second line displays will shift at the same time.
When the displayed data is shifted repeatedly each line moves only horizontally. The second line display does not shift into the first line position.
The address counter (AC) contents will not change if the only action performed is a display shift.

... quindi, sembrerebbe possibile lo scorrimento orizzontale, con un comando di ogni singola linea del display.

Quello che non so è se qualche libreria lo abbia implementato ... o devi farlo tu ::slight_smile:

Guglielmo

P.S.: In allegato il datasheet del controller

HD44780.pdf (322 KB)

... altro modo è crearti in memoria un'immagine di ciò che vuoi vedere sul display (array 16x2 oppure 20x4 ... o quello che hai), aggiornare quella (spostando come vuoi i caratteri ed inserendo quelli che servono) e poi sovrascrivere le righe fisiche del display ::slight_smile:

Guglielmo

... scusa, stavo controllando adesso, ma vedo che nella libreria LiquidCrystal esistono entrambe le funzioni:

  • scrollDisplayLeft(): Scrolls the contents of the display (text and cursor) one space to the left
  • scrollDisplayRight(): Scrolls the contents of the display (text and cursor) one space to the right.

Quindi hanno implementato il comando ... ed in entrambe le direzioni !!! Perché non usi quei comandi ?

Guglielmo

Non uso scrollDisplay perchè il testo viene "scrollato" verso una direzione, ma quando i caratteri escono dallo schermo ricompaiono dal lato opposto del display, in un' altra riga...

Stavo cercando di risolvere mettendo tutto in un array, come hai consigliato anche tu nel tuo secondo post, ma :
1)Non riesco a far "scorrere" gli elementi dell'array.
2)Avendo implementato delle "spie" per la lettura dei pin sull' LCD, non so se riesco a passarle come elementi per l'array.

A dire il vero, lo spostamento dell'array quasi riesco a farlo, ma mi fermo perchè riesco solo a spostare gli elementi, con conseguente riempimento dello spazio in "coda" con quello in "testa"...A me servirebbe spostare i valori verso sinistra mentre riempio con spazi vuoti a partire dalla "coda"...Non so se mi sono spiegato...

Certo se qualcuno avesse già riscontrato questo problema e avesse creato una funzione apposita(scritta sicuramente meglio delle mie prove)mi sarebbe sicuramente molto d'aiuto

Scusa, prendiamo un array di 20 elimenti che chiamio mioArray ...

char mioArray[20];
byte i;
...
...
for(i=0; i<18; i++) {
   mioArray[i] = mioArray[i+1];
}
mioArray[19] = ' ';

... dovrebbe spostarti ogni carattere a sinistra e mette un ' ' nell'ultimo lasciato libero.

Non ho avuto modo di provarlo, ma così ad occhio dovrebbe andare ... prova e fammi sapere.

Guglielmo

Se hai le N righe che sono visualizzate sul display in 2 array (riga1, riga2), è banale:

for (byte i = 0; i < NCOLS; i++) {
  lcd.setCursor (0, 0);
  if (strlen (riga1) < i)
    lcd.print (riga1 + i);
  for (byte j = strlen (riga1) - i; j < NCOLS; j++)
    lcd.print (' ');

  // Ripetere per riga2
}

O qualcosa di simile, spero renda l'idea.

EDIT: Preceduto da gpb, soluzione simile ma... diversa ;).

ok vi ringrazio...
La soluzione che mi avete proposto è simile alla mia, quindi potrei aver fatto qualche errore banale...
Comunque ora ci riprovo e vi faccio sapere...
Grazie ancora, soprattutto per la rapidità

Allora...Devo dire che tutti e 2 i vostri sketch fanno (con le opportune modifiche) esattamente quello che voglio, con un effetto diverso per ciascuno dei 2...

Nel programma di gpb ho degli errori di compilazione(anche se funziona correttamente), mentre quello di sukkopera, non riesce a cancellare l'ultimo elemento dall'array e non capisco il motivo.

Una curiosità, perchè utilizzate byte x dichiarare gli indici del ciclo FOR?
E nel programma di sukkopera, cosa succede quando fai "riga1+i"?

Se volete vi posto i 2 codici...Penso sia utile perchè in rete si trova veramente poco e spiegato male...

Gaio:
Nel programma di gpb ho degli errori di compilazione(anche se funziona correttamente)

... se ottieni un programma eseguibile, NON possono esserci errori di compilazione, ci son forse dei warning ... riportali qui e vediamo :wink:

Guglielmo

#include <LiquidCrystal.h>

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

char stringa[20] = "ciao";


void setup() {
 

  lcd.begin(20, 4); 
  lcd.setCursor(0,0);
  lcd.print(stringa);
  delay(1000);
  }

void loop() {


for(byte i=0; i<strlen(stringa)-1; i++) {
   stringa[i] = stringa[i+1];
}
lcd.setCursor(0,0);
lcd.print(stringa);
stringa[strlen(stringa)-1] = " ";

delay(60);
}

Questo è il mio codice seguendo l' esempio di gpb...

I warning riscontrati sono questi:

C:*\Prova_scorrimento_2.ino: In function 'void loop()':
C:*
\Prova_scorrimento_2.ino:26:28: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]
stringa[strlen(stringa)-1] = " ";

  • ^*
    Lo sketch usa 2.496 byte (0%) dello spazio disponibile per i programmi. Il massimo è 253.952 byte.
    Le variabili globali usano 63 byte (0%) di memoria dinamica, lasciando altri 8.129 byte liberi per le variabili locali. Il massimo è 8.192 byte.

Mentre il codice derivato dall' esempio di sukkopera è questo:

#include <LiquidCrystal.h>

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

char stringa[20] = "ciaoooooooooooooo";


void setup() {
 

  lcd.begin(20, 4); 
  lcd.setCursor(0,0);
  lcd.print(stringa);
  delay(1000);
  }

void loop() {


for (byte i = 0; i < strlen(stringa); i++) {
  lcd.setCursor (0, 0);
  if (strlen (stringa) < i)
    lcd.print (stringa + i);
  for (byte j = strlen (stringa) - i; j < strlen(stringa); j++)
    lcd.print (' ');

delay(500);
}
}

Ora, premesso che è la prima volta che riesco a realizzare questo effetto e quindi il vostro aiuto è stato il più valido fin'ora, vi devo chiedere delle altre info...

In questo progetto, ho visualizzato nel monitor LCD dei caratteri speciali, che mi fungono da spie per vari input...

Praticamente con la funzione "lcd.write" li vado a scrivere direttamente sul monitor, spostando le varie volte il cursore...

Detto ciò, come potrei inserire tutto questo dentro l' array corrispondente a quella riga?

Se volete vi posto il codice di tutto il mio programma

stringa[strlen(stringa)-1] = " ";

Qui ci vogliono gli apici singoli, non le virgolette.

Inoltre ricorda che se una stringa deve poter contenere fino a 20 caratteri, devi dichiarare il rispettivo array di 21.

Ok...Me n'ero accorto anch'io...

Ma che differenza c'è tra apice singolo e apici doppi?

Gaio:
Ma che differenza c'è tra apice singolo e apici doppi?

L'apice singolo racchiude UN carattere, quindi 'A' è il carattere A; i doppi apici racchiudono una stringa del C (... ovvero un char array) quindi "A" sono DUE caratteri, la 'A' ed il terminatore di stringa 0x00.

Prendi un buon testo del linguaggio 'C' e studialo, ti sarà sicuramente utile :wink:

Guglielmo