Risolto:Scritta scorrevole con display Tft 128*160

Ciao a tutti, ho acquistato un display tft 128*160 più per studio che per un progetto.
Ho utilizzato la libreria tft e devo dire che non ho avuto grandi problemi, ho disegnato varie forme, scritte e visualizzato ciò che volevo.
Poi mi sono imbattuto in un problema bello grande: realizzare una scritta scorrevole...
Ho guardato la libreria, ma non esiste un comando che permetta al testo di scorrere.
Quindi ho iniziato a paciugare un po' con il codice, ma senza risultati...anzi...
Chi può aiutarmi?
C'è qualcuno che ha già realizzato un progetto così?
Come posso fare?
Grazie.

Non sono pratico di questi display, ma potresti provare come si faceva negli anni 90 coi monitor vga 640x480...
Scrivi quello che vuoi nella posizione iniziale, aspetti un attimo e poi lo cancelli e riscrivi in una posizione leggermente spostata, aspetti un altro attimo e cancelli di nuovo e riscrivi ancora più spostato.
Col giusto timing l'effetto dovrebbe essere quello della scritta scorrevole

Quale libreria, posta un link.

Per scritte scorrevoli si intende qualcosa di simile a questo:
"CIAO" è la scritta che si vuole fare scorrere.

Colonne del display

0 1 2 3 4 5 6 7 8 9
                  C
                C I
              C I A
            C I A O
          C I A O

Così scorre da destra verso sinistra.

Posta il codice che hai messo su per adesso, poi valutiamo.

PS: Purtroppo il forum non mi permette di allineare le colonne.

Ciao.

Io avrei l'idea di creare un array con tutti caratteri spazi, e poi inserirvi di volta in volta il testo da stampare spostando la posizione nell array di un carattere.

Siccome è più complicato descriverlo a parole che scrivere due righe di codice, posto il codice con l'idea, che non è stata provata quindi possono esserci BUG. :slight_smile:

#define MAXCARATTERI 50 //MASSIMI CARATTERI STAMPABILI SUL DISPLAI
int cont=MAXCARATTERI; //VARIABILE CONTATORE

char testo[50]="testo scorrevole";
char stringa[MAXCARATTERI]; // stringa da stampare

void setup(){

}


void loop(){

   int i=0;
   for(i=0;i<MAXCARATTERI;i++){// inizializzo stringa con degli spazi ' '
        stringa[i]=' ';
   }
  
   for(i=0;i<strlen(testo);i++){ // copio testo in stringa nella giusta posizione
       if(cont-i>=0)
           striga[cont-i]=testo[strlen(testo)-i];
   }

   cont--; //decremento per testo scorrevole, stampera a un carattere dopo
   if(cont<0)// Se è finito lo schermo
       cont=MAXCARATTERI;

   STAMPA(stringa); // richiamare una funzione che stampo testo sul display
   delay(500); //pausa che regola la velocita di scorrimento del testo, altrimenti sarebbe istantaneo
}

Maurotec:
PS: Purtroppo il forum non mi permette di allineare le colonne.

.. Mauro, Mauro ... basta usare i tag giusti ;D Se usi il tag CODE (come ti ho modificato io) tutto è più facile :wink:

Guglielmo

Eccomi qui, grazie per gli aiuti.
Torn24, ho seguito il tuo suggerimento ma non funziona per due motivi:
1-sembra non cancelli ma sovrascriva e crea un casino che non si legge nulla
2-una volta che finisce non riparte.

Maurotec,il codice che ho fatto è il seguente:

#include <TFT.h>  // Arduino LCD library
#include <SPI.h>


#define cs   10
#define dc   9
#define rst  8


#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
TFT TFTscreen = TFT(cs, dc, rst);
#define MAXCARATTERI 10 //MASSIMI CARATTERI STAMPABILI SUL DISPLAI
int cont=MAXCARATTERI; //VARIABILE CONTATORE
char testo[50]="Ciao";
char stringa[MAXCARATTERI]; // stringa da stampare

void setup() {
Serial.begin(9600);

  TFTscreen.begin();
  TFTscreen.background(0, 0, 0);
  TFTscreen.setRotation(3);
  TFTscreen.stroke(255, 255, 255);
  TFTscreen.setTextSize(2);
  TFTscreen.text("Traccia ", 0, 0);
  TFTscreen.text("01",100,0);
}
void loop() {
int i=0;
   for(i=0;i<MAXCARATTERI;i++){// inizializzo stringa con degli spazi ' '
        stringa[i]=' ';
   }
  
   for(i=0;i<strlen(testo);i++){ // copio testo in stringa nella giusta posizione
       if(cont-i>=0)
           stringa[cont-i]=testo[strlen(testo)-i];
   }

   cont--; //decremento per testo scorrevole, stampera a un carattere dopo
   if(cont<0)// Se è finito lo schermo
       cont=MAXCARATTERI;
   TFTscreen.text(stringa,0,20);
   delay (200);
}

Come suggerito.
E si, l'idea è quella che hai descritto tu...
Poi per me sarebbe più fico se partisse da sx verso dx.....
MA si può vedere in seconda battuta....

Qui c'è un vecchio topic su scritte scorrevoli, ma è tanto vecchio che manco ricordavo di avere postato.

Ciao.

Si ma Maurotec, non uso la stessa libreria...
:confused:

Si ma Maurotec, non uso la stessa libreria...

Quindi?

Nota che la funzione è indipendente dalla libreria, ma non importa sono dettagli che comprenderai più in là.

Hai risolto?

Ciao.

No.... :sob:

No....

azz... :smiley:

Allora non ho arduino e non ho IDE, ho solo un pc portatile e quindi ho testato la mia funzione che ti ho linkato e funge.

Questo è ciò che stampa.

19:37:39: Starting /home/mauro/devel/Cprj/scrollstring/scrollstring ...
Hello World!
 sab 8 dic 2012 00:03
sab 8 dic 2012 00:03:
ab 8 dic 2012 00:03:0
b 8 dic 2012 00:03:09
 8 dic 2012 00:03:09 
8 dic 2012 00:03:09 s
 dic 2012 00:03:09 sa
dic 2012 00:03:09 sab
ic 2012 00:03:09 sab 
c 2012 00:03:09 sab 8
 2012 00:03:09 sab 8 
2012 00:03:09 sab 8 d
012 00:03:09 sab 8 di
12 00:03:09 sab 8 dic
2 00:03:09 sab 8 dic 
 00:03:09 sab 8 dic 2
00:03:09 sab 8 dic 20
0:03:09 sab 8 dic 201
:03:09 sab 8 dic 2012
03:09 sab 8 dic 2012 
3:09 sab 8 dic 2012 0
:09 sab 8 dic 2012 00
09 sab 8 dic 2012 00:
9 sab 8 dic 2012 00:0
 sab 8 dic 2012 00:03
sab 8 dic 2012 00:03:
ab 8 dic 2012 00:03:0
b 8 dic 2012 00:03:09
 8 dic 2012 00:03:09 
8 dic 2012 00:03:09 s
19:37:39: /home/mauro/devel/Cprj/scrollstring/scrollstring exited with code 0

C'è una particolarità la stringa è più lunga del numero di colonne che ha il mio display, ma questo è il vantaggio delle scritte scorrevoli, diversamente servono solo per fare scena.

PS: devi stampare a riga 0 e colonna 0 sempre la stessa variabile ad esmpio così:

    for (int i=0; i<30; i++) {

        scroll_string(" sab 8 dic 2012 00:03:09", date_time);
        TFTscreen.text(date_time, 0, 0);
        

    }

La variabile date_time è dichiarata globale così:

char date_time[22];

Ciao.

Ciao Maurotec, in questi giorni sono molto preso con il lavoro ed ho 0 tempo per l'hobby....
Grazie per la tua funzione, l'ho letta e studiata e sulla carta mi sembra funzionare.
In questi giorni la provo con il mio tft...
Ho due dubbi:
1-se la stringa che voglio visualizzare è più piccola di 22 caratteri cambia qualcosa? In questo caso come posso modificarlo per renderlo più dinamico, cioè che si adatti alla lungheza di ciò che voglio visualizzare?
2-Questo passaggio

for (int i=0; i<30; i++) {

        scroll_string(" sab 8 dic 2012 00:03:09", date_time);
        TFTscreen.text(date_time, 0, 0);
        

    }

non è bloccante per tutto il resto dello sketch?
Grazie per l'aiuto.

1-se la stringa che voglio visualizzare è più piccola di 22 caratteri cambia qualcosa? In questo caso come posso modificarlo per renderlo più dinamico, cioè che si adatti alla lungheza di ciò che voglio visualizzare?

La stringa deve avere lunghezza costante durante lo scroll, se la stringa ha meno caratteri gli aggiungi n caratteri spazio fino a raggiungere la lunghezza prevista.

non è bloccante per tutto il resto dello sketch?

Per sviluppare e tarare l'algoritmo va più che bene nel mio caso, nell'applicazione finale ovviamente la si deve modificare, in ogni caso dovrai temporizzarla con millis().

PS: provato sperimentalmente: la stessa funzione permette due strisce scorrevoli sulla stessa riga.

Ciao.

Ciao Maurotec, ho provato ma.....sul display tft non funziona...
In seriale fa esattamente quello che deve fare, mentre sul display sovrascrive e viene un paciugo...
Ho provato anche a cancellare con spazi vuoti prima di scrivere la scritta nuova ma non funziona...
Dove sbaglio???
Qui il codice:

#include <TFT.h>  // Arduino LCD library
#include <SPI.h>


#define cs   10
#define dc   9
#define rst  8


#define  BLACK   0x0000
#define BLUE    0x001F   //ROSSO
#define RED     0xF800  //BLU
#define GREEN   0x07E0  //verde
#define CYAN    0x07FF  //GIALLO
#define MAGENTA 0xF81F  //magenta viola
#define YELLOW  0xFFE0
#define WHITE   0xFFFF


TFT TFTscreen = TFT(cs, dc, rst);

char stringa[10];

void setup() {
Serial.begin(9600);
  TFTscreen.begin();             //inizializzo il display
  TFTscreen.background(0, 0, 0); //sfondo nero
  TFTscreen.setRotation(3);      //ruoto il display di 180°
  TFTscreen.stroke(255, 255, 255); //imposto colore carattere bianco
  TFTscreen.setTextSize(2);        //dimensione carattere
  TFTscreen.text("Traccia ", 0, 0); //scrivo in altro a sx
  TFTscreen.text("01",100,0);

  TFTscreen.setTextSize(3);  //dimensione carattere 3
  
}

void loop() {
scroll_string("123456789", stringa);
TFTscreen.stroke(255, 255, 255);
TFTscreen.text("         ",0,20);
//               B  G  R
TFTscreen.stroke(0, 0, 255);
TFTscreen.text(stringa, 0, 20);
Serial.println(stringa);
delay(1000);
//TFTscreen.text("123456789",0,20);
  //                     x0  y0  x1 y1 x2 y2  colore
  TFTscreen.drawTriangle(0, 128, 0, 100,20, 114, GREEN);
  TFTscreen.fillTriangle(0, 128, 0, 100,20, 114, GREEN);
 //                  x0  y0  w   h     colore
  TFTscreen.drawRect(30, 100, 7, 28, CYAN); //GIALLO
  TFTscreen.fillRect(30, 100, 7, 28, CYAN);  
  TFTscreen.drawRect(40, 100, 7, 28, CYAN); //GIALLO
  TFTscreen.fillRect(40, 100, 7, 28, CYAN); 
  TFTscreen.drawRect(0, 70, 20, 28, MAGENTA);  //60,100
  TFTscreen.fillRect(0, 70, 20, 28, MAGENTA);

}

void scroll_string(const char * s, char *dest_s)
{

    static uint8_t i = 0;                                // viene incrementato ad ogni chiamata
    uint8_t end_idx = i;
    uint8_t idx = 0;
    while (idx < 10) {                                  // copia in dest_s[] 21 caratteri presi da s[]
        dest_s[idx] = s[end_idx];
        idx++;
        end_idx++;
        if (end_idx > 10 )                              //  dopo il 23 esimo carattere si riparte da 0
            end_idx = 0;
    }
    dest_s[9] = '\0';                                  // aggiungo il fine riga
    i++;                                                      // se i supera il limite si riparte da 0
    if (i > 11)
        i = 0;
}

Poi altra cosa, i colori non sono esattamente quelli dichiarati, il rosso visualizza blu il blu visualizza il rosso.......

Allora aggiorno la situazione: leggendo un po' in giro, sembra che dopo aver scritto la stringa devo scriverne un'altra uguale nella stessa posizione ma di colore dello sfondo, e poi scrivere la nuova stringa nella stessa posizione.

scroll_string("123456789", stringa);
        TFTscreen.stroke(255, 255, 255);
        TFTscreen.text(stringa, 0, 20);
        delay(1000);
        TFTscreen.stroke(0, 0, 0);
        TFTscreen.text(stringa, 0, 20);

è a scatti ma credo che con questo display non posso chiedere di meglio...
Ora prò non mi sembra girare molto bene....
A fine ciclo mi scrive su una seconda riga la stringa intera e in seriale quanto segue:

123456789
23456789
3456789
456789
56789
6789
789
89
9


1234567

12345678
123456789
#include <TFT.h>  // Arduino LCD library
#include <SPI.h>


#define cs   10
#define dc   9
#define rst  8


#define  BLACK   0x0000
#define BLUE    0x001F   //ROSSO
#define RED     0xF800  //BLU
#define GREEN   0x07E0  //verde
#define CYAN    0x07FF  //GIALLO
#define MAGENTA 0xF81F  //magenta viola
#define YELLOW  0xFFE0
#define WHITE   0xFFFF


TFT TFTscreen = TFT(cs, dc, rst);

char stringa[10];

void setup() {
Serial.begin(9600);
  TFTscreen.begin();             //inizializzo il display
  TFTscreen.background(0, 0, 0); //sfondo nero
  TFTscreen.setRotation(3);      //ruoto il display di 180°
  TFTscreen.stroke(255, 255, 255); //imposto colore carattere bianco
  TFTscreen.setTextSize(2);        //dimensione carattere
  TFTscreen.text("Traccia ", 0, 0); //scrivo in altro a sx
  TFTscreen.text("01",100,0);

  TFTscreen.setTextSize(3);  //dimensione carattere 3
 
}

void loop() {
scroll_string("123456789", stringa);
TFTscreen.stroke(255, 255, 255);

TFTscreen.text(stringa, 0, 20);
Serial.println(stringa);
delay(1000);


  TFTscreen.drawTriangle(0, 128, 0, 100,20, 114, GREEN);
  TFTscreen.fillTriangle(0, 128, 0, 100,20, 114, GREEN);
 //                  x0  y0  w   h     colore
  TFTscreen.drawRect(30, 100, 7, 28, CYAN); //GIALLO
  TFTscreen.fillRect(30, 100, 7, 28, CYAN); 
  TFTscreen.drawRect(40, 100, 7, 28, CYAN); //GIALLO
  TFTscreen.fillRect(40, 100, 7, 28, CYAN);
  TFTscreen.drawRect(0, 70, 20, 28, MAGENTA);  //60,100
  TFTscreen.fillRect(0, 70, 20, 28, MAGENTA);

}

void scroll_string(const char * s, char *dest_s)
{

    static uint8_t i = 0;                                // viene incrementato ad ogni chiamata
    uint8_t end_idx = i;
    uint8_t idx = 0;
    while (idx < 10) {                                  // copia in dest_s[] 21 caratteri presi da s[]
        dest_s[idx] = s[end_idx];
        idx++;
        end_idx++;
        if (end_idx > 8 )                              //  dopo il 23 esimo carattere si riparte da 0
            end_idx = 0;
    }
    dest_s[10] = '\0';                                  // aggiungo il fine riga
    i++;                                                      // se i supera il limite si riparte da 0
    if (i > 8)
        i = 0;
}

Prova così.
A me stampa questo:

16:21:22: Starting /home/mauro/devel/Cprj/scrollstring/scrollstring ...
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789
1234567891
2345678912
3456789123
16:21:22: /home/mauro/devel/Cprj/scrollstring/scrollstring exited with code 0

Se ci fai caso stampa 10 caratteri a fronte di una stringa grande 9 caratteri, capisci che non ha molto senso, poiché si perde la possibilità di visualizzare più informazioni di quanto siano visualizzabili su una riga o nel campo display che in questo caso è grande 10 caratteri.

Ciao.

Grazie Maurotec, funziona bene...
Ora ci "gioco" un po' ...
Grazie per l'aiuto.
Solo un'ultima cosa voreri chiederti...
Ora la prima scrittura fa "123456789" e poi inizia a scorrere, come posso modificare per far iniziare ad "entrare" cioè

        1
               12
              123
             1234
            12345
           123456 
           ecc...

Aprirò un altro topic sull'incopatibilità dei colori, che sul mio display sono diversi dalla libreria.