Usare un display LCD seriale I2C

saverio13:
... La versione nuova scaricata con aggiornamento fatta circa 10 giorni fa è "Arduino-Nightly" ...

... e come ti viene in mente di usare una versione "Arduino-Nightly" ? ? ? :o

L'ultima versione ufficiale è la 1.8.13, quindi scarica quest'ultima e verifica con essa ... anche se io credo tu potresti avere problemi sul tuo disco e quindi sarebbe meglio fare un'installazione "portable" (... prova a guardare QUI) che rende l'installazione indipendente da qualsiasi "porcheria" ci possa essere sul disco.

Guglielmo

saverio13:
La versione vecchia del programmatore era "Arduino 1.0.1". (con questa sono riuscito a programmare il micro)
La versione nuova scaricata con aggiornamento fatta circa 10 giorni fa è "Arduino-Nightly" (con questa versione non mi funziona).

La 1.0.1 è vecchissima, mi meraviglia che ti funzioni, ma comunque NON scaricare mai le Nightly build, sono compilazioni "continue" per test e sviluppo, ma scarica SEMPRE solo l'ultima versione rilasciata, che ora è la 1.8.13 e che a me funziona con tutto (Uno, Mega, Nano, AtTiny...)! E poi da dove l'hai scaricata, ed hai scaricato l'installer o la versione portable (consigliatissima!)?
Provala e vedi se con questa funziona.

PS: Guglielmo mi ha anticipato, ma lascio comunque il post :wink:

Ogni volta che aprivo il programmatore di Arduino, mi si invitava ad aggiornare la versione.
L'ho fatto e mi è uscito la versione Arduino-Nightly che non sapevo l'esistenza e che immaginavo fosse l'ultima versione. Nel pomeriggio la cancello e seguirò i vostri consigli.

Saverio.

Ieri ho scaricato la versione 1,8.13 di Arduino. Tutto OK.
Poi, ho inserito nel programma del display I2C il controllo di una stampantina termica TTL. Funziona perfettamente.
Nello scrivere un avviso sul display, mi compaiono dei quadratini non voluti. Non riesco a toglierli.
Avete dei suggerimenti?

Grazie da Saverio.

https://imgur.com/5izrdXu

Non hai postato il tuo codice, comunque direi che quando scrivi sull'LCD tu stai usando la println() che aggiunge i caratteri di fine linea \r e \n che sull'LCD vengono renderizzati come caratteri "spuri": non usare println() ma solo print().
Se non risolvi neanche così, posta il tuo codice e vediamo se c'è altro.

Ormai lo sapete già che mi perdo in un bicchiere di acqua.
Qualche post fa ho detto che il mio Arduino Nano era "fuori di testa". Mi sbagliavo, sono io da" curare".

Grazie docdoc. Con una riga di spiegazione hai risolto il mio problema. Ora il display è tutto OK.
A questo punto posso proseguire completando il programma con l'acquisizione di dati da un connettore di una stampante parallela.

Restate inchiodati al monitor, poichè non è escluso che avrò ancora bisogno di voi.

Saverio.

Per cortesia, datemi ancora un aiuto e poi con questo argomento non vi stresso più.
Al programma precedente ho aggiunto il controllo di una stampante termica seriale TTL.
Quasi tutto OK. Il display fa il suo dovere, la stampante stampa correttamente l'intestazione programmata della pagina, ma quando scrivo un testo sulla tastiera della mia macchina, mentre il testo viene visualizzato bene sul display, la stampante mi scrive un solo carattere per riga.
L'istruzione di stampa è "mySerial.println(rx);" Se sostituisco l'istruzione con "mySerial.print(rx);", non ottengo nessun testo scritto.

Faccio presente che lo stesso programma con display 24x2 con ingresso parallelo, la stampante funziona correttamente.
Dove sbaglio?

Grazie da Saverio

//                                Il display è OK  - Stampa un carattere e va a caporiga.
//                                 Inizializzazione display LCD
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);


char rx; // il valore letto
int num = 0; // numero di caratteri scritti nella riga
int riga = 0; // numero righe scritte
#define COLONNE 20
#define RIGHE 4
//                                        Inizializzazione stampante termica seriale TTL
#include <SoftwareSerial.h>
#define RX 13
#define TX 12
SoftwareSerial mySerial(RX, TX); // pin RX=13 e pin TX=12


void setup()
{
lcd.begin();
lcd.backlight();
//                                           Pin controllo display

DDRD = (INPUT); // configura la porta D come ingresso
pinMode(A5, OUTPUT); // pin 24 – A5 Arduino per display (SCL)
pinMode(A4, INPUT); // pin 23 – A4 Arduino per display (SDA)
//                                            Pin controllo stampante
pinMode(A0, INPUT); // strobe stampante
pinMode(A1, OUTPUT); // busy stampante

//  lcd.setCursor(0, 0);

//                                         controllo porta seriale stampante
// pinMode(13, INPUT); // pin porta seriale RX
pinMode(15, OUTPUT); // pin porta seriale TX
mySerial.begin(9600);


//                                          Inizializzazione messaggi su stampante
mySerial.println(" Saverio");
mySerial.println(" Trieste 1980");

mySerial.println(" "); // avanzamento della sola carta stampante
mySerial.println(" ");
mySerial.println(" ");

//                                         Inizializzazione messaggio su display

lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Trieste 1980");
delay(500);
lcd.setCursor(0,1);
lcd.print(" ore 12.30");
delay(500);

lcd.setCursor(0,2);
lcd.print(" Oggi e' mercoledi'");
delay(500);
lcd.setCursor(0,3);
lcd.print("Domenica sara' sole");

delay(500); // ritardo 0,5 secondi
lcd.clear();

}
void loop()
{

//                                                leggi dato ingresso porta parallela
digitalWrite(A1, LOW); // metti a 0 il busy
if (!digitalRead(A0)) // ingresso strobe
{
digitalWrite(A1, HIGH); // metti a 1 il busy
delay(10);
rx = (digitalRead, PIND); // digitalRead (PIND,puls); // leggi dato da inviare al display
{

//                                             per i caratteri stampabili

lcd.setCursor(num++, riga);
if (rx > 19) // se valore ASCII uguale o minore di 9, non memorizzare
lcd.print(rx); // Visualizza dato su display
if (rx > 9) // se valore ASCII uguale o minore di 9, non memorizzare
mySerial.println(rx); // stampa dato su stampante - Mi stampa un solo carattere per riga

//                                    adesso calcolo la nuova posizione del cursore
if (num >= COLONNE)

{

//                                        oltre la fine del display
num = 0;
riga++;

//                                    indietro carrello, avanti riga, come sulle macchine da scrivere
if (riga >= RIGHE)

{

// fine display

riga = 0;

lcd.clear();  //   indietro alla prima riga

}
//                                           svuoto la riga

lcd.setCursor(0, riga);
lcd.print(" ");
}
}
}
}

Intanto ...
... la differenza tra i metodi print() e println() è che il primo NON invia il terminatore di linea (CR), mentre il secondo si. Detto questo ti ricordo che, normalmente le stampati memorizzano i vari caratteri ed alla ricezione di CR stampano la riga.

Ora, è chiaro che se tu, ad ogni carattere, fai un println(), ti viene stampato il carattere e poi viene fatto il passaggio alla riga successiva, mentre se fai solo print() il carattere viene memorizzato nella stampante e rimane li ... in attesa del CR.

Detto questo è sufficiente che, usando il metodo print() per i vari caratteri, fai un println() a vuoto (che invia solo il CR), quando vuoi che venga effettivamente stampata tutta la riga e venga fatta avanzare la carta.

Guglielmo

Stavo scrivendo la mia risposta ma Guglielmo mi ha anticipato, per cui aggiungo solo qualche ulteriore dettaglio e precisazione :wink:

Come detto, se scrivi "mySerial.println(rx);" stai scrivendo il contenuto nella variabile "rx" (che è composto da un solo carattere) ed i caratteri di "fine linea" "\r\n" ossia \r ha valore 13 ed è CR, Carriage Return o "ritorno carrello", e \n ha valore 10 ed è LF, Line Feed o "avanzamento linea". Questo significa che una stampante va a capo dopo ogni carattere.

Se scrivi invece "mySerial.print(rx);" va bene perché stampi solo il carattere, ma suppongo che la tua stampante stampi la riga solo quando è finita, come ha scritto anche Guglielmo, per cui dovresti fare un "mySerial.println();" quando sai che la riga è finita.

Ma, e questo forse è sfuggito a Guglielmo, dato che tu mandi alla stampante il carattere solo se "(rx > 9)", sarebbero inclusi anche \r e \n, se li ricevi. Per cui devo supporre che non ti arrivino questi caratteri dalla seriale, devi verificare meglio esattamente cosa ricevi ossia se c'è terminatore di riga o no.

In ogni caso non so quale editor tu stia usando, ma ti prego, indenta il codice!!! Questa è ormai una FAQ, comunque ecco la spiegazione:
"Indentare correttamente il codice non è una questione estetica, ma assolutamente pratica in quanto serve per renderlo più rapidamente leggibile e comprensibile in quanto consente di identificare la sua struttura senza dover cercare di capire dove iniziano e finiscono i vari blocchi di codice, e ciò è utile sia all'autore per fare debug quando qualcosa non sembra funzionare ma anche per poterlo modificare dopo qualche tempo, sia per chi, come noi, cerca di aiutare a risolvere qualche problema.
Per farlo, basta premere Ctrl-T nell'IDE di Arduino ed il codice sarà correttamente indentato in automatico, e da quel momento cerca di mantenere la stessa logica."
Aggiungo pure che rende il codice poco leggibile anche aggiungere troppe righe vuote inutili (per separare due "blocchi" di codice ne basta una) o mettere dei commenti con decine di spazi o molto lunghi (i commenti finiscono molto a destra nello schermo, meglio metterli "vicini" a ciò che si intende commentare, quindi o sull'istruzione stessa se è corta e lo è anche il commento, altrimenti sulla riga precedente, e diviso in più righe se il commento è lungo).

docdoc:
... "Indentare correttamente il codice non è una questione estetica, ma assolutamente pratica in quanto serve per renderlo più rapidamente leggibile e comprensibile in quanto consente ...

... bella! Questa te la "rubo" e la metto nel regolamento :wink:

Guglielmo

gpb01:
... bella! Questa te la "rubo" e la metto nel regolamento :wink:

Grazie. :wink:
Ovviamente sentiti libero di adattarla ed estenderla come meglio credi :smiley:

docdoc:
Ovviamente sentiti libero di adattarla ed estenderla come meglio credi :smiley:

Punto 17.2 richiamato anche nel punto 14 :wink:

Guglielmo

Grazie per le rapide risposte.
Mi sento più sicuro con due insegnanti come voi.
Conosco l'uso dei comandi “CR” e “LF”, li ho usati in Assembler nella programmazione del micro della scheda che fa la maggiore parte del lavoro.
Al prossimo post spiegherò completamente il mio lavoro con la foto dell'apparecchiatura finita.

Ritornando al mio problema, ecco un esempio di scrittura.
Se scrivo “ciao” e premo il tasto di stampa, ottengo:
Sul display, ottengo “ciao”
Sulla stampante ottengo con l'istruzione mySerial.println:
c
i
a
o
Con l'istruzione mySerial.print la stampante non stampa nulla.
Faccio presente che lo stesso programma con Arduino e un display 24x2 con ingresso parallelo, ottengo una stampa corretta.
Tutti questi miei problemi sono sorti con l'uso del display I2C. (naturalmente per mia ignoranza).
In origine, il testo veniva inviato ad una stampante con ingresso parallelo.
Dal programma “principale” è già compreso “CR” quando chiedo la stampa della riga.
Arduino legge il testo dal connettore centronics e lo elabora come avete già visto.
Con Arduino, ho cercato di leggere esattamente quello che gli arriva prima della stampa, ma non ho avuto nessun risultato per vedere i codici di stampa.
Saverio.

T'ho già scritto che, per ogni singolo carattere stampabile DEVI usare print(), quando è finita la riga e vuoi che la stampante la stampi e vada a capo DEVI fare un println().

Modifica il codice e prova!

Guglielmo

OK. nel pomeriggio provo.
Ora che ci penso, non posso fare come suggerito, poichè il comando di stampa arriva dalla scheda principale e viene letto ed eseguito da Arduino. Devo controllare.

Saverio.

E' giusto rendere pubblico e in modo completo il lavoro che mi aiutate a completare.
La mia apparecchiatura è un convertitore Braille-ASCII che ho progettato, programmato in Assembler e fatto più di 30 anni fa.
Il circuito leggeva i tasti di una macchina dattilo Braille per non vedenti, traduceva i caratteri Braille in caratteri ASCII e li inviava ad una stampante per PC con ingresso parallelo.
Qualche mese fa, ho ricevuto una richiesta di aiuto da un amico. Aveva bisogno di una apparecchiatura simile per imparare il Braille.
Data l'insistenza, ho raccimolato dai miei cassetti, una scheda che ho usato allora e la ho completata con Arduino Nano, un display I2C e una stampantina termica TTL (non si trova più stampanti con ingresso parallelo).
Arduino deve leggere, dal connettore della stampante parallela, i caratteri digitati sulla tastiera Braille e inviarli al display ed alla stampante termica TTL.
Mi è stato difficile ricordare i particolari del programma in Assembler ma con il vostro aiuto sto completando il lavoro.
Naturalmente tutto il mio lavoro per l'amico è gratis. (Salvo i nuovi componenti acquistati).
Ecco le foto:

Saverio.

Beh complimenti per il progettino visto anche il suo lodevole scopo.

Per cercare di risolverti il problema, hai informazioni tecniche relative alla stampantina TTL? Magari un link al prodotto ed al manuale con le specifiche tecniche?

Ad esempio, se tu non hai un terminatore di riga e la stampante stampa solo quando la riga è completa ossia riceve un carattere di fine linea (e qui potrebbe essere solo \r o solo \n o entrambi, anche per questo servono le specifiche) potrebbe non essere possibile con quel modello specifico.

Ma, restando in termini generali, è anche possibile che dopo ogni carattere ti basti mandare \r seguito da un numero di spazi pari alla posizione corrente del "cursore" per riportare la "testina" al punto dove dovrà stampare il prossimo carattere. Ma non hai alcun modo per dare un "invio" o "a capo" dalla tastiera, anche solo con un carattere speciale che tu "tradurresti" in "\r\n"?

Oppure cambiare stampantina?

Direi che la stampante funziona perfettamente.
La stessa stampante la ho usata con lo stesso programma su altro Arduino e display 24x2 parallelo e stampa la riga e va a caporiga ogni volta che do il comando di stampa. In questo caso mi stampa sia sul display che sulla stampante un punto interrogativo ad inizio frase ogni volta che do il comando di stampa. Ma questa è un'altra storia che per il momento non ci penso.

Il problema attuale che più mi interessa, è sorto dopo che ho inserito la parte stampante nel programma del controllo del display I2C 20x4. E' forse un caso?

Ho un'altra stampante TTL di altra marca, ma se ricordo bene mi da lo stesso risultato. comunque la proverò.
Purtroppo sulla programmazione di Arduino ne so veramente molto poco e mi interessa di lui solo quando devo risolvere qualche problema elettronico. Infatti su questi particolari mi perdo.

Saverio.

Questa sera ho provato a sostituire la stampante TTL con una di diversa marca. Il risultato non è cambiato.
Se voglio scrivere "ciao", I singoli caratteri vengono stampati ognuno su una riga diversa, mentre sul display viene scritto "ciao".
Una curiosità. Se scrivo diverse frasi con il comando "stampa" per ognuna, le frasi sul display vengono visualizzate correttamente tutte con uno spazio tra le frasi fino a riempire la riga. E' giusto?
Es. se scrivo:
ciao "stampa" Saverio "stampa" casa "stampa"

Sul display sarà scritto : ciao Saverio casa

Sulla stampante:
c
i
a
o

S
a
v
e
r
i
o

c
a
s
a

Saverio

Ancora una precisazione che dovevo fare prima.
Appena accendo Arduino, come inserito nel programma, sia il display che la stampante visualizza una intestazione iniziale con il nome del convertitore.
Sia il display che la stampante presentano questo nome correttamente.
Dopo, quando scrivo sulla tastiera, interviene il problema evidenziato nei post precedenti.

Saverio.