deletemeplease Posted January 30, 2011 Report Share Posted January 30, 2011 (edited) Hi. I'm trying to plan out my controller in my head and figure out the code as I go along. Below are my two questions, skip to the end of the post if you need more info about my project. Question 1) I need to send a program change message, value 12. Which of the following is correct? MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Program Change, Channel #1 MIOS_MIDI_TxBufferPut(0x12); // Program Number 12 MIOS_MIDI_EndStream(); OR MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Program Change, Channel #1 MIOS_MIDI_TxBufferPut(0x0C); // Program Number 12 MIOS_MIDI_EndStream(); I'm pretty sure its the second, but I thought I'd check. Question 2) I have 6 buttons, I want 4 of them to send program changes, and the other two are more complex so lets tackle the first four first. How do I set these up in the ain64_din128_dout128_v2c example? Can I create an array like the following. Please forgive my syntax, I only know a little objective-c, so I realise the syntax is probably massively wrong: static unsigned char switches[4] = { 0x00, 0x06, 0x0C, 0x12 }; And use MIOS_DIN_PinGet to say - "Pin 2 was pressed, select location 2 from the array". Then is it possible to store this hex result as a variable which i can use in a MIDI stream request? More information about my project It's a simple MIDI box. 1x core, with PIC18F452, 1x DINx1, 1x DOUTx1. 6x buttons, 6x LEDs. The first 4 buttons send different program change messages, the last two buttons send CC#. On first press they send value 127, on second press they are toggled to value 00. I'm quickly realising I'm in way over my head, but everyone has to start somewhere right? Edited January 30, 2011 by Pulsewidth947 Quote Link to comment Share on other sites More sharing options...
nILS Posted January 30, 2011 Report Share Posted January 30, 2011 MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Program Change, Channel #1 MIOS_MIDI_TxBufferPut(0x12); // Program Number 12 MIOS_MIDI_EndStream(); [/code] That's 18 (1 * 16^1 + 2 * 16^0). You know, you can just use decimal numbers as well ;) [code] MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Program Change, Channel #1 MIOS_MIDI_TxBufferPut(12); // Program Number 12 MIOS_MIDI_EndStream(); Question 2: You can do that. When a button gets pressed MIOS calls DIN_NotifyToggle and passes the pin state and number. const unsigned char pc[4] = {0, 6, 12, 18}; void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) { if (pin_value) return; // ignore button up if (pin < 4) sendProgramChange(pc[pin]); else // other buttons }[/code] sendProgramChange would be a function that does the stuff at the start of the post. Doing it this way, you introduce a pretty static connection between hard and software though. I usually use defines to map pins to button names. That allows changing pins/functions on the fly. [code] #define BUTTON_PC0 0 #define BUTTON_PC6 1 #define BUTTON_PC12 2 #define BUTTON_PC18 3 void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) { if (pin_value) return; // ignore button up switch (pin) { case BUTTON_PC0: sendProgramChange(0); break; case BUTTON_PC6: sendProgramChange(6); break; // and so on } } Also, if you only need a total of 12 IOs you can easily use pic pins instead of DIN/DOUT modules. J5 for instance offers you 8 pins and if you don't have any other modules attached you can basically use any free pin. Quote Link to comment Share on other sites More sharing options...
lylehaze Posted January 31, 2011 Report Share Posted January 31, 2011 Good stuff, but I'll offer two thoughts on this: I lean more to assembler than C, but as a rule I find that assuming what the default base might be is dangerous. 0x0C will always be evaluated as the same value, but I know in ASM at least, the "default" base can be changed, and so the value of "12" might NOT always give the same value. In MPASM you can specify a value as decimal by putting a period in front of it, so ".12" will ALWAYS be the same, no matter what the default base is. I understand that you're playing in "C", but it might be worthwhile to look up how to declare a decimal base with each number to prevent it EVER being read the wrong way, by yourself or the next guy. Oh, and the other thing, either ".12" or "0x0C" will give you patch 13, not patch 12, assuming your patches are numbered starting from 1. (That 1 can be in binary, octal, decimal, or hex) Have a great day, LyleHaze:cool: Quote Link to comment Share on other sites More sharing options...
deletemeplease Posted January 31, 2011 Author Report Share Posted January 31, 2011 I can't believe I didn't think of using decimal. I always try and overcomplicate things lol. I usually use defines to map pins to button names. That allows changing pins/functions on the fly. I like the layout of this define and switch. It's very clean and straight forward. I think this is the way to go. I'm a little unclear about sending parameters to a function. Would the following work? void sendProgramChange(unsigned char sendProgramChange) { MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Program Change, Channel #1 MIOS_MIDI_TxBufferPut(sendProgramChange); // Program Number 12 MIOS_MIDI_EndStream(); } Or do I need to ensure that my unsigned char is different from the function name? I presume it's correct to do this as a void, as I don't particularly need any code output? Also, if you only need a total of 12 IOs you can easily use pic pins instead of DIN/DOUT modules. J5 for instance offers you 8 pins and if you don't have any other modules attached you can basically use any free pin. Oh really? Thats very interesting indeed. I'd rather get away from using din/dout boards to save space. Is this difficult to code? Any functions I should be looking into? Knowing what I'm looking for might make it easier to search the forum. Oh, and the other thing, either ".12" or "0x0C" will give you patch 13, not patch 12, assuming your patches are numbered starting from 1. (That 1 can be in binary, octal, decimal, or hex) Thats a good point. The manufacturer of the box I'm trying to control states that the first scene is in fact patch 0, so I think I'm ok. Shouldn't be difficult to test. So you would actually recommend using the value as hex in my case? Quote Link to comment Share on other sites More sharing options...
nILS Posted January 31, 2011 Report Share Posted January 31, 2011 Your function will work this way, as "sendProgramChange()" is sth different than "sendProgramChange". I typically prefer naming the parameters differently though. Doesn't seem to make a lot of sense to me to call the parameter "sendProgramChange". I'd go with just "program" as this describes best what the parameter is - the desired program. Is this difficult to code? Any functions I should be looking into? No. It's a bit more code than using all the premade stuff of course ;) I would suggest using J5 for the inputs - there's a neat driver already written for just that purpose. Look in mios\modules\j5_io there's a readme that explains the usage. I'd suggest using that for the inputs as it handles the debouncing etc iirc. That leaves you with having to find 6 unused pins for the LEDs. Since you are not using an LCD, I'd simply suggest using PortB for that - 8 pins, all physically adjacent, too. To set up PortB as an output port, you'll need to write 0x00 into the TRISB register (each bit corresponds to one pin, 0 = output, 1 = input). From that point on you can write to PortB using either PORTB directly, overwriting all 8 pins at once or the PORTBBits struct to write individual pins easily. Here's a quick example: void Init(void) __wparam { TRISB = 0x00; // set Port B as output PORTB = 0x00; // turn off all LEDs // some doodling with the pins PORTB = 0x0A // 0x0A = 10d = 00001010b which means the 2nd and 4th pin are set high (LED on) PORTBBits.RB0 = 1; // set 1st pin high PORTBBits.RB7 = 0; // set 8th pin low PORTBBits.RB3 = 1; // set 4th pin high PORTBBits.RB2 = 0; // set 3rd pin low }[/code] I am not at home atm, and I have no way of testing the code I write, so don't expect it to work, this is from the top of my head, so for instance the capitalization of PORTBBits might be wrong :) Quote Link to comment Share on other sites More sharing options...
deletemeplease Posted January 31, 2011 Author Report Share Posted January 31, 2011 Your function will work this way, as "sendProgramChange()" is sth different than "sendProgramChange". I typically prefer naming the parameters differently though. Doesn't seem to make a lot of sense to me to call the parameter "sendProgramChange". I'd go with just "program" as this describes best what the parameter is - the desired program. Yes that makes perfect sense. Thank you. Look in mios\modules\j5_io there's a readme that explains the usage. I'd suggest using that for the inputs as it handles the debouncing etc iirc. OK I'll give it a shot. I've read the readme, and don't really understand the implementation, but I think I should be able to search for that just fine. My switches have just arrived so I think it's testing time! That leaves you with having to find 6 unused pins for the LEDs. Since you are not using an LCD, I'd simply suggest using PortB for that - 8 pins, all physically adjacent, too. Great stuff. I'll work on the switches first as the LCD is probably helpful for that. Thanks again :) Quote Link to comment Share on other sites More sharing options...
nILS Posted January 31, 2011 Report Share Posted January 31, 2011 If at any point you need real-time support for some coding issues it might be quicker to drop by the chat - just saying ;) Quote Link to comment Share on other sites More sharing options...
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.