ELS (Electronic Lead Screw) - progetto con ARDUINO

Moderatore: Junior Admin

eugeniopazzo
TORNITORE E FRESATORE
Messaggi: 4204
Iscritto il: dom apr 04, 2010 16:54
Località: Paesi Bassi / Delft

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da eugeniopazzo »

Davide credo funzioni cosi: Il sistema registra l angolo del mandrino A e la posizioine X del carro quando parte la filettatura. Quando torna indietro in asincrono si riporta il carro alla posizione X (al netto del gioco di inversione) e per la seconda passata si rimette il mandrino all angolo A e si ricomincia. Tutto ció può avvenire con mamdrino che gira dalla stessa parte e anche velocemente, basta non cambiare la velocità fra le passate (secondo me). Se non ho capito male ci si basa sulla non perdita di passi dello stepper della vita di avanzamento.
"La roulette russa non uccide" affermano 5 esperti su 6
"La prima cosa che guardo in qulo è la ragazza"
"Se non sei parte della soluzione sei parte del problema"
"Simplicity is the ultimate sophistication"
Avatar utente
McMax
CAPO OFFICINA
Messaggi: 8996
Iscritto il: dom gen 31, 2010 21:46
Località: Bussero (MI)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da McMax »

:1234:
oh ma è mai possibile che sto topic se ne sta buono per mesi poi, quando mi assento per una giornata, si scatena l'inferno ??? :frusta: :frusta: :frusta:

Allora, partiamo dal discorso della routine di interrupt e del motivo per cui va tenuta breve.
Analizziamo il caso del ELS e vediamo cosa deve fare il programma mentre si filetta:
- leggere l'encoder: evento randomico esterno che va intercettato immediatamente e non può essere ne mascherato ne ritardato. Ovviamente questo richiede un interrupt
- generare un passo per il motore stepper in sincrono con il passo o i passi dell'encoder letti: evento specifico generato dal codice stesso sullla base di calcoli che possono essere più o meno complessi. Questo evento NON è prioritario rispetto alla lettura del passo encoder per il semplice fatto che è CONSEGUENZA dei passi encoder.
- BASTA!
Il micro questo deve fare.
Nient'altro.
Che motivo avremmo di mettere entrambi i task che il programma deve eseguire sotto interrupt ?
Nessuno, anzi, se mettesimo anche la generazione del passo sotto interrupt andremmo di fatto a dare la stessa priorità ai 2 task, col risultato che non ci sarebbe più un task prioritario rispetto all'altro ma avrebbero entrambi la stessa priorità. Nel caso specifico questi sarebbero i soli due task che il micro sta eseguendo, entrambi nella stessa routine di interrupt, quindi il micro starebbe eseguendo di fatto SOLO la routine di interrupt.
E qui poi torniamo al solito discorso: funziona ? probabilmente si. E' efficiente ? NO. E' stabile ? probabilmente NO.
Ricordo che i linguaggi compilati come il C spesso sono fuorvianti perché il programmatore in erba è portato a pensare che il solo fatto che il codice si compili senza errori è sinonimo che tutto funzioni. Esistono invece tutta una serie di problemi che si possono verificare "run-time" e che spesso sono molto difficili da diagnosticare.... e quando il codice è scritto come in questo caso per un sistema a basso livello come un microcontrollore è più probabile incorrere in problemi di questo tipo.

La routine di interrupt che deve fare più cose avrà per forza di cose molte più condizioni (in quella di Matteou ho contato 15 if...), la cui esecuzione e durata non dipende solo dall'evento di interrupt che ha causato l'entrata nella funzione ma anche da altre variabili. Nel caso in esame le routine dureranno di più o di meno in funzione che si debba o meno generare il passo piuttosto che si sia o meno nella fase di accelerazione o decelerazione. In questi casi la routine è asimmetrica e potrà durare di più o di meno. Questo è un altro problema: per sapere se riesco a eseguire una routine senza andare in nesting devo sapere esattamente quanto dura, non posso fare una media; posso eventualmente utilizzare il caso peggiore e usare quello come limite, ma capite bene che non è per nulla efficiente e, in ogni caso, più soggetto a problemi di instabilità.
Poi è ovvio che ci sono dei limiti di buonsenso: non saranno certo un paio di if a creare asimmetria, ma da 2 a 15 ce ne ballano 13...

@Davide:"Se torni indietro con mandrino fermo, il sincronismo con l'encoder va a farsi friggere o no ?!"
No Davide. Ti spiego.
Dal momento che l'ELS è acceso in modalità filettatura, qualsiasi posizione assuma il mandrino e qualsiasi posizione assuma il carro (comandato dalla vite) viene tracciata.
Nel dettaglio:

- il mandrino conta in modo incrementale n passi al giro (in funzione della risoluzione) e mantiene in memoria l'esatto passo in cui si trova in quel momento. Faccio un esempio, poniamo che il mandrino sia da 1000 passi giro ed abbia eseguito 4500 passi dal punto 0 (index assoluto), questo vuol dire che il mandrino ha fatto 4 giri completi e mezzo giro dall'index assoluto. E tu potresti pure pensare: "sticazzi" :risatina: ... ma aspetta che poi ci torniamo.

- anche la vite conta in modo incrementare e nel caso spcifico il codice conta i passi che sono stati generati per muovere lo stepper ad essa collegato; è il codice stesso a generare i passi quindi non ha nessuna difficoltà a tenere il conto.... Viene da se che, sapendo dove mi trovo, posso liberamente tornare al punto 0 (index assoluto) generando lo stesso numero esatto di passi nella direzione inversa.

Una volta che la vite è tornata a punto 0, vediamo cosa dobbiamo fare col mandrino. E' vero che il conto è incrementale e nell'esempio che ti ho fatto sopra siamo a 4500passi dall'index assoluto, ma sappiamo bene che il mandrino gira di 360 gradi poi torna a 0 (index relativo) quindi NON CI FREGA NIENTE di tornare all'index assoluto (come per la vite), ma basterà intercettare l'index relativo che avviene ad ogni giro ed in particolare ogni volta che il numero assoluto di passi è perfettamente divisibile per i numero di passi giro! che io sia a 4500 passi, a 13245 passi, a 102456 passi non cambia niente, basterà far ruotare il mandrino e controllare il resto di una divisione a modulo tra il numero di passi attuale e il numero di passi giro.
La divisione a modulo, per chi non lo sapesse, non restituisce il risultato della divisione ma SOLO IL RESTO. In linguaggio di programmazione viene indicata sol simbolo %.
Esempio: mi trovo a 43565 passi assoluti, divido a modulo 43565%1000 = 565. Ovvero, il 43565 sta nel 1000 43 volte con il resto di 565. A noi non interessa che ci sta 43 volte, ma solo che il resto è 565. Nel nostro caso non va bene perchè, essendo il nostro index assoluto a 0, dobbiamo girare finchè non troviamo il resto = 0 ! 44000%1000 = 0! questo è il nostro index e da qui possiamo ripartire con l'avanzamento della vite riprendendo la filettatura nello stesso identico punto della passata precedente.
McMax

“None of us can change the things we’ve done. But we can all change what we do next.” – Fred Johnson

fulminato in tenera età
matteou
FINALMENTE USO IL TORNIO
Messaggi: 564
Iscritto il: mar nov 10, 2009 12:36
Località: Udine

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da matteou »

Permettimi, McMax, di fare il rompiscatole. Potrei dirti "si, hai ragione" ma continuare a fare di testa mia.
Ma a quel punto non avrei imparato nulla e tanto valeva che io scrivessi sul forum.
Quindi, la mia non e' pedanteria o testardaggine ma voglia di capire a fondo.

Il tuo discorso mi e' chiaro e lo condivido a livello generale. Ma nel caso specifico non sono pienamente convinto.
Mi spiego con un esempio:
solito caso di impulsi dall'encoder spaziati di 8uS.
uso una routine di interrupt semplice, dove leggo solo l'encoder ed incremento una variabile. Il tempo di esecuzione e' di 2uS (ipotizziamo).
Ma nel resto del programma, io - programmatore analfabeta - vado a leggermi la variabile che incremento nell'interrupt e, soddisfatte le condizioni, vado a calcolarmi i passi facendo divisioni float in real-time, tengo traccia della posizione del carro e la converto in mm per visualizzarla sul display, uso la funzione digitalWrite per mettere alto il segnale di step, faccio un delay di 10uS e uso un altro digitalWrite per mettere basso il segnale di step.
Ipotizziamo che da quando ho soddisfatto le condizioni per sparare un impulso di step a quando effettivamente l'ho sparato passino 20uS.
Secondo i tuoi canoni, il programma e' efficiente? SI. E' stabile? SI. E' simmetrico? SI. Funziona? NO.
Il mio e' un esempio volutamente esagerato ma spero sia chiaro il mio dubbio.
Poi stiamo parlando tanto per parlare (ma ripeto, a me piace capire e non prendere per oro colato quello che mi dicono) perche', all'atto pratico, filettare a 300 giri con un encoder da 300ppr x4 vuol dire avere 166uS tra un impulso e l'altro. Non e' che serva tutta questa potenza di calcolo per stargli dietro...

Per quanto riguarda la mia routine di interrupt, vero che ci sono tanti if ma uno esclude l'altro. Avrei potuto usare anche qualche else ma quella sara' la fase di ottimizzazione.
Poi non mi e' chiaro perche' non posso usare la condizione peggiore per calcolarmi la durata dell'interrupt. Se, nella condizione peggiore, la funzione dura 4uS e io ho impulsi che arrivano al massimo ogni 8uS (condizione peggiore) saro' sicuro di non perdermi neanche un impulso (e nel mio caso, di generare correttamente e per tempo il segnale di step).
Avatar utente
Davide Resca
CAPO OFFICINA
Messaggi: 13818
Iscritto il: lun feb 29, 2016 11:29
Località: Ustica & Dintorni saltuariamente Bologna o Pesaro
Contatta:

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da Davide Resca »

Ok boys, mi avete convinto... ve lo avevo detto che era un mio limite, se ero sudiato come voi lo avrei fatto io l'ELS :mrgreen:
Gli errori sono per i principianti, noi esperti puntiamo al disastro !!!
Le conoscenze acquisite, sono proporzionali al DANNO PRODOTTO !!! ( esperienza personale...)
youtube



Immagine 2°socio TIRATOSAURO CLUB ITALIAN
matteou
FINALMENTE USO IL TORNIO
Messaggi: 564
Iscritto il: mar nov 10, 2009 12:36
Località: Udine

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da matteou »

McMax, ancora un appunto, vediamo se ho sbagliato io oppure comincio a capire (e quindi posso permettermi di farti critiche :grin: ) e hai sbagliato tu.
Nella tua routine di interrupt hai calcolato i tempi basandoti sulle operazioni che fai. Pero' non hai considerato i tempi per caricare i dati, specie dall'array.
Per curiosita', ho caricato la tua routine in proteus e ho ottenuto il codice assembly.
Ad esempio, per modificare la variabile absolute_encoder_steps (immagine allegata) impieghi 32 cicli di clock (2uS solo li').
Non hai i permessi necessari per visualizzare i file allegati in questo messaggio.
Avatar utente
McMax
CAPO OFFICINA
Messaggi: 8996
Iscritto il: dom gen 31, 2010 21:46
Località: Bussero (MI)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da McMax »

Matteou:"Ipotizziamo che da quando ho soddisfatto le condizioni per sparare un impulso di step a quando effettivamente l'ho sparato passino 20uS.
Secondo i tuoi canoni, il programma e' efficiente? SI. E' stabile? SI. E' simmetrico? SI. Funziona? NO."
Questi non sono i miei canoni. Sono la tua interpretazione dei miei canoni parafrasando ciò che ho scritto.
E comunque anche in queste condizioni estreme il sistema manterrà la lettura dell'encoder proprio perchè quella è la parte prioritaria. Il display non va aggiornato e comuqnue, volendo, si potrebbe fare, ma a quel punto si che la generazione del passo dovrebbe avere una priorità maggiore rispetto al display: ma non rispetto all'encoder.

Matteou:"ho caricato la tua routine in proteus e ho ottenuto il codice assembly"
Mi pare strano che ci metta così tanto: io non carico dati in un array e nemmeno lo vado a scandire con un ciclo, ma vado a leggere una singola cella dell'array (a 8 bit), puntata direttamente dall'indice "port" che è pure a 8 bit. Non ci sono cicli ne condizioni nella routine di interrupt...
Poi per carità mi posso anche fidare di Proteus, evidentemente sa come il compilatore converte il codice, io posso ipotizzarlo ma se lo sapessi avrei scritto compilatori e non codice :risatina:
McMax

“None of us can change the things we’ve done. But we can all change what we do next.” – Fred Johnson

fulminato in tenera età
mimoletti
TORNITORE E FRESATORE
Messaggi: 1140
Iscritto il: dom dic 27, 2009 11:31
Località: Torre del Greco (NA)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da mimoletti »

@Max: Il tempo che intercorre tra un’interruzione quella successiva, si può determinare con estrema precisione, quindi è tutt’altro che random.

La nostra routine non funziona, nel modo in cui l’hai descritta.
Il principio logico è questo:
Nel momento in cui si preme il pulsante di Pause, memorizzo la posizione angolare, con il Reverse retrocede in asincrono di una quantità, precedentemente impostata. Successivamente si preme Play, il sistema riprenderà solo dopo aver raggiunto la posizione angolare precedentemente memorizzata.
Ora immaginiamo che abbia premuto Pause, nell’istante in cui il mandrino si trova ad ore 11.00, premo Reverse, il sistema retrocede il carro della quantità pre impostata, il sistema è ancora in Pause, premo Play e avanzerà esattamente della stessa quantità con cui è retrocesso. Il sistema però partirà solo quando il mandrino sarà nuovamente sulle ore 11.00, ora se quando premo Play e si trovava alle ore 12.00, e assumendo come senso di rotazione quelli anti orario, ripartirà esattamente dopo “un ora”, se invece avessi premuto Play nell’istante in cui si trovava a ore 10.00, ripartirà dopo “undici ore”. In ogni caso farà sempre e comunque qualsiasi sia la lunghezza impostata meno di un giro, prima di riprendere.
E non mi dite che è logicamente impossibile o matematicamente impossibile, perché il sistema è stato ampiamente collaudato, è riprodotto da una 50 di persone.
Che un programmatore di mestiere, avrebbe scritto un codice più efficiente, ve lo concedo.
Tutto è migliorabile.
Solo gli stupidi non cambiano mai idea!

Tornio Wabeco D6000 con ELS; Fresa Wabeco F1210; Segatrice Nebes TM125 Inverter; Tavola a dividere Vertex HV-6,Morsa meccnica Allen MAP/78-N

https://www.youtube.com/watch?v=cobEZI8KvOk
Mario312
APPRENDISTA E ADDETTO ALLE PULIZIE
Messaggi: 37
Iscritto il: mer set 15, 2021 10:31
Località: Brescia

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da Mario312 »

Scusate se mi intrometto nel bel mezzo di una discussione. Volevo farvi una domanda, dato che io sono abituato a filettare sganciando il carro ogni volta invece che invertire il senso di rotazione senza mai sganciarlo
Posso filettare in modalità avanzamento e aumento da li il passo?
matteou
FINALMENTE USO IL TORNIO
Messaggi: 564
Iscritto il: mar nov 10, 2009 12:36
Località: Udine

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da matteou »

Questo e' il codice assembly della tua routine di interrupt cosi' come la compila l'ide di arduino (ver. 1.8.1.13).
Uff... pur mettendolo come codice non mi mantiene la formattazione. Fa cacarissimo ma spero si capisca lo stesso (adesso non ho piu' tempo per riformattare).

Codice: Seleziona tutto


 25c:	89 b1       	in	r24, 0x09	; 9										         	1 ciclo
 25e:	8c 70       	andi	r24, 0x0C	; 12								                 	1 ciclo
 260:	90 91 16 01 	lds	r25, 0x0116	; 0x800116 <_ZZ4loopE12prev_encoder>		2 cicli
 264:	89 2b       	or	r24, r25												1 ciclo
 266:	90 e0       	ldi	r25, 0x00	; 0											1 ciclo
 268:	fc 01       	movw	r30, r24											1 ciclo
 26a:	e0 50       	subi	r30, 0x00	; 0								         		1 ciclo
 26c:	ff 4f       	sbci	r31, 0xFF	; 255								                 	1 ciclo
 26e:	20 81       	ld	r18, Z												2 cicli
 270:	40 91 14 01 	lds	r20, 0x0114	; 0x800114 <steps>						2 cicli
 274:	50 91 15 01 	lds	r21, 0x0115	; 0x800115 <steps+0x1>					2 cicli
 278:	42 0f       	add	r20, r18												1 ciclo
 27a:	51 1d       	adc	r21, r1												1 ciclo
 27c:	27 fd       	sbrc	r18, 7										                 	1/2/3 cicli
 27e:	5a 95       	dec	r21													1
 280:	50 93 15 01 	sts	0x0115, r21	; 0x800115 <steps+0x1>					2 
 284:	40 93 14 01 	sts	0x0114, r20	; 0x800114 <steps>						2
 288:	c0 90 10 01 	lds	r12, 0x0110	; 0x800110 <__data_end>					2
 28c:	d0 90 11 01 	lds	r13, 0x0111	; 0x800111 <__data_end+0x1>					2
 290:	e0 90 12 01 	lds	r14, 0x0112	; 0x800112 <__data_end+0x2>				2
 294:	f0 90 13 01 	lds	r15, 0x0113	; 0x800113 <__data_end+0x3>				2
 298:	42 2f       	mov	r20, r18											        1
 29a:	22 0f       	add	r18, r18												1
 29c:	55 0b       	sbc	r21, r21												        1
 29e:	66 0b       	sbc	r22, r22												1
 2a0:	77 0b       	sbc	r23, r23												1
 2a2:	4c 0d       	add	r20, r12												1
 2a4:	5d 1d       	adc	r21, r13												1
 2a6:	6e 1d       	adc	r22, r14												1
 2a8:	7f 1d       	adc	r23, r15												1
 2aa:	40 93 10 01 	sts	0x0110, r20	; 0x800110 <__data_end>					2
 2ae:	50 93 11 01 	sts	0x0111, r21	; 0x800111 <__data_end+0x1>				2
 2b2:	60 93 12 01 	sts	0x0112, r22	; 0x800112 <__data_end+0x2>				2
 2b6:	70 93 13 01 	sts	0x0113, r23	; 0x800113 <__data_end+0x3>				2
 2ba:	95 95       	asr	r25													1
 2bc:	87 95       	ror	r24														1
 2be:	95 95       	asr	r25													1
 2c0:	87 95       	ror	r24														1
 2c2:	80 93 16 01 	sts	0x0116, r24	; 0x800116 <_ZZ4loopE12prev_encoder>		        2
 =========================================================================================
															totale		56 cicli
Dai 19 cicli che avevi ipotizzato tu ai 56 che ne fa effettivamente c'e' una bella differenza (sempre al netto della chiamata all'interrupt, degli spostamenti di memoria, ecc...).
Proteus e' piu' pessimista perche' non fa nessuna ottimizzazione del codice (colpa mia, me lo segnalava ma l'ho sempre ignorato).
Ma e' abbastanza intuitivo che se fai a+b=c non puoi contare solo il tempo dell'operazione addizione (1 ciclo) ma dovrai anche contare il tempo speso per andare a cercare a e b e per andare a scrivere c.
Per quanto riguarda sapere scrivere compilatori o meno, ti rimando a quello che avevi scritto il 24-11 (cito: "Ricordo che i linguaggi compilati come il C spesso sono fuorvianti perché il program... ecc..."). Se tu sei convinto che la tua routine di interrupt dura 1us quando, in realta', ne dura quasi 4 rischi di incorrere in problemi (perdi passi e non sai perche').
Io, conscio di aver scritto una routine di interrupt lunga, mi son posto il problema e ho misurato (empiricamente se vuoi ma tenendomi un bel margine, ricordo che ho fatto la prova simulando 3600 giri e passo 3, cosa che, nella realta', non succedera' mai) se il mio programma riuscisse a fare tutto in tempo.

McMax: "Questi non sono i miei canoni. Sono la tua interpretazione dei miei canoni parafrasando ciò che ho scritto."
Io l'ho voluta fare volutamente esagerata. Visto che non ci leggono solo programmatori professionisti, il programmatore della domenica che c'e' in me (che penso sia la granparte di quelli che leggono) appena ha letto la tua spiegazione ha pensato: "oibo', quindi se faccio una routine di interrupt veloce sono a posto, il resto e' secondario".
Poi, il programmatore un pochettino piu' svegli che c'e' in me ha pensato: "aspetta un momento, se non genero i passi in tempo mi interessa relativamente di riuscire ad intercettare tutti gli impulsi dell'encoder".
Quindi verissimo che la routine di interrupt deve essere veloce pero' anche quello che ne consegue deve essere altrettanto veloce. Insomma, tra un impulso di encoder e l'altro, io devo essere in grado di stabilire se sparare il segnale di step e, se e' il caso, sparare il segnale di step corretto e tener traccia della posizione del carro prima che mi arrivi un altro impulso di encoder.
Su questo siamo d'accordo? Spero di si.
Quindi, fin'ora, tu hai parlato della velocita' di esecuzione dell'interrupt ma, a logica, dovremmo guardare anche la velocita' di esecuzione della routine di gestione dello stepper (vedi il mio esempio volutamente esagerato). La somma della durata di entrambe deve stare all'interno dell'intervallo tra due impulsi di encoder.
Altrimenti il programma non fara' quello per cui e' stato pensato.
Io ho messo tutto all'interno della routine di interrupt per comodita' e per avere tutto cio' che e' rilevante in un'unica funzione.
Avrei potuto dividere le due cose, lasciare nell'interrupt la lettura dell'encoder e in un altra funzione la gestione dello stepper. Sarebbe stato concettualmente piu' corretto? Sicuramente si. Sarebbe stato piu' efficiente? Probabilmente no.
Avatar utente
McMax
CAPO OFFICINA
Messaggi: 8996
Iscritto il: dom gen 31, 2010 21:46
Località: Bussero (MI)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da McMax »

Matteou sei venuto qui a chiedere e io ti ho risposto secondo la mia esperienza e le mie conoscenze, anche sulla base di quanto ho studiato a scuola. Certo io la maturità l'ho fatta del 1992 quindi sono passati quasi trent'anni ma il C++ (che fu peraltro materia della mia tesina) non è cambiato molto.
Io ti ringrazio per esserti adoperato nel discernere il mio codice e anche per aver analizzato in dettaglio la durata della mia routine di interrupt: certo sono stato un po' ottimista su alcune operazioni ma con 3.5usec direi che ho comunque un buon margine rispetto ai limiti che ho imposto. Parliamo pur sempre di una routine in grado di intercettare passi a 285Khz, non mi pare faccia poi così schifo.

Ora avrei una domanda, e ti prego di non prendertela a male, ma davvero sto perdendo di vista lo scopo di tutta questa discussione: perché ti stai adoperando così tanto per convincermi che la gestione dello stepper è meglio farla sotto interrupt? Ti ho già detto qual'è la mia opinione e te l'ho anche argomentata, non sarà certo la mia mancata approvazione a fermarti.... a quanto pare sai benissimo cosa stai facendo quindi a che pro volermi convincere a tutti i costi ?
McMax

“None of us can change the things we’ve done. But we can all change what we do next.” – Fred Johnson

fulminato in tenera età
matteou
FINALMENTE USO IL TORNIO
Messaggi: 564
Iscritto il: mar nov 10, 2009 12:36
Località: Udine

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da matteou »

Non era mia intenzione fare a gare a chi ce l'ha piu' lungo ne' tantomeno tentare di convincere qualcuno. Io ho solo da imparare e discutendo si impara sempre (vedi ad esempio la funzione millis() e micros() che pensavo fossero ben piu' precise, non mi ero neanche mai posto il dubbio).
Per le risposte che mi hai dato e per aver condiviso il tuo lavoro ti ho sempre ringraziato e continuero' a farlo.
Io la maturita' l'ho fatta nel 2002 ma la mia tesina riguardava la crisi del 29... mi sono avvicinato alla programmazione per voglia di capire il programma fatto dal russo e, grazie alla mia morosa (e al corso di c++ che ha fatto in universita') pian piano ho cominciato a capire, provare, giocare e, credo, migliorare pian piano. Sono autodidatta, quindi sono un praticone, mi manca tanta teoria (ad esempio i tuoi canoni, tuoi non perche' te li sei inventati tu ma perche' li hai semplicemente riportati tu).
Io parto da un problema e cerco di risolverlo. A volte capisco quello che faccio, a volte un po' meno. Pero', partendo dalla pratica e studiando la teoria che mi serve di volta in volta, tutto quello che definisce un programma ben scritto stilisticamente e concettualmente mi manca (ne son conscio e, visto che hai tirato fuori l'argomento, volevo approfondire).
Quando mi trovo davanti una persona che reputo intelligente e brava in quello che fa, cerco di rubare piu' cose che posso. A volte mi rendo conto di essere pesante, a volte lo faccio senza accorgemene.
Ancora una premessa: se chi ho davanti sbaglia (e lo reputo una persona intelligente) mi sembra giusto correggerlo. Imparera' lui e imparero' io (ad esempio non ho "perso tempo" a disassemblare la tua routine di interrupt solo per dire che avevi sbagliato, non e' il mio scopo. Io volevo vedere se la mia intuizione era corretta e trovare il modo per verificarlo).
Premesso questo, torniamo sull'argomento:
1. non ho mai detto che la tua routine faccia schifo, anzi. E non e' mio interesse farlo.
2. non me la prendo, ci mancherebbe. Io non voglio convincere nessuno. Voglio capire, che e' diverso (vedi le premesse sopra). E non mi sto adoperando per convincerti ma semplicemente per capire (il fatto di disassemblare il codice e andare a vedere quanti cicli occupa ogni istruzione non mi sarebbe mai passata per la testa se non avessi letto il tuo messaggio. Il fatto che un compilatore ottimizzi di piu' o di meno lo sapevo ma e' interessante - e affascinante - vedere fino a che punto).

Per fare un sunto: io ho fatto una routine di interrupt. Tu me l'hai bocciata motivando. Io ti ho risposto contromotivandolo.
Visto la determinazione con cui hai bocciato la routine di interrupt, mi son chiesto perche' non potesse andare bene e ti ho risposto con le mie motivazioni e con l'esempio volutamente esagerato.
Tu mi hai risposto che il programma avrebbe funzionato lo stesso perche' riusciva lo stesso a leggere tutti i passi dell'encoder (anche se poi non riusciva a generare gli impulsi di step).
A questo punto mi interessa capire se le tue critiche sono "solo" su una questione stilistica (o di concetto, di principio, di forma) o su una questione di sostanza.
Nel primo caso prendo le tue osservazioni come consigli ma, a parte la bellezza del codice, non cambia nulla.
Se le critiche sono di sostanza (e non solo di forma) la cosa si complica un po' perche' vuol dire che tutto il mio ragionamento e' sbagliato (e quindi, prima ancora di toccare il codice e' da cambiare modo di ragionare).
Quindi non sono io che cerco di convincere te ma ti sto chiedendo di convincermi che i tuoi argomenti siano giusti... e ripeto, non perche' mi interessi farti cambiare idea ma semplicemente per capire se il mio e' un errore di forma o un errore di sostanza.
Ultima modifica di matteou il mer nov 24, 2021 20:37, modificato 1 volta in totale.
Avatar utente
McMax
CAPO OFFICINA
Messaggi: 8996
Iscritto il: dom gen 31, 2010 21:46
Località: Bussero (MI)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da McMax »

Mario312: "...dato che io sono abituato a filettare sganciando il carro ogni volta invece che invertire il senso di rotazione senza mai sganciarlo
Posso filettare in modalità avanzamento e aumento da li il passo?"

No penso di aver capito bene cosa vuoi fare. Tu la chiocciola la puoi staccare se il passo della vite è multiplo del passo che stai costruendo; in tutti gli altri casi se stacchi la chiocciola perdi il sincronismo.
Con l'ELS (il mio chiaramente, degli altri non posso rispondere) puoi filettare in 2 modi:
- vincolo meccanico: questo è ESATTAMENTE come se avessi montato le ruote sulla testa di cavallo per filettare meccanicamente. La vite segue il mandrino in ogni direzione mantenendo il passo che hai impostato.
- filettatura a misura: qui imposti la lunghezza del filetto e il carro torna da solo (premendo una combinazione di tasti) all'inizio del filetto per la seconda passata. Questa operazione di ritorno del carro la puoi fare a prescindere da cosa stia facendo il mandrino in quel momento: può girare in entrambe le direzioni o stare fermo, non cambia nulla. Certo il ritorno non è velocissimo come quando stacchi la chiocciola ma tranquillo che non ti addormenti :risatina:
McMax

“None of us can change the things we’ve done. But we can all change what we do next.” – Fred Johnson

fulminato in tenera età
mimoletti
TORNITORE E FRESATORE
Messaggi: 1140
Iscritto il: dom dic 27, 2009 11:31
Località: Torre del Greco (NA)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da mimoletti »

Max: Ma anche nel tuo, retrocedi in modo asincrono, quando filetti a misura?
Solo gli stupidi non cambiano mai idea!

Tornio Wabeco D6000 con ELS; Fresa Wabeco F1210; Segatrice Nebes TM125 Inverter; Tavola a dividere Vertex HV-6,Morsa meccnica Allen MAP/78-N

https://www.youtube.com/watch?v=cobEZI8KvOk
Avatar utente
McMax
CAPO OFFICINA
Messaggi: 8996
Iscritto il: dom gen 31, 2010 21:46
Località: Bussero (MI)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da McMax »

Matteo, cerco di argomentare un po' meglio sperando di riuscire a passarti il concetto.
Partiamo da un assunto che qualsiasi programmatore ti potrà confermare: le routine di interrupt vanno tenute più brevi possibili.
cito dal manuale di Arduino, che in questo caso dice delle ovvietà che puoi trovare riferite a qualsiasi microcontrollore o microprocessore:
" Interrupts are useful for making things happen automatically in microcontroller programs and can help solve timing problems. Good tasks for using an interrupt may include reading a rotary encoder, or monitoring user input."
e ancora:
"Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be executed after the current one finishes in an order that depends on the priority they have."

In particolare ci ho tenuto ad evidenziare in neretto 2 concetti base che ti avevo già trasmesso e tra i due, a parte quello ovvio sulla durata, quello sul buon utilizzo dell'interrupt che ad esempio è la lettura di un rotary encoder (guarda caso) o il monitoraggio di un ingresso. Come vedi NON si parla di output ma solo di input. Con questo non vuol dire che non puoi usare un interrupt per generare un output, ma semplicemente tra i "good task" l'output non c'è.
A tal proposito apro una parentesi e rispondo anche al buon Massimo:
mimoletti:"Il tempo che intercorre tra un’interruzione quella successiva, si può determinare con estrema precisione, quindi è tutt’altro che random"
un ingresso che cambia di stato autonomamente, anche se per te all'esterno del sistema è perfettamente determinabile, non lo è per il microcontrollore. Un evento esterno, anche sincrono come un impulso a frequenza costante, è un evento randomico perché come tale il micro lo deve trattare.

Ma torniamo all'interrupt.
Matteo ho capito che hai compreso che quelle che ti ho incollato sopra sono linee guida generali oppure, come le chiamano gli inglesi "best practices", ma tu vuoi capire perché le devi seguire e cosa succede se non le segui. Qui no possiamo più generalizzare e dobbiamo analizzare il caso specifico, ovvero il nostro ELS.
Iniziamo con mettere alcuni paletti:
- il sistema che stiamo sviluppando si basa sulla risoluzione di un ingresso (il passo encoder) per generare un uscita (il passo stepper).
- Il limite di risoluzione del sistema è imposto dall'encoder. Io al massimo potrò generare un passo stepper per ogni passo encoder, non di più. Posso ovviamente decidere di generare più passi stepper per ogni passo encoder ma la risoluzione del sistema non cambierà in quanto il passo stepper (o i passi) in aggiunta vengono fatti in modo arbitrario e senza avere un riferimento.
- Nella stragrande maggioranza dei casi io genererò molti meno passi stepper rispetto ai passi encoder che avrò letto

e su questo non credo ci sia nulla da aggiungere.

A questo punto mi trovo nella situazione in cui ho un programma che gira dove saranno molte di più le volte che mi troverò a leggere un passo encoder rispetto a quelle in cui dovrò generare un passo stepper. Non è sempre vero ovviamente, io posso anche dover costruire un passo molto lungo per cui avrò un passo stepper per ogni passo encoder ma questo è 1 solo caso (raro) su molti, ed in ogni caso non potrò avere una situazione in cui dovrò generare più di un passo stepper per ogni passo encoder....
Se io faccio una routine di interruppt che include anche la generazione del passo stepper, seppur ovviamente sotto if, sono costretto a controllare ogni volta se lo devo generare o meno con il risultato che andrò ad eseguire un controllo, SOTTO INTERRUPT, che il più delle volte sarà inutile. Attenzione ora tu mi potrai dire, si ma il controllo lo devo eseguire comunque fuori dalla routine di interrupt, unitamente al calcolo per capire se il passo lo devo fare o meno: vero, ma li non vai a disturbare la lettura dell'encoder perché, se sei fuori dalla routine di interrupt, puoi gestire un interrupt.... se ti trovi all'interno della routine e ti arriva un interrupt NON lo puoi gestire.

Puoi anche interpretare questo come una gran supercazzola con il solo fine di rendere il codice formalmente più bello, e fintanto che anche la tua soluzione funziona questo è senz'altro vero, ma nel momento in cui dovessi riscontrare un problema "runtime" allora si che forse capirai che nella programmazione forma e sostanza a volte si mischiano ed è difficile capire dove finisce una ed inizia l'altra.
McMax

“None of us can change the things we’ve done. But we can all change what we do next.” – Fred Johnson

fulminato in tenera età
mimoletti
TORNITORE E FRESATORE
Messaggi: 1140
Iscritto il: dom dic 27, 2009 11:31
Località: Torre del Greco (NA)

Re: ELS (Electronic Lead Screw) - progetto con ARDUINO

Messaggio da mimoletti »

Max: Ma anche nel tuo, retrocedi in modo asincrono, quando filetti a misura?

mimoletti:"Il tempo che intercorre tra un’interruzione quella successiva, si può determinare con estrema precisione, quindi è tutt’altro che random"
un ingresso che cambia di stato autonomamente, anche se per te all'esterno del sistema è perfettamente determinabile, non lo è per il microcontrollore. Un evento esterno, anche sincrono come un impulso a frequenza costante, è un evento randomico perché come tale il micro lo deve trattare.


Non c'è nulla di logico in quello che dici, un evento random resta tale a prescindere da chi lo osserva o dal mezzo che lo deve determinare.
Le estrazioni del lotto sono un'evento random!
Solo gli stupidi non cambiano mai idea!

Tornio Wabeco D6000 con ELS; Fresa Wabeco F1210; Segatrice Nebes TM125 Inverter; Tavola a dividere Vertex HV-6,Morsa meccnica Allen MAP/78-N

https://www.youtube.com/watch?v=cobEZI8KvOk
Bloccato

Torna a “Elettronica ed elettrotecnica”