Ciao,
non trovo informazioni, sto utilizzando la libreria UTFT per i display, e vorrei scrivere nel display le stesse cose che arduino mi scrive nella seriale, arduino ha dei caratteri CHAR e la seriale li mostra correttamente, se la stessa variabile CHAR la scrivo sul display, vedo altre cose (nemmeno il numero del carattere). C'è uno stratagemma o una conversione da fare?
Grazie a tutti
Beh facci vedere il tuo codice così possiamo dirti qualcosa di più preciso...
Ciao,
mi sono dimenticato il codice :-[
Eccolo:
#include <SPIflash.h>
#include <UTFT.h>
#include <UTFT_SPIflash.h>
#include <URTouch.h>
#define LUCE_DISPLAY 7 // uscita PWM comando luminosità display
#define PROGR_BLUETOOTH 8 // piedino per programmazione AT del bluetooth
UTFT myGLCD(CTE50CPLD, 38, 39, 40, 41);
URTouch myTouch( 6, 5, 4, 3, 2);
SPIflash myFlash(51);
UTFT_SPIflash myFiles(&myGLCD, &myFlash);
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
uint8_t fileid;
uint16_t filetype;
int x, y; // variabile 2 byte per touch
boolean progr;
void setup()
{
pinMode(LUCE_DISPLAY, OUTPUT); // mette il pin 7 come uscita
pinMode(PROGR_BLUETOOTH, OUTPUT); // mette il pin 8 come uscita
digitalWrite(PROGR_BLUETOOTH, LOW); // spegne la programmazione AT del bluetooth
analogWrite(LUCE_DISPLAY, 255); // regola la luminosità del display
Serial.begin(38400); //Inizializzo la seriale di arduino
Serial1.begin(38400); //Inizializzo la seriale del bluetooth
myGLCD.InitLCD(LANDSCAPE);
myGLCD.clrScr();
myTouch.InitTouch(LANDSCAPE);
myTouch.setPrecision(PREC_MEDIUM);
myGLCD.setColor(255, 255, 255);
myGLCD.setFont(BigFont);
myFlash.begin();
progr = false;
tastoProgrBluetooth(); // creo tasto per bluetooth
myGLCD.print("BENVENUTO", CENTER, 50); //scrive caratteri
if (myFlash.ID_device == 0)
{
myGLCD.print("Modulo memoria Flash non trovato", CENTER, 100);
}
delay(1000);
}
void loop()
{
if (Serial1.available()) { // Controlla se il bluetooth riceve qualche dato
char c = Serial1.read(); // Il dato va in una variabile di tipo char
Serial.write(c); // Scrive sul terminale i dati ricevuti
myGLCD.printNumF(char(c) / 1, 0, 75, 125); //char, variabile, divide per, n. decimali,
//posizione orizz, posizione vert
}
if (Serial.available()) { //Se invece il serial monitor riceve un dato da inviare
char c = Serial.read(); //La variabile c viene memorizzata e letta dal monitor seriale
Serial1.write(c); //Il dato viene inviato al bluetooth perchè sia trasmesso
}
//***************************** controllo touch *****************************
if (myTouch.dataAvailable())
{
myTouch.read(); //leggo il touch??
x = myTouch.getX();
y = myTouch.getY();
if ((y >= 215) && (y <= 265)) // contr striscia inizio orizz, fine orizz
{
if ((x >= 5) && (x <= 165)) // controllo striscia inizio vert, fine vert
{
waitForIt(5, 215, 165, 265); //cambio il colore perimetro mentre pigio
if (progr == false)
{
progr = true;
}
else
{
progr = false;
}
tastoProgrBluetooth();
}
}
} //************************** fine controllo touch **************************
} // FINE LOOP
//**************************************************************************
void tastoProgrBluetooth() //pezzo di programma che crea tasto progr bluetooth
{
if (progr == false) {
myGLCD.setColor(0, 0, 255); //colore sfondo tasto
myGLCD.fillRoundRect (5, 215, 165, 265); //misure del rettangolo
myGLCD.setBackColor (0, 0, 255); //colore sfondo scritta
myGLCD.setColor(255, 255, 255); //colore perimetro tasto
myGLCD.drawRoundRect (5, 215, 165, 265); //misure perimetro tasto
myGLCD.setColor(255, 255, 255); //colore scritta
myGLCD.setFont(BigFont);
myGLCD.print("Progr OFF", 10, 233); //scrive, più posiz 1° orizz, 2° vert
digitalWrite (PROGR_BLUETOOTH, LOW);
}
else {
myGLCD.setColor(0, 255, 0); //colore sfondo tasto
myGLCD.fillRoundRect (5, 215, 165, 265); //misure del rettangolo
myGLCD.setBackColor (0, 255, 0); //colore sfondo scritta
myGLCD.setColor(255, 255, 255); //colore perimetro tasto
myGLCD.drawRoundRect (5, 215, 165, 265); //misure perimetro tasto
myGLCD.setColor(0, 0, 0); //colore scritta
myGLCD.setFont(BigFont);
myGLCD.print("Progr ON", 30, 233); //scrive, più posiz 1° orizz, 2° vert
digitalWrite (PROGR_BLUETOOTH, HIGH);
}
}
//******************************************************************************
void waitForIt(int x1, int y1, int x2, int y2) //cambia colore al perimetro mentre si tocca
{
myGLCD.setColor(255, 0, 0); // colore d afare il perimetro
myGLCD.drawRoundRect (x1, y1, x2, y2); // prende i dati del rettangolo da dove viene usato
while (myTouch.dataAvailable()) // aspetta venga tolto il dito dallo schermo
myTouch.read();
myGLCD.setColor(255, 255, 255); // rifà il colore originario del perimetro
myGLCD.drawRoundRect (x1, y1, x2, y2);
}
//******************************************************************************
Ho provato ad analizzare la libreria ed il tuo codice (non ho un TFT dove provarla) ma perché usi la printNumF() per stampare un carattere che non è sicuramente un float?
Ho letto che la normale print() accetta parametro char* quindi o metti il carattere in una variabile char* e passi quella alla print(), oppure prova a usare la printChar().
Ciao,
uso la printNumF() come prova, perchè è l'unica istruzione che mi compila, ho letto anche io della print(), ma non mi compila, forse sbaglio proprio il comando... Io faccio così:
myGLCD.print(dato, CENTER,120);
mi da errore: "invalid conversion from 'char' to 'char'"
Questa stringa mi funziona, ovvero si compila, ma restituisce caratteri geroglifici
myGLCD.print((char*)c , CENTER,120);
scusate se a volte vedete la variabile "dato" o "c", sono prove...
Più che altro temo che tu non abbia chiara la differenza tra char e char* il primo è un carattere, il secondo un puntatore a una stringa, ossia caratteri che terminano con il carattere /0.
Se la print() vuole un char* non puoi fare il cast, devi creare una stringa che contiene il tuo carattere seguito da /0.
Quindi prova qualcosa del tipo (scusa per eventuali errori ma dal cellulare è scomodo ):
char buf[]="."; // Inizializza stringa con un carattere
buf[0]=c; // imposta il primo carattere
myGLCD.print(buf, CENTER,120);
Grazie,
no, non sapevo la differenza dell'*..... fatto come dici, compila, ma appare sempre un carattere geroglifico, ora cerco eventuali errori...
Grazie
No, io non riesco, ho fatto delle prove, ma non capisco come fare, speravo di trovare un esempio in rete, ma non trovo nemmeno quello. Come hai fatto tu Alex, praticamente hai assegnato al primo carattere dell'array buf il char "c", ma è come prima che stampavo c... Poi quello che arriva dalla seriale non è un carattere solo, è una risposta di un modulo bluetooth, quindi è di diversi caratteri, allora già la char "c" è un array? Altrimenti come fa a stamparne diversi? Sul display quando stampo, ne scrive uno solo (geroglifico)...
Grazie per gli aiuti
Ciao,
finalmente ho trovato un esempio in rete, e sono riuscito a stampare i caratteri sul display, questo il codice:
void loop()
{
if (Serial.available()) { // il serial monitor riceve un dato?
c = Serial.read(); // la lettura viene salvata in un CHAR c
dato[conta] = c; //copio i dati letti in CHAR dato
conta++; // incrementa di 1
myGLCD.print(dato, 10, 100); // stampo sul display
}
}
Ora però incontro un'altro problema, l'array "dato" l'ho impostato a 20 caratteri (per esempio), però dopo che ho scritto sul display 20 caratteri, si pianta tutto, sicuramente perchè arduino va a scrivere in altre variabili, come si fa ad azzerare il contatore? Ho provato fuori dall'if ad assegnare zero alla variabile "conta", ma non funziona, dove va fatto?
Grazie ancora a tutti
thedrifter:
Come hai fatto tu Alex, praticamente hai assegnato al primo carattere dell'array buf il char "c", ma è come prima che stampavo c...
Assolutamente no. Scusa, ma chi non ha mai programmato in C questa differenza non è mai chiara, ora ci riprovo così vediamo se riesco a spiegarmi:
char pippo = 'A';
char pluto[] = "A";
Sembrano la stessa cosa, ma nel primo esempio la variabile "pippo" contiene un byte con il codice del carattere 'A' ovvero il valore 65.
Nel secondo pluto è implicitamente un "char *" ossia un "puntatore a caratteri" ossia la variabile "pluto" contiene un INDIRIZZO di memoria, che in quella inizializzazione è automaticamente allocata con 2 byte, il primo con il carattere 'A' il secondo col carattere NULL (ossia codice zero, o \0).
Quindi se una funzione vuole un parametro di tipo "char *" significa che vuole trovare un INDIRIZZO che punti ad una zona di memoria che, se interpretata come stringa, contiene una sequenza di byte ossia caratteri, con il terminatore NULL.
Per cui no, non è "come prima che stampavi c" perché se alla print() mandi la variabile "c" che contiene il codice ASCII del carattere che vuoi stampare, la funzione lo interpreta come un INDIRIZZO e a quell'indirizzo in memoria ci sarà "robaccia" fuori dal tuo controllo.
Ora dici:
thedrifter:
finalmente ho trovato un esempio in rete, e sono riuscito a stampare i caratteri sul display
Bene sono contento per te, ma non mi è comunque chiaro cosa tu abbia fatto, anche perché non ci fai vedere come hai inizializzato la variabile, e quindi in cosa sia differente dall'esempio che ti avevo scritto.
Tu parlavi di visualizzare un carattere per volta per cui nel mio esempio ti avevo fatto inizializzare la variabile buf come:
char buf[]=".";
il che significa fare un array con 2 caratteri, quindi il punto iniziale è seguito implicitamente dal carattere terminatore di stringa \0. Ossia equivale a:
char buf[2];
buf[0]='.';
buf[1]=0;
l'array "dato" l'ho impostato a 20 caratteri (per esempio), però dopo che ho scritto sul display 20 caratteri, si pianta tutto, sicuramente perchè arduino va a scrivere in altre variabili, come si fa ad azzerare il contatore?
Immagino quindi tu abbia fatto una cosa del tipo:
char dato[20];
Se hai un carattere per volta da leggere, lo devi visualizzare in posizioni diverse dello schermo, e per fare questo nel tuo codice accumuli i caratteri dentro all'array, che stampi sempre nella stessa posizione quindi ti funziona. Ma OVVIAMENTE al ventesimo carattere vai a sovrascrivere il terminatore \0, e quindi la funzione si ferma al primo byte a zero che trova nelle locazioni di memoria successive che chissà cosa contengono, e da qui le "schifezze"!
Per cui se vuoi stampare un carattere per volta devi fare qualcosa del tipo:
char dato[2];
int x = 20; // Posizione iniziale
void loop()
{
if (Serial.available()) { // il serial monitor riceve un dato?
c = Serial.read(); // la lettura viene salvata in un CHAR c
dato[0] = c;
dato[1] = 0; // il terminatore NULL (puoi anche metterlo nel setup() basta farlo una sola volta)
myGLCD.print(dato, x++, 100); // stampo il carattere sul display
}
}
Ovviamente qui stamperebbe tutti i caratteri ma attenzione al numero di caratteri che visualizzi, a un certo punto "escono" dallo spazio dello schermo e devi gestire la cosa.
Va bene anche accumulare dentro una stringa i caratteri ricevuti e poi in base al formato (ad esempio attendendo un carattere terminatore come \r) visualizzare l'intera stringa, e lsa successiva la mostrerai o nella stessa posizione o devi scendere di riga.
Ma devi sapere quanti caratteri al massimo riceverai, sia per lo spazio da dedicare a video sia per l'eventuale buffer che diventerebbe qualcosa del tipo:
char dato[60];
int pos = 0;
void loop()
{
if (Serial.available()) { // il serial monitor riceve un dato?
c = Serial.read(); // la lettura viene salvata in un CHAR c
if ( c != '\r' ) { // Non ho ricevuto la fine dato, accumulo
dato[pos++] = c;
dato[pos] = 0;
} else { // Ricevuta la fine del dato, lo visualizzo
myGLCD.print(dato, 10, 100);
pos = 0;
}
}
}
Infine, ho scaricato la UTFT ed ho visto che accetta anche variabili di tipo String, per cui puoi pensare di usare quelle, che forse ti risultano più comode da usare:
void print(char *st, int x, int y, int deg=0);
void print(String st, int x, int y, int deg=0);
String dato="";
void loop()
{
if (Serial.available())
{
c = Serial.read();
if ( c != '\r' )
dato = dato + c; // Non ho ricevuto la fine dato, accumulo
else { // Ricevuta la fine del dato, lo visualizzo
myGLCD.print(dato, 10, 100);
dato = "";
}
}
}
Ciao Alex,
grazie della minuziosa spiegazione, ho capito quasi tutto, il resto me lo studio... Però qualcosa è sempre strano... Ho risolto un po' di cose, ma alcuni problemi mi restano; il discorso di svuotare il contatore e il puntatore l'ho risolto così, in questo modo ogni stringa ricevuta, cancello e riscrivo la nuova, e non arrivo mai a superare i 20 caratteri, ho usato while, è corretto? Io non devo visualizzare un carattere per volta, ma l'intera stringa, che a volte sono 2 caratteri (un OK) e a volte alcune informazioni di risposta, magari di 10 caratteri...
char dato[20] = ""; // array per caratteri ricevuti dal modulo
byte conta = 0;
char c;
if (Serial1.available())
{
myGLCD.setColor(0, 128, 0); //colore sfondo rettangolo
myGLCD.fillRoundRect (1, 100, 600, 115); //misure del rettangolo
while (Serial1.available()) // Controlla se il bluetooth riceve qualche dato
{
c = Serial1.read(); // Il dato va in una variabile di tipo char
Serial.write(c); // Scrive sul terminale i dati ricevuti
dato[conta] = c;
conta++; // incrementa di 1
myGLCD.setColor(255, 255, 255); // imposta colore scritta
myGLCD.print(dato, 10, 100);
}
conta = 0;
}
I problemi rimasti sono due, il primo è cancellare la riga stampata, se noti nel codice, disegno un rettangolo con sfondo colorato (che poi sarebbe nero), ma la prima stringa che ricevo, va bene, disegna il rettangolo e ci scrive dentro, ma alla successiva stringa, il colore del rettangolo non copre la stringa, ora devo provare con dei delay, che magari è un problema di velocità??? Ho provato anche a scrivere una riga con gli spazi, per cancellare la precedente, ma non funziona; quindi mi trovo che se la scritta precedente è 10 caratteri e la successiva 2, mi rimangono in vista gli 8 precedenti...
Il secondo problema è (se possibile) nascondere i 2 caratteri di terminazione stringa, che mi vengono stampati come 2 caratteri geroglifici Oppure ricancellarli appena scritti... Quei caratteri servono al BT sia per accettare i comandi e poi li rimanda anche lui nelle risposte...
Se avessi la stringa sempre lunga uguale, ok, sarebbe facile cancellarli, ma essendo sempre variabile, non mi viene in mente nulla.
Grazie ancora della disponibilità, mi sei stato di grande aiuto
Ciao,
rettifico un problema, per la cancellazione della riga, non è un problema di cancellazione, ma bensì il mio buffer "dato" che rimane pieno dei vecchi caratteri... Come si svuota un array? non sto trovando soluzioni in rete...
thedrifter:
... Come si svuota un array? non sto trovando soluzioni in rete...
Con un ciclo for che lo riempie di 0x00
Guglielmo
Grazie Guglielmo,
pensavo ci fosse un'istruzione specifica, così va
Rimane solo il problema di cancellare gli utlimi due caratteri, che sono il terminatore....
Grazie ancora
In realtà è un NON problema ...
... immagina una stringa in 'C' ... è un array che contiene i caratteri della stringa e che come ultimo carattere, per indicare che la stringa è finita, usa 0x00.
Bene ... se vuoi cancellare tutta la stringa cosa fai ? ... in realtà una cosa banale, scrivi 0x00 nella PRIMA posizione dell'array ... e basta.
Qualunque funzione che va a leggere quella stringa, leggerà come primo carattere 0x00 e ... considererà già finita la stringa ... ovvero una stringa vuota.
Guglielmo
thedrifter:
Il secondo problema è (se possibile) nascondere i 2 caratteri di terminazione stringa, che mi vengono stampati come 2 caratteri geroglificiOppure ricancellarli appena scritti...
Prova questo e fammi sapere (dò per scontato che come terminatore tu abbia la sequenza CR+LF ossia \r \n):
while (Serial1.available()) // Controlla se il bluetooth riceve qualche dato
{
c = Serial1.read(); // Il dato va in una variabile di tipo char
Serial.write(c); // Scrive sul terminale i dati ricevuti
if ( c != '\n' ) { // Ignora i Line Feed
if ( c != '\r' ) { // Se non ho ricevuto il terminatore CR, accumulo il carattere
dato[conta] = c;
conta++; // incrementa di 1
} else { // Se ho ricevuto un terminatore, mostro il risultato
myGLCD.setColor(255, 255, 255); // imposta colore scritta
myGLCD.print(dato, 10, 100);
conta = 0;
for (int i=0; i< 20; i++)
dato[i] = 0;
}
}
gpb01:
Bene ... se vuoi cancellare tutta la stringa cosa fai ? ... in realtà una cosa banale, scrivi 0x00 nella PRIMA posizione dell'array ... e basta.
Vero, in casi normali, ma in questo caso lui imposta il valore di ogni singolo carattere senza aggiungere 0x00 dopo, per cui o mette tutti 0x00 come nell'esempio che ho postato, oppure fa qualcosa del tipo:
dato[conta] = c;
dato[++conta] = 0;
docdoc:
... per cui o mette tutti 0x00 come nell'esempio che ho postato ...
... che è la prima cosa che gli ho detto di fare ... post #13
Guglielmo
Esatto Alex;
devo mettere tutti a 0, altrimenti mi rimane comunque nella stampata successiva, infatti non capivo cosa voleva dire Guglielmo, ora ho capito Comunque ho usato un for, tutto molto semplice...
Si i caratteri di termine sono \r\n, adesso provo come mi hai suggerito.
Grazie