Leggere da una uscita parallela del Pc testi e inviarli ad un display LCD (bis)

Riprendo questo discorso dopo "soli" due anni.
In questi anni avevo abbandonato Arduino e ora mi ricordo ben poco del poco che sapevo allora.
A suo tempo avevo detto che tutto funzionava bene, cioè il carattere inviato all'Arduino/display venivano visualizzati.
Infatti avevo provato un carattere alla volta e tutto funzionava bene.
Oggi invece, ho la necessità di inviare attraverso la porta parallela, un testo di una riga con una ventina di caratteri.
Dolori. I caratteri stampati sono 1 ogni 4 caratteri usciti dalla porta parallela.
La stessa porta, collegata ad una una stampate, stampa regolarmente tutti i caratteri scritti.
Ora l'Arduino/display legge un carattere ogni 4 come se non riesca a sincronizzare l'invio dei dati.
Probabilmente, non è sincronizzato il busy e strobe nel programma.
C'è qualcuno che mi può aiutare?
Il listato incriminato lo si può leggere qua sopra nel post di nid69ita.
Grazie da Saverio.

>saverio13: REGOLAMENTO, punto 16.9 ...
... solo perché eri sempre tu nell'altro thread (QUESTO), ho diviso e lasciato in vita la tua domanda, che altrimenti sarebbe stata direttamente cancellata. :slight_smile:

NON si riaprono thread vecchi di più di 9/12 mesi (... in tantissimi casi difatti, i partecipanti del vecchio thread NON seguono più neanche il forum o NON esistono più come utenti), ma si apre un nuovo thread facendo riferimento al vecchio e ponendo le nuove domande. Grazie.

Guglielmo

Chiedo scusa per la mia disattenzione e ringrazio il moderatore per la sua pazienza.

Per comodità di chi mi vuole aiutare, inserisco il listato del programma.
Ho cercato di mettere dei delay dopo ogni riga per rallentare la lettura dei caratteri inviati aa Arduino e al display, ma questi ritardi non vengono visti dal programma.
C’è un modo per eseguire il programma passo passo?

Saverio.

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 13, 8, 9, 10,11);
int prova = 0; //  variabile prova
int puls = 0; //  variabile lettuta dato da inviare al display
void setup() {
  DDRD = INPUT; //  configura la porta D come ingresso
  pinMode(17, OUTPUT);  //  pin busy - Pin analogico
  pinMode(16, INPUT);   //  pin strobe - Pin analogico
  pinMode(15, OUTPUT);  //  led di prova - Pin analogico
  pinMode(19, OUTPUT);  //   solo prova
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
}
void loop() {
  digitalWrite(19, LOW);
  digitalWrite (17, LOW); //  metti a 1 il busy - rx disponibile
  prova = digitalRead(16); // controlla se strobe=0  - dato uscita tx  ronto
  if (prova == LOW)
  { digitalWrite (17, LOW); //  metti a 1 il busy - rx disponibile
    delay(2);
    puls = (digitalRead, PIND); // leggi dato da inviare al display
    digitalWrite (17, HIGH); //  metti a 1 il busy - rx non disponibilesolo per prova
    delay(10);
    //      trasformare il numero tasto in cararrere ASCII
    int i = puls; //   initializing variables
    char puls = char(i);
    // -------------------------------------
    if (puls >= 19) // elimina i caratteri di controllo stampante con valore meno del numero 19
    { lcd.print (puls);  //  presenta il dato sul display
      puls = 0;          //  azzera la variabile puls
    }
       }
       delay(2);
       }

saverio13:
C'è un modo per eseguire il programma passo passo?

... l'unico che mi viene in mente al volo è, invece di quei delay(), una piccola funzioncina in cui leggi dalla Seriale se uno preme "invio" e fino a quando non lo premi resta li in attesa, quando lo premi ritorna e il programma prosegue.

Quando vuoi fermare il programma la chiami e per farlo proseguire premi "invio" ...
... non è la soluzione "ideale" (... anzi, tutt'altro), ma ti permette di mettere delle pause da te controllate dove vuoi.

Guglielmo

I suggerimento della porta seriale per bloccare il ciclo può essere una buona idea.

Tra le mille prove che ho fatto, è risultato che se elimino i due fili Busy e Strobe che vanno dalla porta parallela ad Arduino, le cose non cambiano. Viene visualizzato nel display sempre 1 carattere ogni 4.
Quindi Arduino non vede queste due linee per la sincronizzazione dei caratteri.
Stesso discorso se elimino nel programma le linee che riguardano Busy e Strobe.

Ho riguardato il circuito.
Le linee Busy e Strobe sono collegate ad Arduino nella porta analogica A2 e A3.

Mi sembra che a suo tempo, la porta analogica poteva funzionare anche come digitale I/O. E' corretto oppure ho sbagliato.
Se è corretto, come devo nominare queste due porte nella configurazione iniziale?

Nel programma presentato, le ho configurate come:
pinMode(16,INPUT) per il Strobe
pinMode(17, OUTPUT) per il Busy.

Avete dei suggerimenti?

Saverio.

saverio13:
Se è corretto, come devo nominare queste due porte nella configurazione iniziale?

Nel programma presentato, le ho configurate come:
pinMode(16,INPUT) per il Strobe
pinMode(17, OUTPUT) per il Busy.

E' corretto ...
... nelle pinMode, per compatibilità con le varie schede, non mettere il numero di pin, ma metti direttamente il nome del pin analogico :

pinMode(A2, INPUT) per il Strobe
pinMode(A3, OUTPUT) per il Busy

Guglielmo

Dopo le modifiche suggerite, oggi ho fatto ancora qualche decina di prove. Delusione >:(
Probabilmente nel programma ci sono più errori.
Ora, vorrei procedere passo a passo ed eliminare un errore alla volta.

La prima cosa che vorrei risolvere, con il vostro aiuto, è capire perchè nel programma presentato sopra, i delay non vengono rispettati (meglio dire ignorati), sia che scrivo "delay(2);" che "delay(2000);".
Avete da suggerire il motivo di questo inconveniente?

Saverio

saverio13:

    puls = (digitalRead, PIND);

non ho capito cosa dovrebbe fare la riga che ho evidenziato....

docsavage:
non ho capito cosa dovrebbe fare la riga che ho evidenziato....

La riga citata legge i Byte della porta D

Ho letto nel manuale l'uso della funzione delay.
E' scritto che in alcuni casi il delay non viene riconosciuto poichè lo stesso delay non disabilita gli eventuali interrupt.
Faccio notare che nel listato non viene attivato nessun interrupt.

Saverio.

io non ho più nessun PC con porta centronics, però stanotte ho pensato un poco

tu tenti di rallentare il tuo programma, cosa non difficile come ti è già stato detto, ma in realtà dovresti accelerarlo, dato che hai delle perdite di dato, o almeno lavorare sulla sincronizzazione col PC

ho notato che non usi la linea nACK, io ho pensato che potresti collegarla per prova, tanto ne hai già fatte tante…

e vedere cosa succede con un programma come questo:

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 13, 8, 9, 10, 11);
int prova = 0; //  variabile prova
int puls = 0; //  variabile lettuta dato da inviare al display
void setup() {
  DDRD = INPUT; //  configura la porta D come ingresso
  pinMode(17, OUTPUT);  //  pin busy - Pin analogico
  digitalWrite(17, LOW); //busy fermo
  pinMode(16, INPUT);   //  pin strobe - Pin analogico
  pinMode(15, OUTPUT);  //  led di prova - Pin analogico
  pinMode(19, OUTPUT);  //   solo prova, vale nACK
  digitalWrite(19,HIGH); // nACK attivo
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
}
void loop() {
  //digitalWrite(19, LOW);
  //digitalWrite (17, LOW); //  metti a 1 il busy - rx disponibile
  prova = digitalRead(16); // controlla se strobe=0  - dato uscita tx  ronto
  if (!digitalRead(16))
  { 
   // delay(2); non serve Strobe indica valori stabili
    puls = (digitalRead, PIND); // leggi dato da inviare al display
    digitalWrite (17, HIGH); //  metti a 1 il busy - rx non disponibile
    //delay(10);
    // attivo lo nACK
    digitalWrite(19,LOW);
    // dovrebbe restarlo per 8 microsecondi, tentiamo cosa succebde a tenerlo basso a lungo
    //      trasformare il numero tasto in cararrere ASCII
    int i = puls; //   initializing variables
    char puls = char(i);
    // -------------------------------------
    if (puls >= 19) // elimina i caratteri di controllo stampante con valore meno del numero 19
    { lcd.print (puls);  //  presenta il dato sul display
      puls = 0;          //  azzera la variabile puls
    }
  }
  delay(2);
  // OK, dati elaborati
  // riportiamo Busy ed nACK al valore normale
    digitalWrite(19,HIGH);
    digitalWrite(17,LOW);
  
}

è il tuo, ho aggiunto un embrione di gestione dello nACK e cambiato due tempistiche, che non dovrebbero però influire

controlla bene i cablaggi, visto che il PC, o cosa sia sia, trasmette anche quando non dovrebbe, ergo non sente Busy o nACK

saverio13:
Tra le mille prove che ho fatto, è risultato che se elimino i due fili Busy e Strobe che vanno dalla porta parallela ad Arduino, le cose non cambiano. Viene visualizzato nel display sempre 1 carattere ogni 4.
Quindi Arduino non vede queste due linee per la sincronizzazione dei caratteri.
Stesso discorso se elimino nel programma le linee che riguardano Busy e Strobe.

Ho riguardato il circuito.
Le linee Busy e Strobe sono collegate ad Arduino nella porta analogica A2 e A3.

e poi questa mi ha dato da pensare

se manca Strobe il PC onn segnala trasmissione effettuata, tu leggi non per un sincronismo (handshaking col pc) ma perchè stai andando in free-running

infatti a linea strobe scollegata tu avrai ingresso sempre basso (magari c'é da pensare ad un pullup)

se invece manca il Busy (che è attivo alto) il PC non sente mai stampante impegnata, e mancando lo nACK crede di ricevere sempre ACK (ovvero dato acquisito) e parte a raffica..........

riguarda la parte HW tra PC e Arduino

Grazie docsavage, sicuramente farò le prove da te suggerite.
La scheda che invia i dati da centronics è gestita da un microprocessore a 4 MHz fatta 23-25 anni fa ed era solo per pilotare una stampante parallela.
A suo tempo per pilotare la stampante, usavo come controllo invio dati, solo Strobe e Busy. Sono i soli due segnali ora disponibili.
Ora, l'rx Arduino funziona a 16MHz, quindi dovrei essere tranquillo per quanto riguarda la velocità in ricezione.
Ho il sospetto, a parte la sincronizzazione, che la perdita dei dati, è dovuta anche per il tempo di l'invio degli stessi da Arduino e display.

Per prova, vorrei collocare dei delay nel programma, per bloccare per 1-2 secondi la ricezione tra un carattere e il successivo. Come posso ottenere questa funzione?

Per quanto riguarda la mia preparazione nel linguaggio di Arduino, è molto scarsa (e si vede :confused: ).

Saverio.

a maggior ragione, mancando nACK tutto il lavoro di timing lo deve fare Busy, controlla che sia OK

controlla che busy sia OK, a livello elettrico intendo

per sicurezza tieni alto Busy via Hw, se la scheda la hai fatta tu, non ti sarà difficile mettere un pulsante sulla linea Busy, così NON dovrebbe esserci trasmissione, se c'è hai qualche problema

controlla anche che la linea Busy sia realmente alta quando arduino la comanda

per il ritardo invece non c'è problema

lo vuoi mettere dopo il trattamento del segnale, o prima della ricezione?

a parte che in un loop poco cambia

se metty un delay come prima riga della loop lo "deve" eseguire

per conferma, visto che hai un led libero, per prove ed indicazioni, lo accendi prima della delay

e lo spegni dopo

tipo:

loop(){
digitalwrite....
delay....
digitalwrite...

e poi tutto quello che c'era scritto prima

devi vedere il led che si accende e spegne

ma torno a dire che il problema non mi sembra li

D'ora in poi ti tengo d'occhio. Mi sa che mi sarai di grande aiuto.
Dopo fatto le prove ti saprò dire.

Saverio.

Abbiate pazienza.
Mi sono nuovamente inchiodato nella programmazione della porta analogica.
Sto usando il pin analogico A2 come Strobe ed il pin analogico A3 come Busy (non ho altri pin digitali disponibili).
Come vanno usati questi pin, uno per ingresso digitale ed uno per uscita digitale?

Saverio.

esattamente come li hai usati tu.......

una scuola di pensiero dice di indirizzarli con i loro "nomi analogici" A1 A2 eccetera, ma non è obbligatorio

è spacciata come cosa utile per la compatibilità con altre schede

io invece credo che se usati come digitali proprio per compatibilità sia comodo tenere i numeri di uscita/ingresso digitale

visto che non è detto che per altre schede la corrispondenza piedino analogico-piedino digitale sia la stessa

casomai posta lo scketch attuale

docsavage:
esattamente come li hai usati tu.......

una scuola di pensiero dice di indirizzarli con i loro "nomi analogici" A1 A2 eccetera, ma non è obbligatorio

è spacciata come cosa utile per la compatibilità con altre schede

io invece credo che se usati come digitali proprio per compatibilità sia comodo tenere i numeri di uscita/ingresso digitale

visto che non è detto che per altre schede la corrispondenza piedino analogico-piedino digitale sia la stessa

casomai posta lo scketch attuale

Devo confessare che il listato di partenza era di 2-3 anni fa.
Non ricordo più niente di come l'ho realizzato e soprattutto non capivo da dove venivano fuori i pin 15, 16, 17, ecc.
Visto che il programma non funzionava ho rinominato quei pin in A1, A2, A3 ecc, ma il tutto continua a non funzionare.

Oggi mi si sono aperti gli occhi. Ho trovato in internet la tabella che allego.
Ora con più coraggio riprendo le prove.

Saverio.

io intanto ho dato una sistemata al codice

e aggiunto una stampa su seriale

magari vedi cosa succede

e controlla bene i cablaggio, secondo me il bacherozzo è li

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 13, 8, 9, 10, 11);
int puls = 0; //  variabile lettuta dato da inviare al display
#define busy 17
#define strobe 16

void setup() {
  DDRD = INPUT; //  configura la porta D come ingresso
  pinMode(busy, OUTPUT);  //  pin busy - Pin analogico
  pinMode(strobe, INPUT);   //  pin strobe - Pin analogico
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  Serial.begin(9600);
}
void loop() {
  digitalWrite (busy, LOW); //  metti a 0 il busy - rx disponibile
  if (!digitalRead(strobe))   {
    digitalWrite (busy, HIGH); //  metti a 1 il busy - rx NON disponibile

    int i = (digitalRead, PIND); // leggi dato da inviare al display

    //      trasformare il numero tasto in carattere ASCII
    char puls = char(i);
    // -------------------------------------
    if (puls >= 19) {
      // elimina i caratteri di controllo stampante con valore meno del numero 19
      lcd.print (puls);  //  presenta il dato sul display
      Serial.print(puls);
    }
  }
  else {
    // non ho ricevuto strobe
    // per ora non faccio nulla
    // ma il caso è da investigare


  }

}

se noti ho cominciato a esaminare il caso di mancato strobe, ma non so come uscirne

Ciao docsavage, Grazie dell’aiuto.
Mi sembra di capire che non posso usare la porta seriale, poichè trasmette e riceve attraverso i pin 0 e 1 di Arduino e non devono essere utilizzati per altre funzioni.
Questi due pin, sono usati per inviare i dati dalla porta parallela ad Arduino.
Questa notte riprendo le prove con più vigore e domani vi faccio sapere.

Saverio.

Giusto, hai ragione, non ci avevo fatto caso

Che pin liberi hai?