Risposte strane dalle serial

Buongiorno a tutti. Vi scrivo perchè mi compare una cosa molto strana con il seguente codice:

void serialEvent1() {
  //beep();
  while (Serial1.available()) {
    char str[12] = Serial1.readString();
    Serial1.flush();
    digitalWrite(att485, 1);
    Serial3.println(str);
    Serial3.flush();
    Serial1.println(str);
    Serial1.flush();
    delay (1000);
    digitalWrite(att485, 0);
  }

}

mi ripete la stringa che scrivo come vorrei correttamente, però poi continua a mandare parentesi graffe all’infinito. Qualcuno sa dirmi per favore dove sbaglio?Stessa cosa se abilito la serial3.
Dimenticavo, att485 è un pin che abilita il max485 alla trasmissione/ricezione.

Buongiorno,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del nostro regolamento, ti chiedo cortesemente di presentarti QUI (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 il su citato REGOLAMENTO ... Grazie. :slight_smile:

Qual'è il tuo obiettivo perché il codice che hai scritto di fatto fa un echo continuo sulla solita seriale quindi ci sta che tu veda un risultato inatteso.
inoltre (anche se anche l'esempio del reference le usa) non usare la classe String per gestire la cosa ma le stringhe classiche del c (vettore di caratteri), ovvero leggi un carattere alla volta e lo posizione in un vettore di caratteri, alla fine manipoli questo vettore per lo scopo che ti sei prefisso, se usi la classe String vai incontro a sicuri malfunzionamenti improvvisi ed imprevisti.
Usi una mega giusto?

>Antonio81: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra) e NON dei tag di tabella che hai utilizzato tu.

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Sistemato la questione del code-/code.
Si uso un mega, volevo usare la funzione readstring per comodità. Mi consigli di leggere un byte alla volta e metterlo in un array quindi?

Un paio di cose …

  1. ti consiglio di migliorare la leggibilità di quel codice con l’apposita funzione dell’IDE … strumenti → formattazione automatica … che mette a posto correttamente tutte le indentature.

  2. SI, per quanto possibile, evita sempre la classe “String” … difatti NON sei su un PC dove c’è un sistema operativo ed un “garbage collector”, sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe “String”, a causa dell’allocazione e riallocazione dinamica della memoria, porta quasi sempre … a grossi problemi e sicuri mal di testa !!! :smiling_imp:
    Come ti è stato detto, impara ad usare le stringhe classiche del C … ovvero semplici array di char terminati dal carattere null (0x00) e le funzioni che trovi nella libreria standard (… che, oltretutto, è automaticamente inclusa dal IDE) AVR libc ed, in particolare, quanto è in <string.h> :wink:

Guglielmo

Grazie per le dritte.

Eppure così funzionerebbe:

void serialEvent1() {
  //beep();
  while (Serial1.available()) {
    String str = Serial1.readString();
    Serial1.flush();
    if (str == "ciao")
    {
      beep();
    }
    //digitalWrite(att485, 1);
    Serial3.println(str);
    Serial3.flush();
    // Serial1.println(carattere);
    //Serial1.flush();
    digitalWrite(att485, 0);
  }
}

Sto costruendo la centralina antifurto che si dovrà inserire/disinserire usando un modulo ID12 che non fa altro ad inviare una stringa una volta accostato un tag.
Va tutto in pallone quando cerco di ripetere la stringa ricevuta nella serial1 nella stessa serial1, ma non se reinvio nella serial 3.
Non mi fido della cosa per cui scriverò una routine che legge carattere per carattere e lo mette in un'array. Però così sarebbe tanto più comodo.

Ma se tu ricevi un carattere dalla Serial1 e lo reinvii nella Serial1 anche su usi gli array non sposti di una virgola il problema, avrai sempre un loop, non usando Serial non andrà in blocco per la memoria esaurita ma la sfilza di caratteri lo avrai sempre, perché devi ritrasmettere ciò che hai ricevuto sulla solita porta? Qual'è l'esigenza che ti spinge a farlo?

Antonio81:
Non mi fido della cosa per cui scriverò una routine che legge carattere per carattere e lo mette in un’array. Però così sarebbe tanto più comodo.

La comodità in questo caso porta ad un fallimento sicuro, soprattutto per progetti sempre accesi H24

Non è così:
usando una chiavetta usb/ttl collegata alla serial1, se invio un carattere da hyperterminal, esso esce dal pin TX dell'adattatore USB ed entra nell'RX dell'arduino. Quando Arduino legge il carattere dall'RX esso lo reinvia tramite il TX che va all'RX dell'adattatore USB e miritorna in hyperterminal. Nessun loop infinito.
L'esigenza è vedere cosa gli arriva tramite la seriale non avendo collegato nessun display.
La cosa strana sta che oltre alla stringa inviata ne ritornano altre di incomprensibili e a più riprese. Cosa che non succede se i dati ricevuti dalla serial1 vengono reindirizzati nella serial3

Ok, nessun loop ma perché devi farlo? Nel senso se è per ottenere il riscontro che il comando è arrivato non è meglio rispondere con un OK o un ERR o roba simile anziché reinviare il comando in ritorno?

Si, però se non avessi fatto così non avrei ricevuto il comando "OK" e non mi sarei accorto di tutte quei caratteri che occupavano la linea RS485. Inoltre quel codice ovviamente era posticcio solo per vedere se le seriali funzionavano. Se non mi avesse fatto subito quel problema là, avrei usato le stringhe dichiarandole con "string" e non con "char".

Ti butto li un'altra idea, invece di amazzarti tutta la complessità della gestione di un protocollo di scambio messaggi prova a guardare la libreria PJON che è ben supportata dall'autore, va su praticamente ogni dispositivo (PC, Raspberry, Arduino) e ti sgrava da tutto quel ginepraio infinito che l'argomento ricezione/invio in rete mono o multimaster (collisioni, errori, ecc), a te resterebbe solo la necessità di definire un tuo protocollo per gestire la tua comunicazione

grazie

Cose strane 2.0

  while (Serial1.available() > 0) {
    char str[20];
    str[t++] = Serial1.read();
    if (Serial1.available() == 0) str[t] = '\0';
    digitalWrite(att485, 1);
    Serial3.println(Serial1.available(), DEC);
    Serial3.flush();
    digitalWrite(att485, 0);
  }

Volevo nella serial3 vedere quanti bytes sono nel buffer della serial1. Nella terzultima riga di codice la funzione available dovrebbe dare questo valore per cui se la serial1 non riceve niente, dovrebbe risultare 0.
L’output su hyperterminal si vede in immagine. Per di più se i bytes sono 0 nell’output della serial3 non dovrebbe comparire niente. Sto diventando matto.

Ho risolto. Nelle piste della scheda che ho fatto c'era una leggera conduzione tra i vari pin TX-RX delle serial.

Ciao Fabpolli, concordo sulla descrizione "ginepraio" e' azzeccata :slight_smile: