Problema Scarico Seriale RS232C

Buongiorno,
sono nuovo del gruppo e volevo chiedervi un consiglio, ho l'esigenza di comunicare attraverso arduino con una centralina con protocollo RS232C handshake, sono riuscito nel primo passo di mettere la centralina in modalità trasmittente attraverso i pin RTS e DTR di arduino ad HIGH, automaticamente la centralina mi risponde ponendo i suoi pin RTS e DTR a HIGH; ora l'ultimo step prevederebbe tramite hypeerterminal l'invio di un comando "last", e vorrei inviarlo piuttosto con hyperterminal con arduino, ma quando uso il comando Serial.Print("last") o Seriale.Write(last) sul comando Serial.Read non compare nulla, come posso risolvere il problema?
Dovrei inviarlo come una stringa di bit?
Se volete vi invio screen centralina e bozza di programma.

Buongiorno e benvenuto, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Normalmente la RS232 si usa senza handshake. Visto che l' elaborazione dei dati ricevuti é molto veloce non é necessario avere la possibilitá di fermare la trasmissione.

Ciao Uwe

Non è che la centralina si aspetta un terminatore di linea? Come avevi programmato HyperTerminal? inviava per caso il CR o il LF alla fine?

Perché, in tal caso, devi usare Serial.println("last"); che automaticamente aggiunge il terminatore.

Guglielmo

Buongiorno al gruppo,
vi allego lo screen della centralina: velocità 38400, 8N1, RTC/CTS; tramite hyperterminal su ubuntu si digita il comando last per far si che la centralina invii tutto il suo contenuto; il problema che riesco tramite DTR alto a mettere la centralina in questa configurazione, ma al momento di inviare "last"con serial.write non riesce ad inviare nulla.

#define RTS 2
#define CTS 3
#define DTR 4
#define DSR 5
#define START 6

bool valore_START = LOW;


void setup() {
  pinMode(RTS, OUTPUT);
  pinMode(CTS, INPUT);
  pinMode(DTR, OUTPUT);
  pinMode(DSR, INPUT);
  pinMode(START, INPUT);
  Serial.begin(38400);
  delay(15000);
  Serial.write("last");
}

void loop() {

  String stringa = Serial.readString();
  Serial.println(stringa);

}

Forse dovrei inviare la stringa in formato binario?

eric1986:
... Forse dovrei inviare la stringa in formato binario?

Scusa ma che vuol dire?

La tua stringa è comunque una serie di bit che vengono inviati lungo un filo ...
... che vuol dire "in binario" ? ? ?

Guglielmo

P.S.: Se quell'affare vuole un handshaking hardware, Arduino semplicemente NON lo gestisce.

eric1986:
Buongiorno al gruppo,

....

Nella trasmissione manca il ritorno a capo, che ti era già stato consigliato

Solitamente DTR CTS si ponticello nella scarpetta del connettore e morta li

Buongiorno, ho apportato modifica al programma:

/* Conversione LAST = [ 01001100 01000001 01010011 01010100 ]
 * Conversione last = [ 01101100 01100001 01110011 01110100 ]
 * 
 * 
 * 
 */

#define RTS 2
#define CTS 3
#define DTR 4
#define DSR 5
#define START 6

bool valore_START = LOW;


void setup() {
  pinMode(RTS, OUTPUT);
  pinMode(CTS, INPUT);
  pinMode(DTR, OUTPUT);
  pinMode(DSR, INPUT);
  pinMode(START, INPUT);
  digitalWrite(RTS, HIGH);
  digitalWrite(DTR, HIGH);
  Serial.begin(38400);
  delay(15000);

}

void loop() {

  Serial.write("l", BIN);
  Serial.write("a", BIN);
  Serial.write("s", BIN);
  Serial.write("t", BIN);


  //Serial.write("076 097 115 116");
  String stringa = Serial.readString();
  Serial.println(stringa);

}

Certo ponticellerò i pin RTS,DTR e DCD, su questo ci siamo, tanto è una modifica hardware al filo seriale.

E funziona?

Ti accetta di stampare in binario una stringa?

Bizzarro

Comunque continui a non mettere il ritorno a capo

Ci rinuncio ... non c'è peggior sordo di chi non vuol sentire ... ::slight_smile:

Guglielmo

Ecco le modifiche richieste:

/*
   Conversione LAST = [ 01001100 01000001 01010011 01010100 ]
   Conversione last = [ 01101100 01100001 01110011 01110100 ]
*/

#define RTS 2
#define CTS 3
#define DTR 4
#define DSR 5
#define START 6

bool valore_START = LOW;


void setup() {
  pinMode(RTS, OUTPUT);
  pinMode(CTS, INPUT);
  pinMode(DTR, OUTPUT);
  pinMode(DSR, INPUT);
  pinMode(START, INPUT);
  digitalWrite(RTS, HIGH);
  digitalWrite(DTR, HIGH);
  Serial.begin(38400);
  delay(15000);

}

void loop() {

  //Invio Stringa last in BIN
  Serial.write('l');
  Serial.write('a');
  Serial.write('s');
  Serial.write('t');
  Serial.write('\n');


  /*  Invio Stringa LAST in BIN
    Serial.write('L');
    Serial.write('A');
    Serial.write('S');
    Serial.write('T');
    Serial.write('\n');
  */


  String stringa = Serial.readString();
  Serial.println(stringa);

}

Aggiunto nel mio personale killfile

eric1986:
Buongiorno al gruppo,

eric1986:
Buongiorno al gruppo,
vi allego lo screen della centralina: velocità 38400, 8N1, RTC/CTS; tramite hyperterminal su ubuntu si digita il comando last per far si che la centralina invii tutto il suo contenuto

Siccome tu non sei un computer, tramite hyperterminal scrivi da "umano", quindi quello che spedisci è un testo "last" probabilmente seguito da carattere terminazione. (come ti è già stato detto).
Quindi Serial.write NON serve a un cappero (soprattutto per un testo è ininfluente).
write o print cambia per l'invio di un numero, write(32) invia il byte 32, print(32) invia 2 caratteri, '3' e poi '2'
Ovviamene le macchine comunicano a bit tra loro. la cosa viene fatta dalle macchine.

Devi fare Serial.print("last"); che è la stessa cosa che fa hyperterminal.
In più però devi vedere come è settato il tuo hyperterminal e vedere se manda anche un carattere di terminazione e QUALE o quali invia.
Di solito invia \n Quindi Serial.print("last\n"); ma magari serve anche \r

Se anche così non funziona, il problema può essere nella configurazione della seriale Serial.begin

Poi nel loop aggiungi una verifica se arrivato qualcosa prima di leggere

...
Serial.print("last\n");
if(Serial.available())
{ String stringa = Serial.readString();
  Serial.println(stringa);
}
...

Grazie tante,
altra domanda curiosa, se uso hyperterminal su ubunt devo digitare last come minuscolo, mentre se lo uso in windows last maiuscolo, secondo voi è case sensitive?

Lo devi chiedere e leggere nelle istruzioni di quel dispositivo.
Un linguaggio come il C è case-sensitive, ma quel last è un DATO, al linguaggio non frega nulla. Ci puoi scrivere pure pippo o pluto, mica lo analizza.
Secondo me c'e' qualcosa in quel dispositivo che capisce comandi diversi, su Windows secondo me viene inviato alla fine \r\n mentre su Linux solo \n

EDIT: corretto, grazie @docdoc

nid69ita:
Secondo me c'e' qualcosa in quel dispositivo che capisce comandi diversi, su Linux secondo me viene inviato alla fine \n\r mentre su windows solo \n

Caso mai il contrario, su Linux il terminatore è in genere solo \n, mentre Windows è \r\n (e non \n\r)... :wink:

Salve a tutti,
comunque volevo aggiornare il topic con il non funzionamento del programma, la cosa strana che la seriale risulta non avviata, in fatto nel code successivo viene stampato il valore KO.

  Serial.writeString("last\r");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \n");
  if (Serial.available())
  {
  Serial.println("OK");
  String stringa = Serial.readString();
  Serial.println(stringa);
}
else
{
  Serial.println("KO");
}

Voi che idea avete?

Ma ci stai prendendo in giro ? Ci stai trollando ?
writeString NON esiste per la classe/oggetto Serial.
Ti diciamo usa Serial.print() e te ne esci con un comando che non esiste, (basta guardare il reference)
E poi metti solo una parte del codice, non tutto, cosa possiamo dire ? Nulla senza vedere tutto il programma, magari l'errore è prima.

Ecco il programma completo:

/*
   Conversione LAST = [ 01001100 01000001 01010011 01010100 ]
   Conversione last = [ 01101100 01100001 01110011 01110100 ]
*/

#define RTS 2
#define CTS 3
#define DTR 4
#define DSR 5

void setup() {
  pinMode(RTS, OUTPUT);
  pinMode(CTS, INPUT);
  pinMode(DTR, OUTPUT);
  pinMode(DSR, INPUT);
  digitalWrite(RTS, HIGH);
  digitalWrite(DTR, HIGH);
  Serial.begin(38400);
  delay(15000);

}

void loop() {


  Serial.print("last\r");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    \n");
  if (Serial.available())
  {
  Serial.println("OK");
  String stringa = Serial.readString();
  Serial.println(stringa);
}
else
{
  Serial.println("KO");
}

}

Ma ti pare che possa essere significativo quel programma? Qui scrivi OK se ricevi un byte, indipendentemente dal COSA stai ricevendo. Inoltre lo fai nel loop() quindi sparando centinaia di volte al secondo la stringa "last". Ed infine non dai il tempo alla controparte di inviare nulla visto che la Serial.available() la chiami qualche millisecondo dopo aver mandato "last".

Vedi, nid69ita ti ha già dato delle utili indicazioni in precedenza, cerca di analizzarle, metterci del tuo e capire cosa stai facendo. Ma prima di tutto mi sa che devi stabilire bene cosa vorresti ottenere.

Tu devi mandare un comando via seriale ed attendere una risposta, e già questo è un argomento ampiamente affrontato sia qui sia in tanti tutorial che trovi anche in rete. Inizia usando dall'altra parte il monitor seriale (quindi ancora non la tua centralina) e vedi come si fa, con un piccolo sketch che accumula in un buffer (un char array, se non sai gestirli studiali, ed evita gli oggetti "String" con la "S" maiuscola...) tutti i caratteri ricevuti, e quando ricevi il carattere di fine linea ('\n', ignora eventuali a capo ossia '\r') rimandi sulla seriale quello che hai ricevuto.

Il secondo passo a questo punto è capire cosa ti aspetti di ricevere quando mandi "last" (seguito dal terminatore quindi usa println() non print() o altro): se è una serie di righe di testo, come immagino, non potrai considerare finito il dato al primo fine linea, ma devi identificare cosa riconoscere come "fine testo". Manda qui l'output del comando "last" che mandi alla cenralina con hyperterminal o putty così capiamo.

A quel punto dovrai scrivere il programma che, dopo che avrà mandato quel comando (per ora UNA sola volta, e nella setup), sia in gradi di acquisire tutta la risposta. Quindi "interpretare" la risposta (non so cosa tu debba farci). Ed infine, modificare il programma per mandare il comando "last" quando previsto (non so, a tempo? In base ad un certo evento? Cosa?).

Con questo, se non vedo progressi e buona volotà, io ho finito qui.