Pages: [1] 2   Go Down
Author Topic: Seriale 0.23 vs 1.02 vs 1.51  (Read 1150 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5895
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ho caricato il medesimo sketch con il quale ricevo una stringa inviata da processing
La stringa e' di 500 caratteri e la ricevo sulla usb quindi uart pin 0-1 a 115200bps

Lo sketch caricato con IDE 0.23 ne riesce a ricevere ~150
Lo sketch caricato con IDE 1.02 ne riesce a ricevere ~70
Lo sketch caricato con IDE 1.51 ne riesce a ricevere ~70

come mai c'e' questa differenza ?
C'e' un modo per ricevere tutta la stringa di 500 caratteri ?
« Last Edit: January 06, 2013, 11:29:24 am by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ho caricato il medesimo sketch con il quale ricevo una stringa inviata da processing
La stringa e' di 500 caratteri e la ricevo sulla usb quindi uart pin 0-1

Lo sketch caricato con IDE 0.23 ne riesce a ricevere ~150
Lo sketch caricato con IDE 1.02 ne riesce a ricevere ~70
Lo sketch caricato con IDE 1.51 ne riesce a ricevere ~70

come mai c'e' questa differenza ?
C'e' un modo per ricevere tutta la stringa di 500 caratteri ?

Dall'IDE 1.x in poi la seriale è gestita via interrupt ed il buffer interno è stato dimezzato.
Prova intanto ad aumentare i buffer modificando il file:
1.0.x: hardware/arduino/cores/arduino/HardwareSerial.cpp
1.5.1: hardware/arduino/avr/cores/HardwareSerial.cpp
alla riga 59 trovi "64", metti "128", il valore che c'era nelle versioni 002x.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9492
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C'e' un modo per ricevere tutta la stringa di 500 caratteri ?

Devi svuotare il buffer della seriale mano a mano che arrivano i caratteri altrimenti lo riempi e quelli in più vanno persi.
Fino all'IDE 023 il buffer era di 128 caratteri, gestito da interrupt in ricezione e tramite polling in trasmissione senza nessun buffer.
Dall'IDE 1.x il buffer è di 64 caratteri in ricezione e 64 caratteri in trasmissione, tutti e due sono gestiti tramite interrupt quindi per inviare tot caratteri Arduino non si ferma fino a che non sono stati trasmessi tutti i caratteri come avveniva con l'IDE pre 1.x
Logged

0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5895
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho allargato a 128 il buffer descritto da Leo, e poi anche a 256
Quote
#if (RAMEND < 1000)
  #define SERIAL_BUFFER_SIZE 16
#else
  #define SERIAL_BUFFER_SIZE 256 // Originalmente 64
#endif

Il risultato e' ottimo, con 128 sono ritornato alle vecchie prestazioni e con 256 le ho superate.

Domande:
0: Parliamo di 256Byte o bit ?
1: Quale e' la contropartita ? Sono 256Byte/bit fermi, sempre allocati giusto, quindi tolti alla Ram ?, Ci sono altri problemi ?
2: Quell #if (RAMEND < 1000) che significa ? Forse che se la Ram scende sotto i 1000 Byte (oppure bit) il buffer si autoriduce ?
3: Astro io non ho usato nessun delay, la velocita' di lettura e svuotamento buffer e' al massimo, c'e' un solo delay di un millesimo di secondo nel codice proprio della lettura seriale
Code:
while (Serial.available())
         {
 delay(1);
 if (Serial.available() >0)
                 {
         char c = Serial.read();
Posso provare a toglierlo o non serve ?
Tu hai altre idee che possano non farmi modificare manulmente il buffer ?
« Last Edit: January 06, 2013, 12:19:41 pm by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

0 e 1:
Parliamo di BYTE quindi se metti 256 come valore del buffer, consumi (256*2)=512 byte del quantitativo totale di memoria. Ricorda che i buffer sono 2 (RX e TX). Sono ovviamente byte PERSI se inizializzi la seriale e poi non la usi.
2:
se la memoria totale (RAM) è inferiore a 1000, inizializza i buffer ristretti. E' un check per chip che hanno poca memoria RAM
3:
quel delay(1) non serve a nulla. Essendo ricezione e trasmissione gestite via interrupt, una volta che hai messo il/i byte nel buffer corrispondente, vengono spediti finché non sono finiti
Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5895
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non avevo pensato al *2, ecco perche' allargand a 512 non andava piu' nulla   smiley-yell

dai miei test risulta questo:
con buffer a 128Byte riesco a ricevere sui 128, piu' o meno poco piu' poco meno, sembrerebbe che lui riempie tutto il buffer e poi lo svuota alla fine,
(e' corretto dire che se invio 128 caratteri sulla seriale sto' inviando 128byte ? e nella Ram di arduino vengono occupati 128Byte ?)

con buffer a 256Byte riesco a ricevere massimo 220caratteri, se ne mando di piu' salta la Ram a volte fino al riavvio.

Non mi ritrovo invece sul delay di cui sopra:
se lo tolgo ricevo solo una decina di caratteri
se lo aumento non cambia nulla, resta solo un po' piu' freezato l'lcd durante la ricezione

Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

non avevo pensato al *2, ecco perche' allargand a 512 non andava piu' nulla   smiley-yell
Saturazione completa  smiley-yell

Quote
dai miei test risulta questo:
con buffer a 128Byte riesco a ricevere sui 128, piu' o meno poco piu' poco meno, sembrerebbe che lui riempie tutto il buffer e poi lo svuota alla fine,
(e' corretto dire che se invio 128 caratteri sulla seriale sto' inviando 128byte ? e nella Ram di arduino vengono occupati 128Byte ?)
Non del tutto. La trasmissione standard PC/Arduino è 8N1, quindi 8 bit di dati, nessun bit di parità, 1 bit di stop, a cui si somma 1 bit di start, per cui ogni carattere in transito è composto da 10 bit al posto degli 8 di 1 byte.
Questo però riguarda solo la trasmissione: una volta ricevuto, del carattere vengono memorizzati solo gli 8 bit dei dati, per cui in RAM alla fine ci sarà 1 byte.

Quote
con buffer a 256Byte riesco a ricevere massimo 220caratteri, se ne mando di piu' salta la Ram a volte fino al riavvio.
Saturazione  smiley-twist

Quote
Non mi ritrovo invece sul delay di cui sopra:
se lo tolgo ricevo solo una decina di caratteri
se lo aumento non cambia nulla, resta solo un po' piu' freezato l'lcd durante la ricezione


Spiegami allora il motivo per cui hai messo quel delay(1) perché non l'ho capito.
Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5895
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

vero, i bit di start e stop.
ma i 10bit di ogni carattere entrano nel buffer oppure lo star e stop viene eliminato in hardware dalla uart ?

Il delay 1 e' presente di defoult in tutti gli sketch che gestiscono la seriale, non l'ho messo io, e cmq ripeto che ho rpovato a toglierlo e non riceve quasi piu' nulla, riceve solo una decina di caratteri, quindi e' giusto che ci sia, ed e' giusto che sia di un millisecondo
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

vero, i bit di start e stop.
ma i 10bit di ogni carattere entrano nel buffer oppure lo star e stop viene eliminato in hardware dalla uart ?
Sono segnali usati solo in trasmissione. Fai finta proprio che non esistano. Tu devi ragionare: spedisco 1 byte, mi arriva 1 byte. Non devi fare i conti: allora, 8 bit ma diventano 10 in trasmissione che però tornano 8 quando li salvo... diventi grullo per nulla  smiley-yell

Quote

Il delay 1 e' presente di defoult in tutti gli sketch che gestiscono la seriale, non l'ho messo io, e cmq ripeto che ho rpovato a toglierlo e non riceve quasi piu' nulla, riceve solo una decina di caratteri, quindi e' giusto che ci sia, ed e' giusto che sia di un millisecondo
Mai visto prima. Novità per me. Dov'è che c'è?
Logged


0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5895
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

in giro c'e' un po' dappertutto, credevo fosse uno standard, vedi ad esempio questo che usa addirittura 100ms
http://wiring.org.co/cgi-bin/yabb/YaBB.pl?num=1218069222

cmq se lo tolgo puff, solo 10 caratteri arrivano. a questo punto posso provare a cambiare metodo di ascolto della seriale, quale mi consigli ?
ho visto ad esempio che uno degli esempi ufficiali si riserva uno spazio proprio per la strnga da ricevere, vedi esempi-Communication-SerialEvent, e' buona cosa secondo te ?
Code:
void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

Ultima idea che mi e' venuta, ma non c'e' modo di dichiarare buffer differenti per rx e tx. se non devo spedire nulla sono veramente sprecati 256byte per tx
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

in giro c'e' un po' dappertutto, credevo fosse uno standard, vedi ad esempio questo che usa addirittura 100ms
http://wiring.org.co/cgi-bin/yabb/YaBB.pl?num=1218069222
L'esempio citato è agganciato ad un post del 2008, però su Wiring. Conosci Wiring? Com'era Wiring nel 2008? Usava la seriale gestita da interrupt oppure no? Io non so risponderti. Un delay(1) a che serve? A far sì che arrivi un carattere altrimenti esci dal check? Allora forse è da rivedere quel check?
Boh, senza vedere tutto il codice non so risponderti. Io non ho mai usato delay di 1 ms prima di controllare la seriale.

Quote
cmq se lo tolgo puff, solo 10 caratteri arrivano. a questo punto posso provare a cambiare metodo di ascolto della seriale, quale mi consigli ?
ho visto ad esempio che uno degli esempi ufficiali si riserva uno spazio proprio per la strnga da ricevere, vedi esempi-Communication-SerialEvent, e' buona cosa secondo te ?
Code:
void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}
Secondo me questo l'hanno fatto per aggirare il buffer di 64 byte senza metter mano alla libreria. Quindi è una soluzione che va bene anche per utenti non capaci/non desiderosi di armeggiare con i file del core.

Quote
Ultima idea che mi e' venuta, ma non c'e' modo di dichiarare buffer differenti per rx e tx. se non devo spedire nulla sono veramente sprecati 256byte per tx
Certamente.
Basta cambiare quella porzione di codice che ti ho linkato inserendo 2 define al posto di uno (per mettere la dimensione del buffer RX e di quello TX) e poi modificare i file CDC.cpp e HardwareSerial.cpp: ci sono 19 occorrenze in cui compare SERIAL_BUFFER_SIZE, devi controllarle tutte e verificare se sono da cambiare.
Logged


0
Offline Offline
Shannon Member
****
Karma: 131
Posts: 10473
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

attenzione che sono buffer circolari: se lo riempi non rimani in attesa ma sovrascrivi i dati più vecchi. il fatto che se mandi più di circa 200 caratteri si impalla tutto è perchè immagino che hai creato la stringa di 200 e passa caratteri, quindi un 3° "buffer" nella ram! anche se la salvi in flash nel momento in cui viene usata mi pare venga caricata in un'area ram ad hoc.
Se invece in un for scrivi i numeri da 0 a 1000, ti accorgerai del fatto del buffer circolare (perdita di dati) però dovresti vedere arrivare gli utimi TX buffer size byte!
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Faraday Member
**
Karma: 47
Posts: 5895
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

grazie leo del tuo parere, faro' delle rpove con il reserve e riporto i risultati.

lesto la stringa mi arriva dal pc, non la creo internamente ad arduino.
tu cosa intendi ?
la stringa che ricevo resta sempre nella ram, non la scrivo mai su flash, perche' cambia spesso, cioe' ogni volta che premo un pulsante sul pc parte sta stringa via seriale, e la acchiappo da arduino che la visualizza su lcd, quindi non la scrivo mai sulla flash di arduino. se spengo arduino perdo la stringa, e' voluto.

io credo funzioni cosi', datemene conferma:
Quando inizio a ricevere la stringa i caratteri vanno nel buffer, ci entrano a 115200bps. Arduino per conto suo, in modo asincrono, inizia a prendere carattere per carattere e metterlo nel buffer, che sarebbe un pezzo della ram.
Pero', questo e' importante, ad ogni carattere che preleva dal buffer e lo passa in ram, lo cancella dal buffer. Quindi non e' che i 200 caratteri occupano 200byte nel buffer e 200 nella ram, ne occupano sempre 200 in tutto, anche durante l'operazione di trasferimento.

E' corretto ?

Non potendo velocizzare arduino, mi verrebbe da dire: Basta che abbasso a 9600 la seriale di arduino ?
In questo modo mi rrivano piu' lentamente i caratteri ? (questo va anche nella direzione indicata da Astro credo)

Astro quando dici:
Dall'IDE 1.x il buffer è di 64 caratteri in ricezione e 64 caratteri in trasmissione, tutti e due sono gestiti tramite interrupt quindi per inviare tot caratteri Arduino non si ferma fino a che non sono stati trasmessi tutti i caratteri
Intendi che non ci sono problemi in trasmissione ? non parli di ricezione. In ricezione il fatto che sia gestita da interrupt e' irrilevante rispetto al problema Ring ? cioe' di sovrascrittura a rotazione dello spazio di memoria ?

karma per tutti  smiley
« Last Edit: January 08, 2013, 09:44:35 am by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I buffer di cui si parla sono solo quelli SW, cioè gli array creati e gestiti da HardwareSerial.cpp e .h.
Come buffer hardware l'Atmega328 ha 2 registri e basta. Il primo è un registro a scorrimento in cui viene composto il dato man mano che arrivano i suoi bit. Una volta che è stata completata la ricezione il dato viene copiato in un altro registro, da cui il codice può leggerlo. Quando viene copiato in questo secondo registro, viene attivato un interrupt di ricezione terminata e dato pronto. E' a questo punto che scatta la ISR, che preleva il byte e lo copia nel buffer SW di cui stiamo parlando.
Logged


0
Offline Offline
Shannon Member
****
Karma: 131
Posts: 10473
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
la stringa mi arriva dal pc
ok, ma il problema rimane, credo, vedi dopo

Quote
Pero', questo e' importante, ad ogni carattere che preleva dal buffer e lo passa in ram, lo cancella dal buffer. Quindi non e' che i 200 caratteri occupano 200byte nel buffer e 200 nella ram, ne occupano sempre 200 in tutto, anche durante l'operazione di trasferimento.

ok, il byte viene letto ed entra nella prossima cella del buffer, se il buffer è pieno sovrascrive il byte più vecchio. Lo spazio del buffer è fisso.
Però poi prelevi il byte, e lo metti nel buffer dei dati destinati all'LCD. Sempre che possieda un buffer SW. Magari questo buffer esiste ed è dinamico, quindi è la libreria dell'LCD che intasa la ram. Che libreria usi?

Quote
Non potendo velocizzare arduino, mi verrebbe da dire: Basta che abbasso a 9600 la seriale di arduino ?
In questo modo mi rrivano piu' lentamente i caratteri ?

sì ma è un pagliativo, bisogna capire bene da che parte arriva l'intasamento della ram o comunque ciò che impalla il micro.

Quote
Intendi che non ci sono problemi in trasmissione ? non parli di ricezione. In ricezione il fatto che sia gestita da interrupt e' irrilevante rispetto al problema Ring ? cioe' di sovrascrittura a rotazione dello spazio di memoria ?

stiamo parlando di ricezione, quindi il problema non si pone. In trasmissione prima la scrittura ti bloccava il codice finchè tutto non era scritto; ora tutto viene salvato in un buffer circolare e l'invio lavora tramite interrupt. Quindi se scrivi nel buffer più velocemente di quanto esso si svuoti vai a riscrivere i byte più vecchi che verranno persi. Ma chissene, ora pensiamo al TX che è più semplice usando un sistema "universale" in tutte le versioni della lib.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Pages: [1] 2   Go Up
Jump to: