Spiegazione sketch "CNC-Laser a 2 Assi" con Arduino

Buonasera a tutti.

Sono alle prese con la costruzione di una CNC a due assi (vorrei fare un incisore laser). Inizialmente la volevo fare con un PIC18F, poi ho optato per Arduino, perchè mi piace la filosofia open.

Veniamo al dunque. Su Google ho trovato questo codice che vorrei analizzare per poterlo comprendere ed imparare qualcosa di nuovo (invece del classico copia e incolla):

Il codice è inserito come allegato perchè sforava i 9000 caratteri imposti dal Forum

Questo codice più o meno l’ho capito. Ho però un dubbio sulla comunicazione seriale.

L’arduino ascolta (Serial.available() ) se c’è qualcosa sulla linea TX e se il controllo è positivo allora procede cercando di capire di che carattere si tratta.
Mentre fa ciò, correggetemi se sbaglio, continuano ad arrivare altri caratteri. Questi saranno messi nel buffer di ricezione della seriale che dovrebbe essere di 64byte.
Quindi, finito di controllare il primo carattere ricevuto, passa al secondo e così via.

Le mie domande sono:
-Come si fa ad essere sicuri di non perdere nessun carattere? Può accadere che l’invio dei caratteri da parte del PC sia più rapido del tempo che impiega l’Arduino a processarli internamente e che quindi vengano sovrascritti?

-Perchè non è stato previsto un carattere di avvenuta ricezione? Cioè un carattere che l’Arduino manda al PC non appena ha finito di processare il primo dei caratteri ricevuti, così che il PC possa inviare il carattere successivo senza problemi

Mi rendo conto della lunghezza del messaggio e della complessità.
Ringrazio coloro che parteciperanno a questa discussione, forse un po’ “filosofica” ma interessante.

Led_ON

CNC_code_laser.ino (9.64 KB)

Per quanto riguarda una cnc laser, credo sia più sensato e si otterrebbe un risultato migliore usando il firmware arduino grbl, dove avrai anche software per controllare il laser.

Per quanto riguarda la comunicazione seriale è qualcosa che va oltre la programmazione arduino o la programmazione in qualunque linguaggio, è un protocollo di comunicazione con delle regole ben precise che viene usato da molti dispositivi diversi. Io ne so poco del protocollo, però se ti interessa come avviene la comunicazione seriale devi lasciare perdere codice di arduino e studiarti il protocollo, perché sono proprio le specifiche del protocollo che rispondono alle tue domande, come non perde un carattere? Perché non esiste un carattere di avvenuta ricezione? ecc...

Led_ON: L'arduino ascolta (Serial.available() ) se c'è qualcosa sulla linea TX

RX. La ricezione seriale avviene sotto interrupt e ogni byte in arrivo viene automaticamente aggiunto al buffer di ricezione. La funzione 'available' riporta quanti ne sono arrivati nel momento in cui viene usata.

Da questo momento in poi è il programma utente (lo sketch) a doversi far carico di leggere i byte dal buffer (con read) ad una velocità superiore a quella con cui arrivano.

Probabilmente nel caso d'uso specifico non è prevista la conferma della ricezione perché ritenuta superflua.

Grazie ad entrambi.

Ah, pensavo che la Serial lavorasse in ciclo continuo. Invece lavora su interruzione? Mi confermi?

Ipotizzando che lavori in interruzione, allora ogni volta che arriva un char questo viene messo nel buffer di ricezione. Poi il programma Arduino analizza il carattere ricevuto ad una velocità superiore rispetto al tempo impiegato per ricevere un altro carattere.

Confermi? Come faccio a sapere a che velocità arriva un carattere? Ovvero, come estraggo questa informazione sapendo che il baud-rate è 9600?

Grazie ancora

Led_ON: Come faccio a sapere a che velocità arriva un carattere? Ovvero, come estraggo questa informazione sapendo che il baud-rate è 9600?

Il baud-rate è il numero di bit al secondo trasmessi/ricevuti ... ... a 9600 hai 9600 bit/secondo, considerando uno start bit, 8 data bit ed uno stop bit, si hanno 10 bit per carattere il che da circa una velocità di 960 caratteri al secondo.

Guglielmo

Led_ON: Ah, pensavo che la Serial lavorasse in ciclo continuo. Invece lavora su interruzione? Mi confermi?

SI, Arduino ha un buffer circolare dove salva i caratteri che vengono ricevuti, indipendentemente dal tuo programma, da una ISR dedicata alla ricezione dei dati.

Quelli che tu leggi, in realtà, sono i caratteri presenti nel buffer circolare, NON lo streaming in arrivo.

Guglielmo

Grazie gpb01.

Secondo voi può accadere che la velocità di ricezione dei caratteri (960 al secondo) sia maggiore del tempo impiegato da Arduino nel processarli? Come potrei fare a determinare questo tempo?

Mi faccio questa domanda perchè non capisco come fa ad essere sicuro colui che ha scritto il software di non perdere neanche un carattere. In effetti 960 caratteri al secondo sono 960byte, quindi vuol dire che il buffer di ricezione di 64byte si riempie in:

960/64 = 15 secondi ?

In realtà non sono proprio 960 byte, perchè giustamente gpb01 hai fatto il conto con 10bit (consideranto start e stop bits). Però penso che su per giù siano 15 secondi.

Questo tempo è sufficiente? Oppure ho completamente fatto un conto a caso...

Grazie dell'aiuto prezioso.

mah...

tralascio la differenza tra "baud" e "bps" che ha troppo "sapore tecnico"

però hai sbagliato il conto, non 960/64 ma 64/960 cioè meno di 7 centesimi di secondo

certo che Arduino riesce a processare i dati a 9600 bps, garantito, se li deve solo leggere e magari ritrasmettere se li deve anche "eseguire" magari spostando i motori la cosa è meno garantita

sarebbe da esaminare il programma, temo

Grazie.

Certo, hai ragione, io ho trovato 15Hz.

Il programma l'ho allegato, se vuoi puoi guardarlo. Però se non hai voglia di studiartelo, ti capisco perfettamente, lascia pure perdere.

Invece mi interesserebbe la differenza tra baud e bps.

Grazie, Led_ON

sono sicuro che a ingegneria elettronica trovi qualcuno (io ti auguro qualcuna) che ti spiega la differenza, con parole certamente migliori di quelle di un vecchio perito meccanico

>Led_ON: Nel nostro caso le due cose coincidono quindi, per semplificare, ho usato le tue parole :smiley:

Se vuoi una spiegazione più tecnica, considera che in realtà qui parliamo di bps (bit per second) e, dato che di mezzo non c’è alcuna modulazione o codifica del segnale, quiesti coincidono con il baud-rate. Il baud-rate indica quante volte al secondo un segnale cambia (o può cambiare) in funzione di ciò che si trasmette.

Ad esempio, potresti avere delle codifiche in cui usiamo 4 segnali per rappresentare le quattro coppie di bit 00, 01, 10 ed 11 (es. -12V -6V, +6V, +12V) … in tal caso, ad ogni varazianoe del segnale, in verità corrisponde una coppia di bit, per cui con un baud-rate di 1200 avresti un bps di 2400 (1 variazione = 2 bit trasmessi).

Naturalmente questa è una semplificazione per spiegarti la differenza … considera che con i veri modem si hanno codifiche in grado di rappresentare 6bit (o più bit) quindi, un baud-rate di 2400 corrispondererebbe a 14400 bps :wink:

Guglielmo

>Ducembarr: … purtroppo per lui sono un ‘qualcuno’ e non una ‘qualcuna’ :smiley: :smiley: :smiley:

io sono sicuro che mio fratello volesse dire che nel suo "ambiente" la differenza BpS-Baud dovrebbe essere abbastanza conosciuta

però quello che voleva dire lui lo dirà lui

io invece volevo dire che il programma lo ho ben guardato, e comincia con una bella pausa da 100 mS e solo dopo comincia a leggere la seriale, che nel frattempo potrebbe avere il buffer ben spinto in overload

insomma non mi piace per nulla

anche perché poi, nell'interpretazione dei comandi G fa un bel po' di presunzioni pericolose sulla lunghezza e sull'ordine degli argomenti

Led_ON: L'arduino ascolta (Serial.available() ) se c'è qualcosa sulla linea TX e se il controllo è positivo allora procede cercando di capire di che carattere si tratta. Mentre fa ciò, correggetemi se sbaglio, continuano ad arrivare altri caratteri. Questi saranno messi nel buffer di ricezione della seriale che dovrebbe essere di 64byte. Quindi, finito di controllare il primo carattere ricevuto, passa al secondo e così via.

Non proprio

alloca un buffer sconsideratamente grande (512 byte, un quarto della memoria solo per ricevere comandi G) legge byte per byte dalla seriale, e solo al termine di una riga passa l'intero buffer al trattamento

fino a che si trova in una riga siamo sicuri che arduino riesca a ricevere i dati

come faceva notare mio fratello è durante il trattamento che sorge il problema, se si aggiunge che c'è anche un delay 100 al termine del trattamento

Vi ringrazio tutti per i chiarimenti.

@Ducembarr: Spero sia qualcuna anche io :). Apprezzo la tua umiltà, ma sono convinto che un perito ben preparato sia anche meglio di un ingegnere senza troppa esperienza.

@Salvorhardin: Suppongo che Ducembarr sia tuo fratello. Per concludere, quel programma non è molto affidabile giusto? Diciamo che ci sono vari tecnicismi da approfondire. Ad ingegneria, specialmente la triennale, abbiamo molte materie teoriche e tanta matematica. Io sono all'inizio del 3° anno e solo ora sto cominciando ad andare in laboratorio. Quindi la differenza tra baud e bps non è mai stata trattata. Fortuna che sono un perito elettronico e quindi riesco un po' a smanettare da solo.

@gpb01: Grazie mille delle tue risposte esaurienti. Ho capito il concetto.

Vi ringrazio tutti.

In conclusione, riassumo così che questa discussione possa essere utile ad altri: Il programma che ho allegato nel primo post non è affidabilissimo poiché non vengono trattate adeguatemene alcune parti, come la comunicazione seriale. Funziona certamente, ma solo perché lo stream di caratteri è limitato.

Correggetemi se sbaglio. E.P.

Sì, siamo gemelli (non monozigotici, ci teniamo a dirlo)