Jump to content

Recommended Posts

Posted

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' ?

eg

for ((array_index) = 0 ; (array_index) <= 3 ; (array_index)++)	
	toggle_state[0] == 0;

Thanks Robin

Posted

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.0

Only difference is, that you don't toggle the array entry, but just set or clear it

Best Regards, Thorsten.

Posted

Thanks Thorsten

My 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

Posted

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 function

Best Regards, Thorsten.

Posted

Dear TK

I 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.

RULES

A) 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 code

unsigned 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

Posted

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.

Posted

Dear Thorsten

I 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

Posted

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 way

Best Regards, Thorsten.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...