julienvoirin Posted August 7, 2007 Report Share Posted August 7, 2007 Here is a completly amazing control surface for your favorite sequencer or synthesizer :It's a machine capable of playing Notes, Control Change and Program ChangesPhotos are available at http://www.midibox.org/forum/index.php?topic=9655.0Here is how it is made :The machine is composed by 3 things :1 - A 64 buttons keyboard, design of TK with the scan matrixhttp://www.ucapps.de/mbhp/mbhp_scan_matrix1.pdf2 - A control surface with 4 buttons, one jack for a footswitch and one clickable encoder and several LEDs3 - Classic stuff from ucapps : 1 core (pic 18f452), 1DINX2, 1 DOUTX2, midi and supply connector, and things removed from the trash.How to connect it : Connect DINX2 and DOUTX2 at the core, ports J8 and J9.Connect the Scan Matrix to the first Shift Register (SR1) of DIN & DOUTConnect the encoder to pin 0&1 of SR2, the Clic at pin2 (on the 2nd DIN)Connect the Jack at pin4 of SR2 (on the 2nd DIN)Connect Button A,B,C,D at respectively pins 5, 6, 7, 8 of the 2nd DIN. Don't forget the ground !!Connect the LEDs to the SR of the 2nd DOUT :4 green leds to pin 0 1 2 31 red led to pin 41 yellow led to pin 5a tricolor led to pins 6 & 7 (red/green/yellow fluo)Connect a light to the supplyConnect a light to pin J14 of the core.How it works : Button A = Note mode, and midi channel choosing ; indicated by the 4 green leds. Coding hard to understand (a bit llke BinaryCodedDecimal, but different)Button B = Program Change Mode ; indicated by red ledButton C : Control change mode ; indicated by yellow ledButton D : switch between the layers : A, B or CRq : Layer is a manner to have 128 virtual buttons with only 64 real ones.Layer A corresponds to buttons 0 to 63 (led red fluo), layer B corresponds to buttons 64 to 127(led green fluo)and layer C is a mix of A & B, buttons 32 to 96 (led yellow fluo).You choose which mode you want by pressing the corresponding button. WARNING : The midi channel is selected by the note mode button. For example I want to play a note c-1 at channel 4 :Start the device. I press 4 times on buttonA, that means I am in midi channel 4, it is indicated by the 4th leds highlighted. Then I choose the layer : it will be layer A because we are looking for the first note in MIDI (note 00). the layer LED must be red fluo. If it's not, press several time on buttonD until LED become red fluo.Then play on the Keyboard the 1st button (up left corner).the velocity is given by the encoder : turn clockwise to increase, anticlockwise to decrease, or press the click to get the maximum velocity. By default at start up the velocity is 100 (0x64).For example i want to send a program change message : 52Press buttonB, choose layer A, then press the 52th button of the keyboard ! or choose layer C and press the 20th button of the keyboard. (32+20=52)This manner is easy to command a drummachine which has its patterns defined by PC message (ex : Machinedrum, MPC, Jomox, etc). The midi channel is always defined by buttonA. That means that you have to pass by Note mode to change the channel. To choose the channel you push the button A and the channel increase ; when it reaches 16, it then fall back to channel 1. Leds show the corresponding midi channel, but coding 16 values with only 4 LEDs is a bit like speaking with an Alien : complicated.Now I want to modulate Control change 13 at channel5 :Choose channel 5 by pressing buttonA until the leds indicate that you are in channel 5 (look in main.c it is explained)then switch to CC mode by pressing buttonCThen choose CC13 by pressing the 13th button of the keyboard.then modulate with the encoder !!Press the footswitch (connected to the jack) to start your favorite sequencer.Whatever the mode be, the light connected to pin J14 of the core is highlighted when you send a midi message.Have fun and send me feedback if you like it !!In several months a special sequencer will maybe exist, based on this design with an additionnal Display. Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted August 7, 2007 Author Report Share Posted August 7, 2007 And the Firmware I had forgotten !!8x8 KBD LED Enc v1.1.rar8x8 KBD LED Enc v1.1.rar Quote Link to comment Share on other sites More sharing options...
Rio Posted August 7, 2007 Report Share Posted August 7, 2007 Nice ;) Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted August 9, 2007 Author Report Share Posted August 9, 2007 some inner photos ... to understand8x8KBD Led Photos.zip8x8KBD Led Photos.zip Quote Link to comment Share on other sites More sharing options...
ilmenator Posted August 9, 2007 Report Share Posted August 9, 2007 Sorry, most of the close-ups are rather blurry so it's hard to see...ilmenator Quote Link to comment Share on other sites More sharing options...
/tilted/ Posted September 29, 2007 Report Share Posted September 29, 2007 What is that case?It is sweet.It looks like maybe a C64 diskdrive case? Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted September 30, 2007 Author Report Share Posted September 30, 2007 I don't know ! I ve found 8 of them in a trash ; seems to be interphones. As my friend told I was making "Voirinof" (notice the russian accent), it was the perfect case for (70's Eastern Europe style). Buttons where included, and 1x DIN5P too ; that is why I recycled. Practical and cheap (15€ bargain each time, used for SID too). Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted October 3, 2007 Author Report Share Posted October 3, 2007 i learned how to write 'OR' in C so I added support for indicating MIDI channel while in Program or CC mode. Two months I was waiting for this and it is the website of Arduino which learn it to me (nice free project this arduino !). Learned also && and !. Yeah. Still not understood how to make boolean var.also edited the readme.txt and added a changelog into.schematic not planned except if at least 3 midiboxers want to build it. Contact me. By default i can produce a map indicating the pins to connect :J9 Core >> J1 DINX2 ... D0 SR1 DIN >> scan matrix etc ...But ask if you want it. No job for nothing8x8 KBD LED Enc v1.2.rar8x8 KBD LED Enc v1.2.rar8x8 KBD LED Enc v1.2.rar8x8 KBD LED Enc v1.2.rar Quote Link to comment Share on other sites More sharing options...
Narwhal Posted October 3, 2007 Report Share Posted October 3, 2007 It sounds like you know C even better than you may be aware of. You don't need to make a boolean variable. What you are doing with &&, ||, and ! are boolean comparisons. These boolean comparisons can be done with any type of variable (int, float, byte, char, long, pointers). So yeah.. you are in good shape with the boolean comparisons. Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted October 3, 2007 Author Report Share Posted October 3, 2007 thanks for your explanations, but here is what i would like to do (maybe you can help me) : i have a bool var : StateX. It can be 0 or 1 (true, false)i have another var : StateY. 0 or 1StateX is attached to ButtonA. When buttonA is pressed, StateX change from 0 to 1 or 1 to 0 (depending of the previous state). I have made a compromiss, using ++ and another condition sooner in the program : If StateX >2 ,then StateX=0.And sometimes, during the use of the Voirinof, i have queries : "is StateX in 0 or 1 ?" then do somethingAnd also "if StateX is false and StateY is true then ..."Any help welcome. I don't know how to declare this, especially the "grammar" to use.I noticed, studying clockbox, that thorsten uses State_t stuff. I tried the same but unsuccessful (i looked in the forum and the wiki), lots of error while compiling with the linker (i use PSPAd to code, no knowledge on IDE - i am a selfmade man)I am also looking for a manner to isolate the "A" of 0x9A and put it in a integer in order to read it and display the midi channel. For the moment, i am using a sort of table with || (similar to an array), listing all the possibilities.Ahh ! Arrays !, another thing i don't manage.Cheers Quote Link to comment Share on other sites More sharing options...
Narwhal Posted October 3, 2007 Report Share Posted October 3, 2007 lots of questions there.A lot of confusion can arise here over boolean operations because C++ added some new functionality that may or may not be implemented in the later C compiler we are using for the microcontrollers. I'm not 100% sure what's implemented in the compiler you are using.I use microsoft C++ every day and I can do the following to alternate the state of a variable that is being treated like a boolean:char StateX = 0;StateX = !StateX;this works like the following psedocode:if StateX is false then set StateX to be equal to trueelse set StateX to be equal to falseI don't want to crack your brain while your doing so well with the booleans, but there are also bitwise operators that you can use. That will result in all of the bits of your variable alternating states:char StateX = 0;StateX = ~StateX;pseudocode for this:if StateX == 0x00 then set StateX to 0xffelse set StateX to 0x00;I'll have to dig into the code to see what you mean by the State_t stuff. I assume that is some type that Thorsten uses for states. Unfortunately I'm too busy to do that at the moment, so maybe someone else can comment more on that.- Isolating the A of 0x9a:char data = 0x9a;char midichannel = (data & 0x0f)after this, midichannel will be equal to 0x0a. if data were set to another value, say 0x99, then data would be equal to 0x09. The & 0x0f part is a bitwise AND operation. Because 0x0f has the right side 4 bits set to 1, you are essentially extracting the rightmost 4 bits of the data variable.Hope that helps. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted October 3, 2007 Report Share Posted October 3, 2007 StateX = !StateX; Is a comparator (a logical NOT) and might not work quite the way you're thinking. That's more for stuff like: If (StateX != foo) then bar(); It's logical as in true/false. You might want an operator (a bitwise NOT, aka, one's complement) like this: StateX = ~StateX;Which inverts the bits of the variable given.http://www.phim.unibe.ch/comp_doc/c_manual/C/CONCEPT/expressions.html Good summary. Check out the rest of the site.http://www.midibox.org/forum/index.php?topic=6981.msg45080#msg45080 Nibbles thread of goodness. Check this out for grabbing one nibble of a byte (EG 0x94 broken into 0x90 or 0x04). I updated the cheat sheets tonight. Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted October 3, 2007 Author Report Share Posted October 3, 2007 thanks a lot guys ! i will try it.stryd, you are a teacher, aren't you ?and what is "typedef union" often used by TK ? and how to use it ? Quote Link to comment Share on other sites More sharing options...
stryd_one Posted October 3, 2007 Report Share Posted October 3, 2007 typedef and union are actually two separate things, but TK is using them together. I'm guessing that you're looking at a bitfield. Here's an example, I'll break it down.First we have typedef. It's used to define a variable type. You'll already know about types like 'unsigned char' which is 8bit, or 'signed int' which is 16b. Typedef allows you to create your own customised types.You can do typedef char MyType_t; Which creates a type named MyType_t, and makes it a char (which will be unsigned by default). Now, you can create as many variables as you need, using this type: unsigned char Example; unsigned char Example1; int Example2; MyType_t MyVar; MyType_t MyVar1; MyType_t Foo; Now your type can be just about anything you specify. For example we could create a struct: struct MyStruct { unsigned char Foo; unsigned char Foo1; unsigned int Bah; unsigned int Black; unsigned char Sheep; }; What this makes is a set of variables which you access like so: MyStruct.Foo = 0x69; MyStruct.Sheep = 0; Now, you can also create bitfields with the struct keyword, by specifying the member name and how many bits it should have assigned to it: struct MyStatus { unsigned RUN:1; unsigned PAUSE:1; unsigned START_REQ:1; unsigned STOP_REQ:1; unsigned CONT_REQ:1; }; This creates a struct called MyStatus which is 5 bits in size, with one bit assigned to each member. So: MyStatus.RUN = 1; Sets a one-bit 'flag' that your app can use to tell if the Status is running. You can combine this with the typedef like so: typedef struct { unsigned RUN:1; unsigned PAUSE:1; unsigned START_REQ:1; unsigned STOP_REQ:1; unsigned CONT_REQ:1; } MyStatus_t; This creates a type called MyStatus_t, which you can then use to declare several variables as the same 5-bit bitfield: MyStatus_t Status1; MyStatus_t Status2; So now, you have for example: Status1.RUN = 1; Status2.RUN = 0; Status2.START_REQ = 1; etc etc... Now, onto union... union instructs the compiler (SDCC) to assign the same memory address to two different variables. A simple example is: union { unsigned char foo; unsigned char bah; } Example_u Now if the two unsigned chars, foo and bah, share the same physical memory. That means that whatever you write to one, you also write to the other, so if you do: Example_U = 0x10; return bah; Then this function will return the value of bah, which is 0x10. If the above declaration of the MyStatus type looked like this: typedef union { struct { unsigned ALL:5; } struct { unsigned RUN:1; unsigned PAUSE:1; unsigned START_REQ:1; unsigned STOP_REQ:1; unsigned CONT_REQ:1; } } MyStatus_t Now we have created a type, which is a union, of two 5-bit bitfields. In order to make sure that the data is properly asigned with the 8-bit memory, it's best to make it 8-bit, so we do this: // status of midi clock typedef union { struct { unsigned ALL:8; }; struct { unsigned RUN:1; unsigned PAUSE:1; unsigned START_REQ:1; unsigned STOP_REQ:1; unsigned CONT_REQ:1; }; } mclock_state_t; (Look familiar?) ;) Notice that the 'ALL' member is now 8 bits wide. It is in a union with the 5-bit bitfield, so three bits are unused by the bitfield but still accessible by the ALL union member. Once this type is defined, then you use the type to declare the variable: mclock_state_t mclock_state; You could use this type as many times as you need: mclock_state_t mclock1_state; mclock_state_t mclock2_state; mclock_state_t Some_Other_state; Now, it is possible to address the individual flags like so: mclock_state.RUN = 1; Or you can access them all by making use of the union. For example, you can clear all the flags when you initialise the clock: mclock_state.ALL = 0; How's your head? It's 0130 here, I'm out!PS Maybe this thread could be split off into the C programming forum?Edit: BITFIELDS!! (sorry, it's an in-joke between me and another forum member. couldn't help it) Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted October 3, 2007 Author Report Share Posted October 3, 2007 thanks stryd! don't understand everything but will try. Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted December 3, 2007 Author Report Share Posted December 3, 2007 Hello guysi've really improved the voirinov : now it has a display ! which shows what note, CC or program you send.I am totally re-designing it to integrate a sequencer. This will be v2.Have fun !8x8 KBD LED Enc v1.4.zip8x8 KBD LED Enc v1.4.zip Quote Link to comment Share on other sites More sharing options...
stryd_one Posted December 15, 2007 Report Share Posted December 15, 2007 Pics! Pics!! Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted December 17, 2007 Author Report Share Posted December 17, 2007 ok ok pics & colegram : (i had no more battery on photo device so rather bad shoots)as you can see, it indicates if it is note, cc or program change mode.a function also print on the left of the lcd incoming midi message (software feedback idea)find some videos at : http://4colors.free.fr/midibox/demos/voirinof/voirinof%20mini%20demo.movsome "chop chop" (like on MPC, each 1 of the 8 buttons is assigned to a sample, this sample is creating further by the slicing of a loop) with ableton, using midi learn (cmd+M) :http://4colors.free.fr/midibox/demos/voirinof/chopchop_voirinof.movGuys having a monome can do the same thing without max/msp patches ... Quote Link to comment Share on other sites More sharing options...
nILS Posted December 17, 2007 Report Share Posted December 17, 2007 Pictures? My computer no likey .mov... An I don't like installing QuickTime ;D Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted December 17, 2007 Author Report Share Posted December 17, 2007 1 picture : DSCI0030.JPG Quote Link to comment Share on other sites More sharing options...
revoltingrobots Posted June 2, 2011 Report Share Posted June 2, 2011 huh, great. that box is almost completely the thing i am looking for, because it can control other synths and samplers, with look and feel of ableton live. and here is the thing that would make my dreams totally come true : this box.. with the ability sending a midi-signal that triggers a sample (eg. a loop from a connected sampler) BUT: not before the next bar is gained? i hope you know what i mean. its like the starting of clips in ableton live's session-mode, where they start right in-time with the next bar. so it will require a midi-clock to adjust the tempo (and able to send tempo to a slaved device) of course. would it be hard to realize building a box like this? if there a project that is similarly close to my visions, please let me know. thanks a lot, tibor Quote Link to comment Share on other sites More sharing options...
julienvoirin Posted June 12, 2011 Author Report Share Posted June 12, 2011 you will have to implement a sequencer inside, based on clockbox, so that the midi note is played when you are at the beginning of a bar ; where you are not, the note must be stocked inside a memory space, ready to be released 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.