RobG 1,892 Posted May 11, 2011 Share Posted May 11, 2011 As part of my other project, I had to create a simple MIDI receiver. I figured that instead of polluting my other thread, I will create a new one, dedicated to my MIDI adventures. Here is my first MIDI receiver. It displays message type (note on, note off, after touch, control change, program change, channel pressure, pitch wheel,) MIDI channel, note number, and the velocity. Because of the time it takes to update LCD, I am not updating headers so "Note" and "Vel" are not accurate descriptions of the data received for some type of messages. I will make some improvements later, like changing the clock to 8MHz because current 1MHz seems to be too slow. EDIT: code below runs at 8MHz, still some problems, will have to rewrite it completely. Code removed, new version below bluehash and nexusone1984 2 Quote Link to post Share on other sites
NatureTM 100 Posted May 12, 2011 Share Posted May 12, 2011 MIDI is *so* last month Quote Link to post Share on other sites
nexusone1984 32 Posted May 12, 2011 Share Posted May 12, 2011 The sounds of Silence.... Future project....I seen someone else do this on Arduino. Make a midi device.... fires solenoids at plates of a xylophone to make music. maybe a real drum, etc... make a micro controlled band. Quote Link to post Share on other sites
RobG 1,892 Posted May 13, 2011 Author Share Posted May 13, 2011 Nature, you know what they say: it's not when you use it, it's how you use it I wasn't happy with my first version so I rewrote it and here it is, all new and improved. No more missed messages, headers are correct for the type of message, didn't bother to convert pitch bend values though. Still no SysEx but I think I will leave it at that. #include "msp430g2553.h" void send(char data, char registerSelect); void sendHeader(const char* header); void setLCDData(char startIndex, char data); void clearData(char startIndex); #define sendData(data) send(data, 1) #define sendFunction(data) send(data, 0) #define DATA_PIN BIT6 #define CLOCK_PIN BIT5 #define ENABLE_PIN BIT4 #define MIDI_IN_PIN BIT1 char charIndex = 0; char bitCounter = 0; char digitCounter = 0; char rxData = 0; char rxByte = 1; char channel = 0; char status = 0; char lastStatus = 0; char lcdData[16] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; const char headerAddr = 0x87; const char dataAddr = 0xC0; const char initSequence[4] = { 0x3C,0x0C,0x01,0x06 }; const char charMap[10] = { 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 }; const char mainHeader[6] = { 0x4D,0x73,0x67,0x20,0x43,0x68 }; const char noteHeader[9] = { 0x4E,0x6F,0x74,0x65,0x20,0x56,0x65,0x6C,0x20 }; const char ctrlHeader[9] = { 0x43,0x6F,0x6E,0x74,0x20,0x56,0x61,0x6C,0x20 }; const char progHeader[9] = { 0x50,0x72,0x6F,0x67,0x20,0x20,0x20,0x20,0x20 }; const char presHeader[9] = { 0x50,0x72,0x65,0x73,0x20,0x20,0x20,0x20,0x20 }; const char pitchHeader[9] = { 0x4D,0x53,0x42,0x20,0x20,0x4C,0x53,0x42,0x20 }; const char msg[7][3] = { { 0x4F,0x46,0x46 } ,{ 0x20,0x4F,0x4E}, { 0x41,0x46,0x54}, { 0x43,0x43,0x48}, { 0x50,0x43,0x48}, { 0x43,0x48,0x50}, { 0x50,0x57,0x48} }; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_8MHZ; DCOCTL = CALDCO_8MHZ; _delay_cycles(100000); P1OUT &= ~(CLOCK_PIN + DATA_PIN); P1OUT |= ENABLE_PIN; P1DIR |= ENABLE_PIN + CLOCK_PIN + DATA_PIN; P1SEL = MIDI_IN_PIN; P1SEL2 = MIDI_IN_PIN; UCA0CTL1 |= UCSSEL_2; UCA0BR0 = 0x00; UCA0BR1 = 0x01; UCA0CTL1 &= ~UCSWRST; IE2 |= UCA0RXIE; while(charIndex < 4) { sendFunction(initSequence[charIndex]); charIndex++; _delay_cycles(16000); } charIndex = 0; while(charIndex < 6) { sendData(mainHeader[charIndex]); charIndex++; } __bis_SR_register(GIE); while(1) { if(lastStatus != status) { sendFunction(headerAddr); if(status == 3) { sendHeader(ctrlHeader); } else if(status == 4) { sendHeader(progHeader); } else if(status == 5) { sendHeader(presHeader); } else if(status == 6) { sendHeader(pitchHeader); } else { sendHeader(noteHeader); } lastStatus = status; } sendFunction(dataAddr); digitCounter = 0; while(digitCounter < 16) { sendData(lcdData[digitCounter]); digitCounter++; } } } #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { rxData = UCA0RXBUF; if(rxData & BIT7) { if(rxData < 0xF0) { status = (rxData >> 4) - 8; channel = (rxData & 0x0F) + 1; lcdData[0] = msg[status][0]; lcdData[1] = msg[status][1]; lcdData[2] = msg[status][2]; setLCDData(3, channel); } return; } else { if(rxByte == 1) { rxByte = 2; if(status == 4 || status == 5) { clearData(12); rxByte = 1; } else if (status == 6) { setLCDData(12, rxData); return; } setLCDData(8, rxData); } else { rxByte = 1; if(status == 6) { setLCDData(8, rxData); return; } setLCDData(12, rxData); } } } void clearData(char startIndex) { lcdData[startIndex] = 0x20; lcdData[startIndex + 1] = 0x20; lcdData[startIndex + 2] = 0x20; } void sendHeader(const char* header) { char hdrIndex = 0; while(hdrIndex < 9) { sendData(header[hdrIndex]); hdrIndex++; } } void setLCDData(char startIndex, char data) { // int to BCD clearData(startIndex); charIndex = startIndex + 2; lcdData[charIndex] = 0x30; while(data > 0) { lcdData[charIndex] = charMap[data % 10]; data /= 10; charIndex--; } } void send(char data, char registerSelect) { bitCounter = 0; while(bitCounter < 8) { (data & BIT7) ? (P1OUT |= DATA_PIN) : (P1OUT &= ~DATA_PIN); data <<= 1; P1OUT |= CLOCK_PIN; P1OUT &= ~CLOCK_PIN; bitCounter++; } registerSelect ? (P1OUT |= DATA_PIN) : (P1OUT &= ~DATA_PIN); P1OUT &= ~ENABLE_PIN; P1OUT |= ENABLE_PIN; } NatureTM 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.