Problema seriale caratteri strani.

Stò usando un arduino nano con la seriale software per ripetere i messaggi che riceve sulla seriale hardware e viceversa.

Il problema è che mentre quello che invio dalla seriale hardware tramite console viene trasmesso correttamente, quello che leggo invece è semileggibile ma contiene comunque errori.

Vi posto un listato qui sotto, dove lo collego alla seriale di un raspberry.

Cosa può essere ? Ho pensato al buffer troppo piccolo, ma si presenta pure con frasi molto corte.

Linux raspy4.19.42-v7+ #1219@SMP Tue May@14 21:20:58 BST 2019 a⸮ٝ⸮5

}⸮uy⸮⸮ae⸮⸮5⸮}⸮⸮⸮
 dbeop e,⸮!
dasuac⸮⸮a

b/ wB⸮9}a⸮⸮
rdpbw
SS⸮ is enabled@⸮⸮bab⸮q⸮⸮⸮⸮}⸮r}⸮ba:ej⸮⸮⸮⸮⸮}⸮yayy⸮
This is cill prtp t oroot@raspy:~# 
root@raspy:~# 
root@raspy:/# l
bin   dev  home  lost+found  mnt  proc	run   server  srv  tmp	  usb@⸮⸮⸮u
boc	e  	s   
root@raspy:/#

Questo è il codice usato

void loop() {

  if (Serial.available()) {
    soft_serial.print(char(Serial.read()));
  }

  if (soft_serial.available()) {
    Serial.print(char(soft_serial.read()));
  }

}
  1. a che velocità fai lavorare la SoftwareSerial?

  2. hai adattato i livelli? Arduino lavora a 5V, raspberry a 3.3V

Guglielmo

I livelli li ho adattati con un resistenza di 120ohm e uno zener a 3.3. da arduino a raspy, al contrario non li ho adattati ma il livello da 3v3 a 5 dovrebbe andare bene, perchè di solito le porte hanno il LOW da 0 a 0,8 e l'HIGH da 1,8 a 5... però devo controllare meglio sul datasheet dell 328p.

la velocità è la stessa sia per la hardware che per la software, impostata a 115200.

Scordatela quella velocità ... :smiley:
... la SoftwareSerial, abbiamo dimostrato tempo fa qui sul forum, è affidabile fino a 9600 ... già a 38400 non va più bene.

Prova a 19200 o cala definitivamente a 9600.

Guglielmo

ok. Ho sistemato l'adattamento di livello, ma niente da fare, è migliorato un pò ma il problema persiste. Il fatto è che devo modificare i parametri dal raspberry e mi secca un pò perchè avevo altre cose che volevo gestire a 115200. va beh, in caso vedo se si può usare l'hardware serial dai pin 0 e 1.

Ma posono dare problemi se li uso anche per programmare il nano ? O devo scollegarli ogni volta ? No perchè l'RX è bufferizzato con due transistor e non dovrebbe dare rogne, mentre il TX ha solo una resistenza e uno zener, questo vuol dire che mentre lo programmo la roba arriva pure al raspy, spero non interferisca.

Niente, ho provato ma va per forza dissaldato.

Se devi per forza andare a quelle velocità, ti serve un qualche cosa con più di una seriale hardware ...
... o una scheda basata su ATmega1284P (es. QUESTA, con due seriali HW) o una Arduino MEGA con 4 seriali a bordo.

Guglielmo

Grazie intanto, posso anche abbassare alla fine.

Però è sorto un altro problema. Scrive male anche in TX, cioè sul raspy se do:

Cat /dev/ttyS0

Mi lista lo stream della seriale, e si vede che i caratteri a volte vengono scritti bene, altre volte troncati e altre ancora viene giù roba incomprensibile...

Cosa può essere ?

Ma le masse le hai messe in comune? Hai abbassato la velocità della SoftwareSerial?

Guglielmo

Le masse sono in comune certamente, e uso la seriale hardware. Non uso più la software.

In sostanza alla pressione di un pulsante scrivo al raspberry facendo il login e dicendogli di spegnersi. Ovviamente così funziona una volta su 10.

E poi ci saranno 10cm di filo mica metri.

Controlla che entrambe le seriali abbiano i parametri identici. Come test riduci la velocità fino a che non ottieni caratteri puliti.

Ok, ho abbassato la velocita a 9600 e va molto meglio. Strano però.

Ora ho messo un contatore che printa a partire da zero in sù.

In sostanza faccio

Serial.print (i);
Serial.print ("\r\n");
i++

E funziona però se dò cat sulla seriale dal raspy mi printa si i numeri incolonnandoli uno sotto laltro, però occasionalmente ne perde uno, diciamo uno ogni 20-30...

In più a volte i numeri sono attaccati uno sotto l'altro, a volte invece cè una riga di spazio.

E cosa ancora più strana, dopo un pò mi butta fuori dal cat e torna alla console, sul raspy intendo. Premetto che raggiungo il raspy tramite SSH. Ma se redireziono lo stream verso un file di log fa lo stesso, cioè dopo un pò smette di loggare.

Che può essere ?

La raspberry è un micro computer che gira un OS che ... ha i suoi tempi e le sue "latenze", Arduino è un microcontrollore, senza alcun OS che spara dati a raffica ...

Se vuoi fare una cosa veramente affidabile, anche ad alte velocità, devi mettere in piedi un piccolo "protocollo" che, per ogni invio, indichi ad Arduino che ha avuto buon fine e che può effettuare il prossimo.

Guglielmo

dukeluca86:
Le masse sono in comune certamente, e uso la seriale hardware. Non uso più la software.

In sostanza alla pressione di un pulsante scrivo al raspberry facendo il login e dicendogli di spegnersi. Ovviamente così funziona una volta su 10.

E poi ci saranno 10cm di filo mica metri.

Dipende in che "ambiente" stai lavorando, che disturbi elettromagnetici ci sono (alimentatori switching, inverter nei paraggi, ecc...)

Prova solo a togliere i 10 cm di filo e vedi di collegarli con un ponticello oppure, in qualche modo, con UN centimetro di filo.

Io ho provato solo una volta a testare la seriale hardware di un RasPy (ma era ancora una delle prime versioni) e non permetteva neppure il full duplex (semplice ricezione in loop di quanto trasmesso). Si perdevano un sacco di byte. Credo che il consiglio di ridurre drasticamente il flusso (che non vuol dire la velocità) sia fondamentale. Quindi NO trasmissione continua da Arduino, almeno intervallare ogni trasmissione con una pausa.

Hm... Non ho mai usato il RPi però in generale per una connessione seriale bisogna controllare i parametri esatti utilizzati/richiesti (oltre alla velocità da impostare identica, ricorda per dirne una che Arduino non ha alcun handshake né software -XON XOFF- né hardware), poi i cablaggi hardware, poi i livelli dei segnali (Arduino va a 5V ossia da 0 a 5V, sicuro che la seriale del RPi esca a 3.3V, e che siano asimmetrici ossia tra 0 e 3.3V e non da -3.3 a +3.3?). Inoltre verifica se RPi si aspetta un certo tipo di terminale, devi avere un tty "base" ossia niente codici di controllo o altro.

Se queste cose le hai già verificate, che a 9600 abbia problemi mi pare molto strano, e neanche i 10cm di filo dovrebbero influenzare i risultati.

Se usi la UART nativa e non più la SoftwareSerial, non puoi più vedere nulla per capire cosa "vede" Arduino, per cui torna alla SoftwareSerial (a 9600) e posta il nuovo listato, insieme a cosa ottieni dal serial monitor quando apri la porta e vediamo.

EDIT: domanda, ma hai necessità di collegarli proprio via seriale? Perché è anche possibile far parlare Arduino e RPi via USB ossia con la seriale "virtuale", vedi QUI...

Aggiungo la mia, sono più di 12 mesi ininterrotti che comunico da/a Arduino con un Raspberry via seriale, traslatore di livelli CD4050 e libreria PJON, baudrate 9600 mai un problema. Non ho dovuto impstare nulla di particolare sia sulla raspberry sia lato Arduino. Penso che il problema fondamentale sia quello sollevato da Guglielmo, ovvero serve un protocollo e non un flood continuo di caratteri per non aver problemi.

Ma proprio carattere pausa carattere, o pausa dopo una stringa ? Inotre l'enter come lo dò a fine riga ? Al momento uso \r e \n ma non sò se sia corretto.

Ps

Chiarisco una cosa, non sto usando la seriale come tty semplice ma proprio come console, sulla quale viene replicto il login.

Trasmetto solo. I dati li leggo dal raspy con cat.

Non serve la pausa dopo ogni carattere ma devi inviare/ricevere solo quando serve, inoltre il fine riga può andar bene come stai facendo tu ma è superfluo. Se nel tuo protocollo decidi di inviare i comandi che terminano sempre con un determinato carattere (Es #) puoi usare quello per determinare se hai finito di ricevere la trasmissione e risparmi un carattere, oppure puoi scegliere di intercettare solo \r o \n il protocollo è tuo e sta a te decidere come fare la fine trasmissione (Esiste anche il carattere EOT nella tabella ASCII se vuoi).
Il succo è che da Arduino e da Raspberry devi inviare solo quando serve, ad esempio se da Arduino devo inviare la temperatura rilevata da un sensore a Raspberry per infilarlo dentro un Db da Ardunino puoi fare una cosa del tipo:

if(vecchiaTemperatura!=nuovaTemperatura)
{
   Serial.write(0xAA); Carattere inizio trasmissione
   Serial.write(nuovaTemperatura);
   Serial.write(0xFF); //Il tuo terminatore
   vecchiaTemperatura=nuovaTemperatura;
}

e per similitudine anche su Raspberry prima di mandare qualcosa devi accertarti che sia strettamente necessario.
Chiaramente questo non è un vero e proprio protocollo in quanto non ho indicato verifica se sono avvenuti errori, check del comando, ecc. e neppure l'eventuale attesa di una risposta di comando ricevuto, però era per darti l'idea di come trattare la cosa.

Un altra cosa, io lo faccio loggare come root sulla seriale e lo stesso faccio tramite server ssh, possono coesistere due utenze root loggate contemporaneamente ? O potrebbe non loggarsi sulla seriale, che è l'ultima a provarci e io non ne saprei niente non avendo feedback ?

Abbiamo postato nello stesso minuto:

Raga, ve lo stò a dire da un pezzo, non è la seriale normale, nessun protocollo, è la ttyS0 che è una console.

Per capirci, è come se scrivessi con la tastiera al terminale, infatti cè pure la bash:

root@user:#

La prima voce che si presenta è:

login:

Alla quale io rispondo:

root\r\n

Che sarebbe root più invio.