Pic MIDI Documentation

15
Progetto di un a tastiera “MIDI Master Keyboard” Progetto e realizzazione di un dispositivo per il polling temporizzato di una matrice di contatti e la generazione conseguente di messaggi secondo lo standard musicale MIDI. Corso: Elettronica III Studente: Giancarlo Todone

Transcript of Pic MIDI Documentation

Page 1: Pic MIDI Documentation

Progetto di un a tastiera

“MIDI Master Keyboard”

Progetto e realizzazione di un dispositivo per il polling temporizzato di una matrice di contatti e la

generazione conseguente di messaggi secondo lo standard musicale MIDI.

Corso:

Elettronica III

Studente:

Giancarlo Todone

Page 2: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 1

Introduzione

Lo scopo del progetto era quello di trovare un campo

di utilizzo reale per il microcontrollore Microchip

PIC18F452 che pur dimostrandone la potenza e la

flessibilità, non necessitasse di molta circuiteria

esterna e fosse di facile ed economica costruzione per

chiunque volesse riprodurre il dispositivo. Per

motivazioni contingenti è stato scelto di usare il PIC in

campo musicale, e precisamente per costruire una

cosiddetta “master keyboard” MIDI, o “tastiera muta”,

e cioè un dispositivo che analizzi lo stato di un’insieme

di tasti e resistenze variabili disposti a foggia di

tastiera musicale e generi a partire da esso un

adeguato flusso di dati MIDI con cui comandare un

sintetizzatore, un campionatore o un altro strumento

MIDI “slave”. Per l’hardware dei tasti musicali si è

riciclata una vecchia tastiera che –per quanto non professionale- dispone della forma e dei contatti

appropriati a gestire le caratteristiche richieste. Il protocollo MIDI -riassunto di seguito- dimostra una certa

complessità quando ci si trovi a doverlo interpretare (poiché per questioni tecniche è necessario

decodificare anche molti dati ai quali non si è direttamente interessati) ma si rivela abbastanza semplice nel

momento in cui si debbano invece generare comandi di un insieme ristretto di tipologie. Per il progetto si è

deciso di implementare i comandi MIDI note-on e note-off per segnalare la pressione dei vari tasti, di

leggere la “pitch-wheel” o “controllo del portamento”, di inoltrare comandi relativi al pedale del sustain e

gestire il cosiddetto “active-sensing”: è comunque facile aggiungere a richiesta fino ad altri 7 comandi

analogici e diversi altri comandi discreti (il numero è dipendente da eventuali tecniche di multiplazione). In

particolare, un punto focale dell’intero progetto è la gestione della “velocity” o “dinamica”, cioè della

rapidità -con cui solitamente si approssima la forza- con la quale ogni tasto viene attivato, parametro che di

conseguenza viene usato per comandare l’espressione di ogni singolo suono prodotto. Per poter gestire

tutti gli aspetti discussi finora –in particolar modo la dinamica- è stato necessario progettare del semplice

hardware dedicato, incarnato da due de-multiplexer 74hc138 economici (circa 0,60 euro l’uno) e di

semplice utilizzo, ed è stato inoltre necessario “spremere” abbastanza la potenza del PIC utilizzando un

quarzo da 20 MHz direttamente connesso col microcontrollore. Il resto dei componenti è passivo (tranne il

classico regolatore di tensione 78ls05) e rappresenta il tipico setup per un PIC: alimentazione, clock, reset.

Nel prototipo –perfettamente funzionante- realizzato su piastra millefori, mancano alcune raffinatezze

come resistenze limitatrici di corrente o condensatori di de-bounce, che sono però stati aggiunti nel

progetto CAD sviluppato con il software gratuito EAGLE: grazie ad esso è quindi possibile generare semi-

automaticamente anche una PCB dedicata al circuito, da incidere con i soliti metodi.

Figura 1 - prototipo del dispositivo di polling e generazione

messaggi MIDI

Page 3: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 2

Materiali ed attrezzature

Il Microchip PIC18F452 è un microcontrollore a basso consumo

dotato di una CPU RISC capace di eseguire fino a 10 milioni di

istruzioni al secondo, di 1,5 Kbyte di ram on-chip, 256 bytes di

eeprom gestibile con istruzioni dedicate, memoria programma

di 16 K istruzioni e di diverse periferiche come timers, un

USART e un convertitore AD multiplato su 8 ingressi. Esso

risulta molto comodo per la compatibilità –ottenibile con sforzi

limitati- verso molti altri dispositivi della stessa casa di

produzione, ormai molto diffusi e largamente utilizzati.

Durante questa esperienza è stato quindi possibile riutilizzare il

know-how accumulato con altre periferiche simili, ed

addirittura l’hardware di programmazione precedentemente

auto costruito.

L’altro integrato adottato nel progetto è il 74hc138, una semplice logica combinatoria

che implementa un de-multiplexer mantenendo alte o basse le diverse 8 uscite a

seconda della configurazione binaria presente su 3 ingressi e 3 linee di enable (in figura

pedinatura e tabella di verità). In particolare, quando abilitato, l’integrato –qui usato

nella sua versione invertente- pone a 0v una delle 8 linee di uscita normalmente a Vcc,

corrispondente al numero binario in ingresso sui tre input.

Figura 2 – caratteristiche e pedinatura del

PIC18F452

Figura 3 - pedinatura

dell'integrato

74hc138

Figura 4 - tabella di verità dell'integrato 74hc138, ripresa dal suo datasheet

Page 4: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI

permetta l’interazione con vari hardware

semplice ed economico programmatore JDM (in figura foto e schema elettrico), ricorrendo

all’uscita seriale hardware del PIC per le operazioni di debug.

utilizzato è l’ottimo PicPGM che vanta notevoli funzioni di auto

al quale sono stati dati in pasto direttamente i binari generati da MikroC.

ciclo di polling sono stati usati un’oscilloscopio (non strettamente necessario) e un frequenzimetro auto

costruito (in figura). Una volta terminato e fatto funzionare il prototipo, si è proceduto al disegno CAD dello

schema elettrico con la versione dimostrativa gratuita di EAGLE,

maniera assistita anche le PCB (nella versione dimostrativa limitate per dimensioni).

Figura 6

semplice

programmatore JDM

(autocostruito)

adattato a

funzionare con

packaging diversi

Figura 5 - schema elettrico del programmatore JDM, qui

dimostrato per l'uso con un diverso modello di PIC

Progetto e realizzazione di un controller master MIDI

Per questioni di comodità, e per permettere a chiunque

di costruire la sua versione del dispositivo, si sono usati

software gratuiti o versioni dimostrative gratuite d

software commerciali. Per la programmazione

C/assembler, è stato adottato MikroC, un ambiente

semplice e rapido in cui si produce codice riutilizzabile

anche nel’ufficiale C18 di Microchip (con minime

modifiche); il software permette di creare e ridistri

liberamente progetti, ma permette la compilazione

fino a 2000 parole di istruzione, dopo le quali è

necessario adottare la versione a pagamento (che costa

poco più di 100 euro). Nonostante l’ambiente MikroC

permetta l’interazione con vari hardware di programmazione/ICD, per questo progetto si è fatto uso del più

semplice ed economico programmatore JDM (in figura foto e schema elettrico), ricorrendo

del PIC per le operazioni di debug. Il software di programmazion

utilizzato è l’ottimo PicPGM che vanta notevoli funzioni di auto-detect di programmatori e microcontrollori,

al quale sono stati dati in pasto direttamente i binari generati da MikroC. Per verificare

usati un’oscilloscopio (non strettamente necessario) e un frequenzimetro auto

costruito (in figura). Una volta terminato e fatto funzionare il prototipo, si è proceduto al disegno CAD dello

schema elettrico con la versione dimostrativa gratuita di EAGLE, un software che permette di generare in

maniera assistita anche le PCB (nella versione dimostrativa limitate per dimensioni).

Figura 6 - foto di un

semplice

programmatore JDM

(autocostruito)

adattato a

funzionare con

packaging diversi

elettrico del programmatore JDM, qui

dimostrato per l'uso con un diverso modello di PIC

Figura 7 - utilizzo del frequenzimetro autocostruito

(con PIC16F84) per verificare la frequenza di polling di

circa 1 KHz

Pagina 3

Per questioni di comodità, e per permettere a chiunque

di costruire la sua versione del dispositivo, si sono usati

software gratuiti o versioni dimostrative gratuite di

software commerciali. Per la programmazione

C/assembler, è stato adottato MikroC, un ambiente

semplice e rapido in cui si produce codice riutilizzabile

anche nel’ufficiale C18 di Microchip (con minime

modifiche); il software permette di creare e ridistribuire

progetti, ma permette la compilazione di

fino a 2000 parole di istruzione, dopo le quali è

necessario adottare la versione a pagamento (che costa

poco più di 100 euro). Nonostante l’ambiente MikroC

di programmazione/ICD, per questo progetto si è fatto uso del più

semplice ed economico programmatore JDM (in figura foto e schema elettrico), ricorrendo talvolta

Il software di programmazione gratuito

detect di programmatori e microcontrollori,

verificare la regolarità del

usati un’oscilloscopio (non strettamente necessario) e un frequenzimetro auto

costruito (in figura). Una volta terminato e fatto funzionare il prototipo, si è proceduto al disegno CAD dello

un software che permette di generare in

maniera assistita anche le PCB (nella versione dimostrativa limitate per dimensioni).

utilizzo del frequenzimetro autocostruito

per verificare la frequenza di polling di

Page 5: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 4

Lo schema elettrico

Per completezza, in primis riportiamo anche la

configurazione di base di un PIC. I condensatori C1

e C5 con il regolatore di tensione 78ls05

costituiscono una sorgente di tensione stabilizzata a

5 Vcc. Il valore del condensatore elettrolitico è

abbastanza elevato da garantire la continuità

dell’alimentazione anche durante un elevato

assorbimento da parte di un altro componente del

circuito o durante i possibili sbalzi nella tensione di

alimentazione non regolata (marcata 6-10v), ma

abbastanza basso da consentire un ridotto tempo di

start-up, che consente di polarizzare il piedino di

reset MCLR con una sola resistenza direttamente a

5Vcc, senza condensatori di temporizzazione

(solitamente si collega un condensatore tra MCLR e

GND per fare in modo che il PIC resti resettato

finchè l’alimentazione non si stabilizza). La base dei

tempi utilizza l’oscillatore interno (qui non facciamo

uso di PLL) che si basa sul quarzo esterno -in questo

caso da 20 MHz- stabilizzato dai due condensatori

da 15 pF.

Le linee RD0-RD2 del PIC sono connesse alle linee di ingresso di entrambi gli integrati 74hc138, mentre RD3

è collegata in modo da abilitare uno o l’altro integrato esclusivamente a seconda del suo livello logico;

questo in pratica ci consente di ottenere logicamente un unico de-multiplexer che accetta un numero

binario su 4 bit (quindi da 0 a 15) e pone a livello logico basso la linea corrispondente, lasciando a livello

alto tutte le altre. Per esempio, se RD0-RD3 vale 0, la sola linea “bank A” viene posta a 0v; se RD0-RD3 vale

1, la sola linea “bank B” viene posta a 0v; se RD0-RD3 vale 8, la sola linea “bank A’ ” viene posta a 0v.

Questo consente di effettuare la scansione delle note per banchi. Ognuno degli 8 banchi “A”, “B”, “C”, “D”,

“E”, “F”, “G”, “H” attiva un gruppo di otto note che vengono lette contemporaneamente dagli otto ingressi

Figura 8 - configurazione di base del PIC: alimentazione, clock,

reset.

Figura 9 - de-multiplexer

che gestisce i banchi

"before"; viene attivato

quando RD3 è posto a

livello logico basso

Figura 10 - de-

multiplexer che gestisce

i banchi "after"; viene

attivato quando RD3 è

posto a livello logico alto

Page 6: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 5

RB0-RB7 del PIC. I corrispettivi banchi con l’apice servono per il rilevamento della dinamica; ogni nota

chiude in rapida sequenza due contatti: uno che potremmo chiamare “before” e successivamente un altro

che potremmo chiamare “after”. Da quanto ravvicinatamente i contatti “before” e “after” vengono chiusi,

dipende il parametro di dinamica di ogni pressione. Ad esempio, ponendo a 0 le linee RD0-RD3 attiviamo il

banco A e possiamo quindi leggere su RB0-RB7 lo stato degli switch ”before” delle prime 8 note della

tastiera; ponendo RD0-RD3 a 8 attiviamo il banco A’ e possiamo quindi leggere su RB0-RB7 lo stato degli

switch “after” delle prime 8 note. Abbiamo visto che “attivare” un banco significa porre la corrispondente

linea a 0 (stiamo quindi usando la logica negativa); ciò è dovuto a come è costruita la matrice di contatti (in

figura) e anche al fatto che in questo modo si possono sfruttare le resistenze di pull-up programmabili

interne della porta RB del PIC.

Figura 11 - costituzione della matrice di contatti della tastiera (semplificata a tre banchi da tre note per chiarezza). I diodi evitano

ritorni di corrente in caso di pressioni contemporanee e fungono inoltre da blande resistenze. Le resistenze di pull-up nel nostro

caso sono interne al microcontrollore.

Figura 12 - suddivisione della tastiera in banchi da 8 note. I banchi A, B, C,... permettono la lettura degli switch "before", mentre

A', B', C', ... permettono la lettura degli switch "after"

Page 7: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 6

L’interfaccia MIDI è costituita da una semplice

resistenza connessa alla porta TX dell USART

integrato nel PIC. Come vedremo, infatti la

trasmissione MIDI è una trasmissione seriale su una

linea in “current-loop” per cui vengono fornite

anche le linee Vcc e Gnd. Lo standard MIDI prevede

l’utilizzo di un optoisolatore, ma esso è a carico del

dispositivo “slave”, e quindi non dobbiamo

preoccuparcene.

Di seguito vengono riportate le pedinature dei connettori utilizzati per collegare la matrice di contatti (e

pochi altri dispositivi) alla scheda del prototipo. Quello a 20 contatti “grigio” era già presente ed è stato

mantenuto non modificato per consentire l’utilizzo della matrice con altri progetti precedentemente

sviluppati: trasporta le linee relative ai banchi A, B, C, D, E, F, G, H e due contatti del pedale del sustain;

quello a 16 contatti “colorato” –collegato ex novo- trasporta le linee dedicate ai banchi A’, B’, C’, D’, E’, F’,

G’, H’ e delle linee dedicate a controller analogici (resistenze variabili) che sono poi collegate alle linee AN

(il convertitore ADC) del PIC.

La resistenza variabile da usare come pitch-bender va

semplicemente collegata con PB al comune, Vcc su uno dei

piedini rimanenti e Gnd sull’altro. Data la natura economica

della tastiera, essa dispone però di una “rotella” per il

controllo del portamento che non si basa su resistenza

variabile ma su una matrice di contatti mostrata in figura. Si è

ovviato collegando i contatti con delle resistenze, in modo da

emulare sommariamente un resistore variabile “a gradoni”, e

smussando poi le letture con un filtro software sul micro.

Figura 13 - interfaccia MIDI.

Figura 14 - connettore a 20 pin,

osservato "da sotto"

Figura 15 - connettore a 16 pin,

osservato "da sotto". PB = Pitch-

Bender

Figura 16 - collegamento della

resistenza variabile del Pitch-

Bender (controllo del

portamento)

Figura 17 - sulla destra la schematizzazione della

PCB della rotella del portamento, sulla sinistra la

rete di resistenze per emulare un resistore

variabile

Page 8: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 7

Il protocollo MIDI

Il protocollo MIDI

rappresenta un ottimo

caso di studio perchè

abbastanza semplice da

essere comunque molto

comprensibile, ma

abbastanza complesso da

non risultare banale.

Inoltre, si tratta di una

comunicazione seriale

asincrona -e in quanto

tale facilmente simulabile.

I dati viaggiano su una linea a bassa tensione con una tecnica chiamata "current loop" per interfacciarsi con

la quale lo standard MIDI prevede l'uso di optoisolatori come il comune 6N138 e l'adozione di un baud-rate

non standard di 31250 (+/- 1%).

La pubblicazione delle prime specifiche risale al 1983, ma

lo standard è sopravvissuto fino ad oggi (e continua ad

imporsi) nonostante le pecche che ovviamente comincia a

dimostrare. Difetti sensibili risiedono sia nella logica del

protocollo, sia nelle specifiche di comunicazione elettrica,

originariamente pensati per comunicare da un singolo

master ad un singolo slave in maniera unidirezionale, poi

adattati a gestire loopbacks e catene di strumenti ed

effetti musicali grazie anche all'introduzione del MIDI-

THRU, una porta che replica in uscita i messaggi arrivati

alla porta MIDI-IN dello stesso strumento. In questo modo

-grazie anche alla suddivisione in canali virtuali di cui

parleremo- ogni strumento osserva l'intero flusso di dati

in ingresso, e filtra da esso quelli che è programmato per

recepire, passando poi i dati ad altri strumenti tramite la

porta THRU. Così facendo, però -non essendo tra l'altro il canale di comunicazione di banda molto larga e

non prevedendo il protocollo un sistema di rilevamento o correzione degli errori- si introducono effetti

indesiderati e latenze, cui si è cercato di ovviare migliorando nel tempo i dispositivi implementanti

Figura 18 - la rotella del controllo portamento disassemblata; la PCB a destra è autoesplicativa: il

trascinamento della rotella provoca la chiusura dei contatti in diversi modi.

Figura 19 - Connessione MIDI - lato ricevitore(slave); la resistenza di protezione

dell'optoisolatore è di 220Ω, mentre quella di pull-up di 1KΩ

Figura 20 - Connessione MIDI - lato trasmettitore

(master); si noti il pin collegato direttamente a Vcc e il

pin centrale (GND) che viene lasciato scollegato per

evitare oscillazioni nel potenziale di massa; entrambe le

resistenze sono da 220Ω

Page 9: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 8

piuttosto che lo standard. Per questi motivi, da sempre gli strumenti MIDI professionali hanno richieste di

latenza molto bassa e capacità di interpretare "elasticamente" il protocollo.

Le informazioni che si possono ricavare da uno stream di comandi MIDI sono organizzate in messaggi, che

sono composti di "opcodes" (o "status bytes") seguiti da dati. Esistono poi degli opcodes particolari

indicanti messaggi di sistema.

Osservando un qualsiasi dato in transito durante una comunicazione, è possibile dire immediatamente di

che tipo si tratta: infatti qualsiasi byte con il bit 7 impostato a '1' rappresenta un opcode, altrimenti -se '0'- i

sette bit meno significativi rappresentano un dato, come il parametro di qualche comando (quindi parlando

di byte di dati, in realtà d'ora in poi intenderemo i 7 bits utili rimasti). Per interpretare correttamente una

comunicazione, quindi, bisogna tener conto del tipo di byte che si sta osservando e dell'evoluzione della

comunicazione. In dettaglio, ecco le tipologie di messaggi:

opcode nome descrizione e numero di bytes di parametri

Sta

tus

by

tes

rela

tiv

i a

d u

n c

an

ale

vir

tua

le

0x80-0x8f note off indica di silenziare una nota; è seguito da due byte di parametri (uno

per la nota, l'altro per l'intensità)

0x90-0x9f note on indica di suonare una nota (o silenziarla se l'intensità è 0)

0xa0-0xaf key pressure "after-touch"; è seguito da due byte di parametri (uno per la nota,

l'altro per la presenza di effetto)

0xb0-0xbf Cc parameter modifica di un parametro continuous controller; è seguito da due byte

(uno per il codice controller, l'altro per la nuova impostazione

parametro)

0xc0-0xcf Program change seleziona uno strumento; è seguito da un byte che indica il codice del

nuovo strumento da adottare

0xd0-0xdf chan. pressure effetto di pressione tasti che interessa l'intero canale (non

perfettamente specificato); è seguito da un byte indicante l'intensità di

effetto

0xe0-0xef pitch wheel indica la posizione assoluta della rotella che sposta finemente il tono; è

seguita da due bytes rappresentanti una parola di 14 bits (i 7 bits meno

significativi per primi)

Sy

ste

m M

ess

ag

es,

al

di

fuo

ri d

ell

a l

og

ica

de

i

can

ali

vir

tua

li

0xf0 system

exclusive

indica l'inizio di un messaggio di sistema seguito da un numero variabile

di bytes di parametri (va terminato con un EOX)

0xf1 undefined

0xf2 song position per i sequencers; indica la nuova posizione in una traccia; seguito da 2

bytes che costituiscono il valore di 14 bits indicante la posizione, i 7

meno significativi per primi

0xf3 song select per i sequencers; indica il codice della nuova traccia; è seguito da un

byte indicante il codice della nuova traccia

0xf4 undefined

0xf5 undefined

0xf6 tune request per i sintetizzatori analogici: indica la richiesta di risintonizzare gli

oscillatori. Non è seguito da alcun dato

0xf7 EOX

(terminator)

indicatore che termina una sequenza di parametri in un messaggio di

sistema a lunghezza variabile; anche altri messaggi come note-on o

note-off possono interrompere una sequenza. Non è seguito da alcun

dato.

Re

alt

ime

Me

ssa

ge

s

0xf8 timing clock usato per sincronizzare le macchine (specialmente le “drum-machines”)

0xf9 undefined

0xfa start per sequencers: indica di iniziare la riproduzione

0xfb continue per sequencers: indica di continuare la riproduzione

0xfc stop per sequencers: indica di fermare la riproduzione

0xfd undefined

0xfe active sensing viene mandato ogni 300 ms circa dal master quando questo non ha

niente da fare (per far capire che è ancora vivo); quando non viene

ricevuto alcun messaggio per più di 300 ms il master è da considerarsi

Page 10: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 9

opcode nome descrizione e numero di bytes di parametri

disconnesso

0xff system reset reset di sistema

alcune precisazioni:

1. vale la regola del "running status byte": una volta che un messaggio viene ricevuto, non occorre

ripetere l'opcode prima di mandare i dati successivi, se questo non cambia (vedere esempi in

seguito)

2. una note-on con intensità posta a 0 è interpretata come un note-off; questo, insieme alla

convenzione del "running status byte" permette di inviare lunghe stringhe di eventi note-on/note-

off rapidamente

3. MIDI prevede la suddivisione in canali virtuali; i messaggi da 0x80 a 0xef sono raggruppati in gruppi

di 16: nel messaggio (nei 4 bits meno significativi) è insito il canale virtuale al quale ci si riferisce; ad

esempio 0x90 significa "note-on sul canale 0", mentre 0x91 vuol dire "note-on sul canale 1" e così

via

4. i messaggi "undefined" vanno semplicemente ignorati

5. gli ultimi 8 messaggi da 0xf8 a 0xff chiamati "realtime messages" (è più in generale i messaggi senza

parametri in coda) così come altri System Messages possono venire inframezzati ad altri comandi

ed è quindi necessario gestirli -in ricezione- anche se non interessa l'informazione veicolata

6. i messaggi "cc parameter" da 0xb0 a 0xbf indicano i valori di eventuali controllers (continui o

discreti) come manopole o sliders che possono venire associati ad effetti: solo il contoller continuo

di codice 0 è standardizzato ed è la cosiddetta "modulation wheel"; tutti gli altri codici di parametro

controller sono proprietari e tendenzialmente diversi da macchina a macchina. I messaggi

parameter possono contenere ulteriori comandi valevoli per l'intero canale al quale si riferiscono

(aggiunti con questo trucco a quelli già esistenti):

codice

controller

Nome secondo byte di parametro

Co

ntr

oll

ers

ve

ri

e p

rop

ri,

sta

nd

ard

o

qu

asi

0x00 Bank select il banco strumenti da selezionare (0 per “General MIDI”)

0x01 Modulation

Wheel

la nuova impostazione di modulazione

0x07 Volume l’intensità di volume da impostare

0x40 Sustain 0 per pedale sustain non premuto, 127 per pedale premuto, indefinito

per qualsiasi altro valore (da ignorare)

Co

ntr

oll

ers

fit

tizi

, u

sati

co

me

com

an

di

ag

giu

nti

vi

0x7a local control 0 = local control off, 0x7f = on

indica ad esempio se una tastiera deve suonare gli eventi locali o quelli

inviati da remoto

0x7b all notes off 0

0x7c omni mode

off

0

0x7d omni mode

on

0

0x7e monophonic

mode

numero di canali monofonici o 0 per indicare un numero pari ai

riceventi

0x7f polyphonic

mode

0

in più, oltre al controller 0x7b, anche quelli da 0x7c a 0x7f silenziano ogni nota.

7. per semplicità di discorso, chiameremo "comandi" gli opcodes riferiti ad un canale (da 0x80 a 0xef),

"System Messages" (o SM) quelli da 0xf0 a 0xff e "dati" tutti gli altri valori

Page 11: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 10

Analizziamo per esempio la seguente sequenza:

0x91 0x40 0x41

• 0x91 significa "Note-on sul canale 1"

• 0x40 = la nota da "accendere" è la numero 64 (il DO centrale delle tastiere)

• 0x41 = la "velocity" (assimilabile con l'intensità con cui suonare la nota)

Vediamo ora un'altra sequenza:

0x91 0x40 0x41 0x4c 0x30 0x40 0x00

• i primi tre bytes hanno lo stesso significato che nel precedente esempio: suonare il DO centrale a

un'intensità media

• il quarto byte è ancora un dato, quindi vale l'ultimo status byte ricevuto, ovvero 0x91; i byte 4 e 5

vogliono quindi dire "suona il DO un'ottava sopra il DO centrale a un'intensità lieve sul canale 1"

• i bytes sei e sette sono ancora dati, quindi vale ancora lo status byte 0x91 (note-on sul canale 1);

l'intensità però stavolta è 0, quindi bisogna interpretare il messaggio come "spegni

immediatamente il DO centrale"

Ed ecco un ultimo esempio di sequenza valida:

0x91 0x40 0xfe 0x41 0x4c 0x30 0xf0 0x01 0x02 0x03 0xf7 0x40 0x00

• La sequenza di eventi relativi ai canali è identica a prima, ma la sequenza è stata inframezzata da

messaggi di sistema (un "realtime message" e un "system exclusive")

• i dati inframezzati alla sequenza originale sono

o 0xfe = realtime message chiamato "active sensing" (qui non ha molto senso, ma serve a

fabbricare l'esempio)

o 0xf0 0x01 0x02 0x03 0xf7 = sequenza "system exclusive" a lunghezza variabile che trasporta

in questo caso il payload 0x01 0x02 0x03 (anche qui i dati inseriti sono a puro titolo

d'esempio)

• Si noti che il realtime message è inserito addirittura tra il primo e il secondo parametro del primo

comando "note-on".

Il software

Si è optato per un loop while infinito, nel quale ad ogni ciclo viene effettuata una lettura completa di tutti i

dispositivi: tutti i banchi di note “before”, tutti i banchi di note “after”, ingressi discreti (pedale) e analogici

(pitch-wheel).

while (1)

{

scanBeforeAndAfter();

readOtherInputs();

sendMIDIMessageAccordingly();

handleActiveSensing();

}

Page 12: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 11

In un sottociclo, una variabile viene incrementata da 0 a 15 e riportata in output sui primi bits della porta

RD; ad ogni sottociclo, sugli otto ingressi di RB si leggono (invertendoli) i bit corrispondenti allo stato delle

otto note del banco selezionato. Tenendo traccia dei vecchi valori è possibile sapere quali switch sono

appena stati premuti o rilasciati:

void scanBeforeAndAfter()

{

for (i = 0; I < 16; ++i )

{

oldData[i] =newData[i]; // each bit contains on/off status of a switch;

newData[i] = ~PORTB; // 1 byte = 1 bank = 8 switches

justPressed[i] = ~ oldData[i] & newData[i];

justReleased[i] = oldData[i] & ~ newData[i];

}

}

L’algoritmo per il rilevamento della dinamica è semplice: vi sono 64 possibili note, e di conseguenza 64

misure dei tempi tra “before” e “after”; dunque sono allocati nella ram interna 64 bytes ognuno dei quali

memorizza il valore della velocity della nota corrispondente. Ogni valore di velocity viene inizializzato a 127

(massima velocity nello standard MIDI). Ad ogni ciclo, se lo switch “before” di una nota risulta chiuso, allora

decrementiamo la corrispondente velocity; se lo switch “after” è appena stato premuto, allora procediamo

a spedire un messaggio MIDI di note-on in cui la velocity è quella memorizzata; se lo switch “before” è

appena stato rilasciato, provvediamo a fabbricare e inviare un messaggio MIDI note-off e resettiamo la

corrispondente velocity a 127.

for (i = 0; i < 64; ++i)

{

if (pressedBefore[i]) // for sake of simplicity here we omit the code that translates index

--velocity[i]; // from bit mask to linear array

If (justPressedAfter[i])

sendNoteOn(i, velocity[i]);

if (justReleasedBefore[i])

{

sendNoteOff(i);

velocity[i] = 127;

}

}

Il precedentemente menzionato algoritmo di smussamento dei valori del pitch-bender viene implementato

come un controllore PID elementare in cui la parte integrativa sia posta a 0.

filteredValue = filteredValue + (value - filteredValue)*k, 0<k<1 (in questi casi solitamente piccolo)

Page 13: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 12

Ovviamente per evitare fenomeni di accumulo dell’errore e aliasing sarebbe necessario usare dei numeri

reali; inoltre è necessario adattare le diverse dimensioni in bit: si è deciso di implementare questa funzione

con la tecnica fixed-point. L’ADC del PIC fornisce un numero intero non segnato a 10 bits, mentre il

protocollo MIDI richiede per il parametro del pitch-bender un numero intero non segnato a 14 bits,

entrambi ovviamente gestiti poi con interi non segnati a 16 bits che lasciano quindi spazio ad almeno 2 bits

per la parte frazionaria.

La lettura dello stato del pedale viene effettuata direttamente su uno degli ingressi digitali della porta C del

PIC (attualmente senza multiplazione): un meccanismo logico permette di gestire pedali dai contatti sia

normalmente aperti che normalmente chiusi (una lettura effettuata allo start-up prima di entrare nel ciclo

principale stabilisce la norma)

Come spiegato in precedenza, parte dei meccanismi del protocollo MIDI sono dedicati alla minimizzazione

del traffico di dati. La già descritta convenzione del “running status byte” prevede di evitare di reinviare due

comandi uguali che siano inframezzati solo da dati. A questo proposito, si è adottato un semplice

meccanismo che ricorda l’ultimo status byte inviato:

void sendCommand(cmd)

{

if (lastSB != cmd)

{

lastSB = cmd;

send(cmd);

}

activeSensingTimeout = 0

}

Nell’ultima riga si può notare l’azzeramento di una variabile che (contando semplicemente il numero di

cicli) permette di stabilire se è il caso o meno di inviare un “active-sense”, utile a segnalare la presenza e il

funzionamento del dispositivo quando non ci sono altri comandi da inviare per un certo tempo. Come

ultima operazione del nostro ciclo principale, infatti abbiamo:

++ activesensingTimeout;

if (activeSensingTimeout>300)

{

activesensingTimeout = 0;

send(activeSensingToken);

}

Page 14: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 13

Conclusioni e possibili sviluppi

Collegando il dispositivo a degli analizzatori di protocollo MIDI (come per esempio un semplice terminale

che supporti il baudrate MIDI, o il progetto “FPGA_MIDI” sviluppato per il corso di elettronica II su board

Altera) si è proceduto a verificare che i messaggi vengono inviati correttamente.

Il dispositivo si comporta bene anche nelle prove pratiche, nelle quali si procede semplicemente a suonare

la tastiera e a far attenzione alle eventuali inesattezze di riproduzione del suono, come ritardi o veri e

propri errori. Per completare tale prova si è provveduto a collegare il circuito alla porta MIDI standard di un

PC (nel nostro caso tramite una scheda sonora Creative Sound Blaster Audigy Platinum) e ad eseguire un

semplice programma che traduca messaggi MIDI in suoni. Le latenze non sono avvertibili anche in casi

critici per il protocollo, come quello di molte pressioni simultanee e la risposta appare immediata,

dimostrando la semi-professionalità del dispositivo costruito; nonostante ciò, la pulsione al miglioramento

ci suggerisce eventuali modifiche apportabili al progetto. Una delle prime migliorie possibili sarebbe quella

di aumentare la velocità con la quale le scansioni si succedono: una prima idea potrebbe essere –date le

attuali ridotte dimensioni del codice eseguibile- quella di usare la tecnica dei loops “srotolati”. Il PIC 18F452

riesce a sostenere clock fino a 40 MHz, che sarebbe il doppio di quello attualmente in uso: ciò

permetterebbe di ravvicinare ulteriormente tra loro le scansioni e quindi migliorare la risposta della

dinamica. A tal proposito, la risposta dinamica del circuito è attualmente lineare, mentre è facile intuire che

allo scopo di simulare la forza di pressione, la velocity andrebbe distorta prima dell’invio, tramite -ad

esempio- una look-up table. La rotella del portamento andrebbe modificata in modo da azionare

direttamente un potenziometro, permettendo così di eliminare dal software il filtro, che è abbastanza time-

consuming. Al circuito andrebbero aggiunti pochi componenti passivi come resistenze limitatrici e un

condensatore di anti-bounce al fine di ridurre i –già minimi- consumi e garantire l’affidabilità. L’unico errore

non gestito del dispositivo, al momento, riguarda l’operatività in condizioni di alimentazione insufficiente

(es: batteria scarica): invece di smettere semplicemente di funzionare, il circuito comincia a commettere

errori di scansione, inviando messaggi pseudo-casuali. La cosa è eventualmente ovviabile con un minimo di

circuiteria esterna. Un ultima raffinatezza potrebbe essere quella di misurare la dimensione -in numero di

istruzioni- di ogni blocco condizionale, in modo da riempire di un numero adeguato di NOP uno dei due

rami di ogni istruzione condizionale, per fare in modo da avere cicli di tempo di esecuzione sempre

esattamente identico a se stesso (adesso sono presenti minime oscillazioni). Lo sviluppo di una board

dedicata permetterebbe di effettuare tests più seri ed eventualmente portare ad una produzione su medio-

piccola scala.

NB: progetti, schemi, immagini, foto, informazioni e codici sorgenti di Giancarlo Todone vengono rilasciati

con licenza Apache 2.0, a parte le informazioni sul protocollo MIDI 1.1 dedotte dall’ottimo documento “The

Usenet MIDI Primer” di Bob McQueer, facilmente reperibile in rete.

Page 15: Pic MIDI Documentation

Giancarlo Todone - Progetto e realizzazione di un controller master MIDI Pagina 14