robinfawell Posted November 22, 2005 Report Posted November 22, 2005 Dear Thorsten I have made an attempt to introduce code in the Din_Notify_toggle section. It worked in a fashion but not correctly. I believe I need to have a register (I am thinking hardware not software!) to store the last unsigned char pin . I can then compare the current ' pin' with the stored value using an if /else statement. Depending on the result I can manipulate the MIOS_DOUT_PinSet expressions and the toggle_state arrays to Drive the LED's and to eventually send appropriate Sysex messages. At this stage I want to restrict the work to just getting the correct LED behaviour.I suspect that I may need another global variable and some additional code in the Din_Notify_toggle section. Briefly how do I achieve this?Also can I use 'pin' or 'array_index' in a for statement? Do they need to be 'int' ?egfor ((array_index) = 0 ; (array_index) <= 3 ; (array_index)++) toggle_state[0] == 0;Thanks Robin Quote
TK. Posted November 24, 2005 Report Posted November 24, 2005 Hi Robin,no, you don't need an "int" for a for statement, "char" or "unsigned char" will work ok, and they are much faster anyhow (16bit always produces additional code, which is mostly not required)So, I guess that your main question is, how to store the last state of a button or LED. You can do this in the same way like described here: http://www.midibox.org/forum/index.php?topic=5662.0Only difference is, that you don't toggle the array entry, but just set or clear itBest Regards, Thorsten. Quote
robinfawell Posted November 24, 2005 Author Report Posted November 24, 2005 Thanks ThorstenMy difficulty is to how record the last Pin # pressed. Also to temporarily store the current Pin # so that I can restore the array index after setting the group array_index values to zero.I am trying to use my Assembler method using C.On each Din I reset all array_index in the group. Then set the current array index by using the stored current pin # or array_index. I realise that it would be possible to use a conditional 'for loop' using break and/or continue.This ensures that only the current array_index is On and it is copied by Dout. Dout.If however the same Din in the group is pressed twice in succession (using Last_ pin_pressed) then each array_index is set to zero prob by using the XOR toggle.I am no sure how to set up the two stored values.Regards Robin Quote
TK. Posted November 24, 2005 Report Posted November 24, 2005 Hi Robin,you could save the last pin number in an additional global variable (just call it 'unsigned char last_pin;')Alternatively you could declare the variable within the function, and make it static ('static unsigned char last_pin;') - static variables don't loose their value when the function is called again, and the variable name is only in the scope of this function, which means, that you can use simple names without the danger for conflicts with other global variables.On each Din I reset all array_index in the group. Then set the current array index by using the stored current pin # or array_index. Thats perfect, I wouldn't do it on a different way I realise that it would be possible to use a conditional 'for loop' using break and/or continue.This leads only to additional execution time (due to the if condition), and to larger code. If however the same Din in the group is pressed twice in succession (using Last_ pin_pressed) then each array_index is set to zero prob by using the XOR toggle.Something that isn't clear to me is the relation between the XOR toggle and the subject "Radio group button behaviour". So long you only want to set a certain pin, and clear the others, then I would suggest following solution:unsigned char group1_selected;void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam{ unsigned char i; // DIN 16..31 is one "radio group" if( pin >= 16 && pin <= 31 ) { // save the selected button function of the group group1_selected = pin - 16; // the LEDs of this group are connected to DOUT Pin 0..15, clear them for(i=0; i<=15; ++i) MIOS_DOUT_PinSet0(i); // set the LED which is related to the selected function MIOS_DOUT_PinSet1(group1_selected); } else { // this branch handles DIN 0..15 and DIN 32..127 }}[/code]So, as you can see, for a group of LEDs, where only one lits, you don't need to store the information in an array, you only need to store a reference to the selected functionBest Regards, Thorsten. Quote
robinfawell Posted November 26, 2005 Author Report Posted November 26, 2005 Dear TKI have spent about 2 days trying to figure out how to code the next stage---without success. A few times I nearly got there but it was always incorrect.Your last code snippet worked fine.What I want is the following. Ultimately to send sysex message when new DIN in the group is pressed. When same lamp pressed in succession it's lamp will go OFF and a Group_Cancel sysex sent. If same Din pressed in succession again the Sysex sent previously will be sent and the lamp will come on. etc etc The Sysex messages can be dealt with later. I want to get the Buttons and LED behaviour sorted out first.RULESA) Only one LED On in group at any time.B) If the same Din pressed repeatedly then it's LED should turn on and off alternately ie toggle.C) If different DIN pressed then new LED comes ON and if previous lamp is ON it will go OFF.Here is my codeunsigned char group1_selected; unsigned char last_pin; unsigned char toggle_state[31]; // 31 buttons can toggle void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam { unsigned char i;// index for toggle_state & MIOS_DOUT_PinSet //unsigned char array_index; // DIN 4..7 will be pressed if( pin >= 4 && pin <= 7) {if (pin_value == 0) {group1_selected = pin - 4;//save current p i = pin - 4; //Starts array at 0 if(last_pin == pin) { toggle_state [i] ^= 0x01;// changes state on each press MIOS_DOUT_PinSet(pin, toggle_state [i] ? 0x7F : 0x00); }else { // all toggle_state arrays reset and LED's should be cleared for(i=0; i<=3; i++) //toggle_state[i]== 0; {MIOS_DOUT_PinSet0(i);} //set current LED and reset toggle_state MIOS_DOUT_PinSet1(group1_selected); toggle_state[group1_selected] == 1; } last_pin = pin; }else{ //other pins } } } I'm not sure about the storage of last_pin . Also the resetting of the elements in the toggle_state array and the LED's is not working.I thought that I could manage this part on my own. Sorry!Regards Robin Quote
TK. Posted November 27, 2005 Report Posted November 27, 2005 Hi Robin,Based on my code I can show you a working solution very quickly.Just define, that group1_selected gets a special value (e.g. 0xff) if the selected button has been pressed a second time. As an effect, all LEDs will be turned off. Once you press the same button again, the routine will work like pressing any other button...So, here the modification:unsigned char group1_selected;void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam{ unsigned char i; // DIN 16..31 is one "radio group" if( pin >= 16 && pin <= 31 ) { // if button is already selected, turn off all LEDs // this is identified with group1_select == 0xff; if( group1_selected == (pin - 16) ) { group1_selected = 0xff; // all LEDs off } else { // save the selected button function of the group group1_selected = pin - 16; } // the LEDs of this group are connected to DOUT Pin 0..15, clear them for(i=0; i<=15; ++i) MIOS_DOUT_PinSet0(i); // set the LED which is related to the selected function if( group1_selected != 0xff ) MIOS_DOUT_PinSet1(group1_selected); } else { // this branch handles DIN 0..15 and DIN 32..127 }}[/code]Best Regards, Thorsten. Quote
robinfawell Posted November 27, 2005 Author Report Posted November 27, 2005 Dear ThorstenI spent some time trying to get the new code working until I remembered that I am using momentary action buttons. I changed if( (pin >= 4 && pin <= 7) to if( (pin >= 4 && pin <= 7) && (pin_value == 0)){It works! I will now see if I can put the pin numbers and group_selected parameters in parallel arrays for the 7 radio groups to keep the code size down.It is a very neat solution.Thank you once again.Regards Robin Quote
TK. Posted November 28, 2005 Report Posted November 28, 2005 Hi Robin,It works! I will now see if I can put the pin numbers and group_selected parameters in parallel arrays for the 7 radio groups to keep the code size down.great! thats the right wayBest Regards, Thorsten. Quote
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.