Sostieni il forum con una donazione! Il tuo contributo ci aiuterà a rimanere online!
Immagine

Re:politica midi

Tutto ciò che riguarda l'elettronica digitale, dalla porta not al protocollo midi... e oltre!
Rispondi
Avatar utente
Dimitree
Diyer Esperto
Diyer Esperto
Messaggi: 425
Iscritto il: 01/09/2006, 23:56

politica midi

Messaggio da Dimitree » 02/04/2010, 16:50

ciao ragazzi
allora, volendo programmare un microcontrollore per ricezione midi, si può facilmente gestire una routine di interruzione che non fa altro che gestire un buffer circolare, in modo da prendere tutti i messaggi midi che arrivano e passarli piano piano alla funzione che li elabora. Bene fin qui tutto ok.
ora mettiamo caso che la funziona che elabora un singolo messaggio occupi il processore per qualche tempo, diciamo 1 secondo, con l'arrivo di diversi messaggi, l'ultimo di questi verrà elaborato dopo un bel pò di tempo.
Faccio un esempio banale:
facciamo finta che la funzione prenda il messaggio Control Change appena arrivato, e qualsiasi valore abbia, faccia lampeggiare 10 volte un led ogni 100ms, quindi ogni CC provoca 1 secondo di lampeggiamento. Quindi, se durante quel secondo di lampeggiamento sono arrivati altri 10 control change, il decimo messaggio sarà elaborato dopo 10 secondi, essendosi dovuto mettere in fila  :lol1:
in molti casi non è quello che si vuole, ovvero, facciamo finta di dover scorrere le patch con una pedaliera, si inviano al controllore un sacco di messaggi, ma noi chiaramente stavamo solo scorrendo per raggiungere quello che intendiamo usare, invece il microcontrollore è costretto a elaborare tutto quello che riceve e che gli è dato ricevere.
Allora, cosa si può fare per evitare questo?
io pensavo di aggiungere una condizione nella routine di interrupt, del tipo "se arriva uno Status Byte del giusto canale e del giusto tipo, invece di tornare al punto in cui l'interrupt è arrivato, torna al programma principale", così facendo l'ultimo status byte fa ripartire il tutto, e non è costretto a perdere tempo con messaggi che non vogliamo elaborare.
il fatto è che per realizzare questa cosa bisogna fare una chiamata a funzione all'interno dell'interrupt, e non mi piace molto, visto che una volta che la funzione chiamata avrà finito, il programma torna all'interno dell'interrupt (o sbaglio?) e quindi una volta finita la routine interrupt torna al punto in cui l'interrupt era arrivato, insomma un vero macello!
voi che dite?
Ultima modifica di Anonymous il 02/04/2010, 16:53, modificato 1 volta in totale.

Avatar utente
davidefender
Garzone di Roger Mayer
Garzone di Roger Mayer
Messaggi: 1437
Iscritto il: 11/02/2008, 23:51
Località: Roma
Contatta:

Re:politica midi

Messaggio da davidefender » 02/04/2010, 17:22

Dimitree ha scritto: voi che dite?
osservazione giusta, ma ti stai complicando la vita!  :arf2:
Proprio perchè la funzione chiamata in fase di interrupt è cruciale di solito la si fa la più snella possibile, 1 secondo non è una funzione di interrupt, è un abominio!  :lol1:

La tua funzione di interrupt NON si deve occupare del led che lampeggia, questo lo deve fare una funzione normale... l'interrupt routine dovrebbe solo mettere il dato nel buffer, ed incrementare di 1 la dimensione del buffer (per indicare che è stato inserito un nuovo dato); con questa struttura, per effettuare un lampeggio all'arrivo di un dato puoi inserire un loop nel main:

while(true) {
  if (buffer.size() > 0) then {
    buffer.read();
    led.setStatus(ON);
    delay(100);
    led.setStatus(OFF);
  }
}

in questo modo se ti arrivano 120 messaggi, il led lampeggerà 120 volte ma non ne perderai neppure 1. In realtà potresti andare incontro ad un altro problema: buffer overflow, ovvero perdendo tempo a far lampeggiare il led consumi troppo lentamente il dato e la interrupt routine non sa più dove mettere le informazioni; le soluzioni sono due: o allarghi il buffer, o velocizzi la "consumazione" del dato.

Attento però, non pensare che questo sia un "difetto" in realtà è una situazione piuttosto fisiologica: se ad un evento fisico molto veloce, si cerca di star dietro con un evento fisico troppo lento, è ovvio che si va in saturazione! Nell'esempio del cambio patch il problema non si pone poichè la risposta (il cambio ad esempio del display o via dicendo) è talmente veloce che non riuscirai mai a saturare il buffer in ricezione..

Non farti fregare dalla percezione di "velocità" che abbiamo noi poveri umani  :face_green: , per quanto tu possa premere il dito velocemente sul tastino "patch up", fra una ditata e l'altra per il microcontrollore passa un'eternità! fidati  :fonz: Lo so per esperienza,  :face_green:
:ciao:
La teoria è quando si sa tutto ma non funziona niente. La pratica è quando funziona tutto ma non si sa il perché. In ogni caso si finisce sempre con il coniugare la teoria con la pratica: non funziona niente e non si sa il perché.
(Albert Einstein)

Avatar utente
Dimitree
Diyer Esperto
Diyer Esperto
Messaggi: 425
Iscritto il: 01/09/2006, 23:56

Re:politica midi

Messaggio da Dimitree » 02/04/2010, 17:34

Davide grazie per la risposta, mi sono spiegato male però

l'interrupt infatti non si occupa del led, non fa altro che prendere il byte, metterlo nella coda, e finisce là, saranno 3-4 istruzioni.
poi la funzione principale è quella che perde tempo, infatti prende dalla coda il byte, e lo elabora. Bene, il fatto è che se per ogni byte spreca 1 secondo di tempo, arrivati 10 byte, sprecherà 10 secondi di tempo, e se uno manda l'undicesimo byte nel frattempo, deve aspettare che passino quei 10 secondi di tempo, quando invece uno vorrebbe che l'ultimo byte sia elaborato all'istante. Non so se mi sono spiegato ora.  :Gra_1:

Avatar utente
jackson
Diyer Esperto
Diyer Esperto
Messaggi: 402
Iscritto il: 24/01/2010, 12:44
Località: Curno (BG)

Re:politica midi

Messaggio da jackson » 02/04/2010, 20:13

Dimitree ha scritto: ...
  , quando invece uno vorrebbe che l'ultimo byte sia elaborato all'istante. Non so se mi sono spiegato ora.  :Gra_1:
allora devi fare una LIFO e non un FIFO  :lol1:

:bye1:
Jack!
Immagine
Immagine

Avatar utente
Dimitree
Diyer Esperto
Diyer Esperto
Messaggi: 425
Iscritto il: 01/09/2006, 23:56

Re:politica midi

Messaggio da Dimitree » 02/04/2010, 20:22

eh no sai che macello in quel modo  :lol1:
prima di tutto si mischierebbero Status e Data, e poi mi elaborerebbe prima gli ultimi e poi quelli arrivati prima..insomma, è il contrario di quello che vorrei  :lol1:

Avatar utente
davidefender
Garzone di Roger Mayer
Garzone di Roger Mayer
Messaggi: 1437
Iscritto il: 11/02/2008, 23:51
Località: Roma
Contatta:

Re:politica midi

Messaggio da davidefender » 03/04/2010, 0:54

allora, nonostante credo che si sbagliato proprio il principio (tu devi puntare a soddisfare tutte le richieste, e non a scartarne alcune..) a questo punto potresti sviluppare un software più sofisticato.. sciluppa la funzione del led come una sorta di "transazione" ovvero, devi avere la possibilità di abortirla.

A questo punto l'interrupt routine  deve poter sapere se c'è già un'esecuzione della transazione (magari con un flag settato a 1), deve abortirla e riprogrammare una nuova esecuzione.. tutto questo secondo me è del tutto sproporzionato, torno a dire che il vero grande problema di questo programma è che non posso tenere la CPU occupata per un secondo e poi voler stare attento a tutti i dati che ricevo...

ma hai un esempio pratico su dove tu debba utilizzare questa cosa?
La teoria è quando si sa tutto ma non funziona niente. La pratica è quando funziona tutto ma non si sa il perché. In ogni caso si finisce sempre con il coniugare la teoria con la pratica: non funziona niente e non si sa il perché.
(Albert Einstein)

Avatar utente
jackson
Diyer Esperto
Diyer Esperto
Messaggi: 402
Iscritto il: 24/01/2010, 12:44
Località: Curno (BG)

Re:politica midi

Messaggio da jackson » 03/04/2010, 2:10

giusto per capire meglio! quando ti arriva un evento MIDI tu, con una routine di interrupt memorizzi in uno stack i dati dell'evento, e qui finisce la routine di interrupt e il programma continua da dove aveva finito! ho detto giusto  :????:
se è cosi, potresti, a priori, decidere quali eventi devono avere una precedenza e segnalarli al programma principale settando un flag, grazie al quale lui sospenderà l'operazione in corso per dare precedenza a quella appena arrivata.
comunque, come dice Davide se ci fai un esempio pratico, forse riusciamo ad esserti di maggior aiuto!  :face_green:

:bye1:
Jack!
Immagine
Immagine

Avatar utente
Dimitree
Diyer Esperto
Diyer Esperto
Messaggi: 425
Iscritto il: 01/09/2006, 23:56

Re:politica midi

Messaggio da Dimitree » 03/04/2010, 14:26

tu devi puntare a soddisfare tutte le richieste, e non a scartarne alcune..
se si trattasse di un semplice programma di switching immediato, o cambio preset ecc, non ci sarebbero problemi..però non è questo il caso
non ho un applicazione precisa, però cercherò di fare un esempio pratico:

allora, io chitarrista ho una pedaliera midi a terra, tipo la GCX, insomma, una di quelle con display e preset. Poi ho il mio aggeggio midi programmato per ricevere program change. Facciamo che questo elabora solo i program change da 1 a 10, sul canale 16. L'aggeggio ha 10 led, e se per esempio riceve Program change 03, il led 3 lampeggia per 2 secondi, se riceve Program change 08, il led 8 lampeggia per 2 secondi, e così via. Quindi ogni program change tiene occupato 2 secondi il microcontrollore.
Bene, a inizio concerto accendo la pedaliera, il primo preset richiama program change 01, e quindi il led1 lampeggia. Poi però voglio passare al preset 10, perchè mi serve che lampeggi il led 10. Per far questo sono costretto, da pedaliera, a scorrere i preset. Quindi, ogni volta che scorro, al microcontrollore arriveranno: pc02, pc03, pc04, ecc, fino al pc10. Siccome gli sono arrivati tutti questi program change, il microcontrollore scorrerà il buffer e sarà costretto a elaborare prima il pc02, poi il pc03, ecc. Ognuno di questi occupa 2 secondi il lavoro, quindi dopo 18 secondi diciamo, avrò finalmente il mio pc10 richiamato! disastro, visto che io lo volevo subito  :ok_1:

ripeto, se il main fosse un semplice switch di relay, preset, ecc, insomma senza fattori di tempo, non ci sarebbe questo problema, perchè tutti i preset intermedi verrebbero soddisfatti velocemente (almeno per noi umani) e non ci accorgeremmo del piccolissimo ritardo. Però qua c'è un tappo, che è il tempo imposto al lampeggiamento!
Ultima modifica di Anonymous il 03/04/2010, 14:28, modificato 1 volta in totale.

Avatar utente
jackson
Diyer Esperto
Diyer Esperto
Messaggi: 402
Iscritto il: 24/01/2010, 12:44
Località: Curno (BG)

Re:politica midi

Messaggio da jackson » 03/04/2010, 14:51

allora devi temporizzare la partenza all'esecuzione del PrgChg, in questo senso! quando ti arriva il PC 01, prima di eseguire la routine che fa lampeggiare il led 01, attendi un tempo "x". al termine di "x", se non è arrivato un altro PC, esegui il PC 01. in questo modo, se tu stai scorrendo i preset, il software aspetta che tu ti fermi per eseguire solo la routine dell'ultimo PC arrivato.
ora, però pensandoci bene, sei sicuro che la pedaliera midi manda sempre i pc ogni volta che tu scorri i preset, e non lo faccia solo quando tu hai deciso quale scegliere ??? secondo me, sarebbe + logico. finche scorro i vari preset la pedaliera non ha senso che mandi PC, lo farà solo quando tu dirai quale preset vuoi. esempio, se sono sul preset 01, e comincio a scorrere in avanti, 02...03...04 ecc. e voglio lo 09, quando sono su 09, darò conferma alla pedaliera che a sto punto mi manda il PC 09. ovviamente ciò è una mia idea su come dovrebbe funzionare, quindi potrei aver detto una marea di cazzate

:bye1:
Jack!
Immagine
Immagine

Avatar utente
Dimitree
Diyer Esperto
Diyer Esperto
Messaggi: 425
Iscritto il: 01/09/2006, 23:56

Re:politica midi

Messaggio da Dimitree » 03/04/2010, 15:03

no non credo che la pedaliera faccia in questo modo, o almeno non credo che tutte le pedaliere lo facciano. Insomma, un può scorrere preset a diverse velocità, anche se scorre con un preset al secondo, sarebbe comunque tappato dal mio main che per ogni program change mangia 2 secondi..
Insomma, è un pò come quando uno deve mettere la suoneria sui cellulari, avete presente?
uno le scorre, mentre le scorri iniziano a suonare, ma non bisogna aspettare che finisca la canzoncina per iniziare la prossima, capito?
per questo io dico, la soluzione sarebbe abolire il buffer, e gestire l'interrupt in modo che a ogni messaggio midi valido (ovvero, ogni program change nell'intervallo 1-10 sul ch16, per l'esempio di prima) faccia ripartire il programma che gestisce il messaggio ricevuto. In questo modo l'ultimo messaggio valido ha sempre la precedenza, e i precedenti messaggi sono ormai "obsoleti" e non servono più a niente, quindi la coda neanche servirebbe, perchè se arrivassero subito 3 messaggi, solo il terzo andrebbe soddisfatto.

Rispondi