Jump to content

potential bug with "delay_ms" and other ".ngr" questions


mumblecake
 Share

Recommended Posts

Hi,

 

I have now finally come to a stage with my organ project at which I can start scripting my ngr file. In order to speed up my keyboard scans I have used the relatively new option to define the maximum number of shift registers (SRIO num_sr=16) which I think might explain the behaviour which I'm describing in the following.

 

I played a bit around with the scripting and in particular the delay functions. The script was as simple as:

 

if ^section == 0
   Log "start"
   delay_ms 1000
   Log "end"
endif

The script was fired on a button press. But rather than seeing a delay of 1 sec between the two messages I saw only half a second. Could it be that the delay_ms is somehow coupled to the defined number of shift registers and that by halving that my delays halve as well?

 

Another thing I noticed is that if I press the button while the previous script is still running it seems to abort the script and start it again. Is that intended behaviour? Meaning:

 

<press button first time>

MIOS studio: "start"

<press button another time>

MIOS studio: "start"

<wait>

MIOS studio: "end"

 

This brings me to my specific application and I was hoping someone could give me an idea of how to approach this, as if done wrong I can fry quite a bit of my equipment.

 

I have stop action magnets (SAM) for the organ. Those have a digital output (reed switch) indicating if they are on or off (normal DIN). You are also able to automatically change the switch over to a certain position. For this the SAM carries two coils, one used to switch the SAM on and one to switch it off (DOUT/LED with ULN darlington transistor). The coils are operated with a 15V PSU, draw 0.5A current and are quite small ... too small as if they could dissipate 7.5W. It is therefore key that neither coil gets activated for longer than ~100ms as otherwise I would risk to burn out the coil. There are now two operational modes which the controller needs to cater for:

 

Firstly: it needs to be possible to manually change over the SAM. The controller should recognise this and send out a midi signal to the computer (cc signal)

 

Secondly: An automatic change is requested by an incoming midi signal (same cc signal).

   - If the SAM is already in the requested position: don't do anything.

   -  the requested value is different

      - The script should now disable the opposite coil (just in case it was still active)

      - it should activate the correct coil

      - wait for 100ms (I do not want to wait on the din as if the button is stuck we get to a situation where the current stays on indefinitely)

      - switch the coil off (probably best to switch every coil off)

      - if the digital input flips it should ignore this and not send out a midi signal as it is simply obeying a command. The computer expects the command to

        having been executed and doesn't need confirmation

 

Now the things I'm worried about. I have 43 of those SAMs and a lot of commands can come in in quick succession. The ngr file takes about 5ms to load for each called script section. How can I ensure that the coils are actually being switched on if a successive script call is going to cancel the previous one which started less than 5 ms ago and hasn't activated the coil yet? Then how can I ensure that the coils are switched off after 100ms and lets say an absolute maximum of 200ms: Let's say I alternate through all 43 SAMs with 10ms delay. That means the new coils would all get set but the delay_ms will never finish and no coil would ever get switched off.

 

It would be great if someone more experienced could shed some light on how to best approach the problem

 

thanks a lot

 

best regards

 

Mathis

Link to comment
Share on other sites

I have used the relatively new option to define the maximum number of shift registers (SRIO num_sr=16)

 

Please note that there was a problem with the SRIO num_sr function in V1.032

There is a newer version (v1_033_pre4) which can be downloaded here: http://www.ucapps.de/mios32/

However, I don't know if this will fix your issues...

 

 

The script was fired on a button press. But rather than seeing a delay of 1 sec between the two messages I saw only half a second. Could it be that the delay_ms is somehow coupled to the defined number of shift registers and that by halving that my delays halve as well?

 

It shouldn't... I never tried such a high delay by myself, will try this soon...

 

 

Another thing I noticed is that if I press the button while the previous script is still running it seems to abort the script and start it again. Is that intended behaviour?

 

Yes, this is the intended behaviour.

Commands won't be queued.

 

 

Now the things I'm worried about. I have 43 of those SAMs and a lot of commands can come in in quick succession.

 

I fear that there is currently no way to do such kind of automation with MIDIbox NG :-/

 

And I've currently no idea for a simple implementation.

My biggest problem is, that I don't have access to your equipment for testing ;-)

 

Best Regards, Thorsten.

Link to comment
Share on other sites

Hi Thorsten,

 

thanks for reply. I installed the update but it doesn't change anything about the timing of the delay_ms. I turned the SRIO num_sr subsequently off for testing and the timing was still out by a factor of 2. Will poke my scope in at some point to get a more quantitative measurement. Doesn't really matter at the moment was just a noteworthy find.

 

I think you are underestimating what you have achieved with NG. I do think that it is possible with the right combination of meta events and ngr scripting (activating and deactivating meta events when needed). I think that it definitely is possible just not as straight forward as all other steps to this point. I'll get to work and try to prove you wrong (I take it that you won't mind that) ;)

 

BR Mathis

Link to comment
Share on other sites

I'm struggeling a bit (with the simple stuff unfortunately)

 

I would like to forward midi events to their respective LEDs:

 

E.g. I get a midi signal: ch5 cc=0 value=0

I want to forward this event to LED:33

I get a midi signal: ch5 cc=0 value=127

I want to forward this event to LED:34

 

from the respective LEDs I would like to start the correct section of the script.

 

I started with something like this:

 

#should forward when incoming signal is the correct channel, correct cc and value=0

  EVENT_RECEIVER id=1 fwd_id=led:33 type=CC chn=5 cc=0 range=0:0

#should forward when incoming signal is the correct channel, correct cc and value=127
  EVENT_RECEIVER id=2 fwd_id=led:34 type=CC chn=5 cc=0 range=127:127

# should switch on LED:33 and run section 1
  EVENT_LED id=33 type=Meta meta=RunSection:1

# should switch on LED:34 and run section 2
  EVENT_LED id=34 type=Meta meta=RunSection:2

 

unfortunately this doesn't work. Even when I replaced the receiver events with button events and forwarded to the LEDs, it never started the script sections.

 

Any insight into what I'm doing wrong would be much appreciated

Link to comment
Share on other sites

This configuration will only set the value of the LED, but it won't trigger the action (it won't execute the meta command)

 

For such purposes I introduced the SENDER event; so if you write:

#should forward when incoming signal is the correct channel, correct cc and value=0
  EVENT_RECEIVER id=1 fwd_id=sender:33 type=CC chn=5 cc=1 range=0:0
#should forward when incoming signal is the correct channel, correct cc and value=127
  EVENT_RECEIVER id=2 fwd_id=sender:34 type=CC chn=5 cc=1 range=127:127
# run section 1
  EVENT_SENDER id=33 type=Meta meta=RunSection:1
# run section 2
  EVENT_SENDER id=34 type=Meta meta=RunSection:2

the run script section should be executed.

 

From the section you can switch the LED, e.g. "set LED:33 127" will turn it on, and "set LED:33 0" will turn it off

 

Best Regards, Thorsten.

Link to comment
Share on other sites

This configuration will only set the value of the LED, but it won't trigger the action (it won't execute the meta command)

 

For such purposes I introduced the SENDER event; so if you write:

#should forward when incoming signal is the correct channel, correct cc and value=0
  EVENT_RECEIVER id=1 fwd_id=sender:33 type=CC chn=5 cc=1 range=0:0
#should forward when incoming signal is the correct channel, correct cc and value=127
  EVENT_RECEIVER id=2 fwd_id=sender:34 type=CC chn=5 cc=1 range=127:127
# run section 1
  EVENT_SENDER id=33 type=Meta meta=RunSection:1
# run section 2
  EVENT_SENDER id=34 type=Meta meta=RunSection:2

the run script section should be executed.

 

From the section you can switch the LED, e.g. "set LED:33 127" will turn it on, and "set LED:33 0" will turn it off

 

Best Regards, Thorsten.

 

That's brilliant. Thank you Thorsten!

 

Would this work (sorry, I'm at work right now, otherwise I would just give it a whirl rather than asking)?

 

#should forward to Senders with hw_id=1 when incoming signal is the correct channel, correct cc and value=0
  EVENT_RECEIVER id=1 fwd_id=sender:1 type=CC chn=5 cc=1 range=0:0
#should forward to Senders with hw_id=2 when incoming signal is the correct channel, correct cc and value=127
  EVENT_RECEIVER id=2 fwd_id=sender:2 type=CC chn=5 cc=1 range=127:127
# run section 1, switch on LED 33, switch off LED 34
  EVENT_SENDER id=1 hw_id=1 fwd_id=LED:33:127 type=Meta meta=RunSection:1
  EVENT_SENDER id=2 hw_id=1 fwd_id=LED:34:0
# run section 2, switch off LED 33, switch on LED 34
  EVENT_SENDER id=3 hw_id=2 fwd_id=LED:34:127 type=Meta meta=RunSection:2 
  EVENT_SENDER id=4 hw_id=2 fwd_id=LED:33:0

What I'm trying to do is getting the "switch on/off" out of the script so that it doesn't matter if the script gets cancelled before the LED got switched. The script would only contain the wait and a "switch all 86 LEDs off". So even if my organ software sends 20 midi signals to get 20 stop action magnets (deutsch: Registerknoepfe) changed it would activate all 20 LEDs/solenoids and deactivate the respective opposites. The script would start executing 19 times and each time get interrupted. On the twentieth run, the script would however run through and deactivate everything at the end.

 

I have decided that the case of commands coming in every 10, 20 even 100ms is unlikely and I can't afford looking for a solution that covers that requirement. For now I also ignore the fact that once the BUTTON gets switched by the solenoids it is going to repeat the signal that was initially requested ... it shouldn't do any harm. That means that if I could manage to activate one LED, deactivate another and start the script I would basically be done.

Link to comment
Share on other sites

OK, it doesn't work but I don't fully understand why. I have at the moment:

 

ngc:

 

# run section 1, switch on LED 33, switch off LED 34
  EVENT_SENDER id=1 hw_id=1 type=Meta meta=RunSection:1
  EVENT_SENDER id=2 hw_id=1 fwd_id=LED:34:0
  EVENT_SENDER id=3 hw_id=1 fwd_id=LED:33:127
# run section 2, switch off LED 33, switch on LED 34
  EVENT_SENDER id=4 hw_id=2 type=Meta meta=RunSection:1 
  EVENT_SENDER id=5 hw_id=2 fwd_id=LED:34:127
  EVENT_SENDER id=6 hw_id=2 fwd_id=LED:33:0

# using buttos rather than receive events for testing

EVENT_BUTTON id=33 fwd_id=sender:1 type=CC chn=4 cc=0 button_mode=OnOnly
EVENT_BUTTON id=34 fwd_id=sender:2 type=CC chn=4 cc=1 button_mode=OnOnly

 

and ngr:

 

if ^section == 1

log "section 1"
 delay_ms 100

set LED:33 0
set LED:34 0
endif

 

I can see that the script is getting fired but none of the LEDs seems to get engaged now (or all at once ... nothing moving)

 

any ideas?

 

Link to comment
Share on other sites

That's a clever solution! :)

 

Unfortunately EVENT_RECEIVER doesn't filter based on the specified range, which means that forwarding will always take place.

 

I'm currently working on a better solution for you (it might require a firmware change)

Please wait some minutes...

 

Best Regards, Thorsten.

Link to comment
Share on other sites

Ok, here the recommended solution:

 

  EVENT_RECEIVER id=1 fwd_id=sender:1 type=CC chn=5 cc=1

# run section 1, switch on LED 33, switch off LED 34
  EVENT_SENDER id=1 hw_id=1 if_equal=0   fwd_id=LED:33:127 type=Meta meta=RunSection:1
  EVENT_SENDER id=2 hw_id=1 if_equal=0   fwd_id=LED:34:0
# run section 2, switch off LED 33, switch on LED 34
  EVENT_SENDER id=3 hw_id=1 if_equal=127 fwd_id=LED:34:127 type=Meta meta=RunSection:2 
  EVENT_SENDER id=4 hw_id=1 if_equal=127 fwd_id=LED:33:0

the receiver forwards the received values to all senders which are matching with hw_id=1

The senders only react on a matching value (if_equal=<value>)

 

The value forwarding to a non-existing event (LED:33:x and LED:34:x) will only work with this new pre-release:

http://www.ucapps.de/mios32/midibox_ng_v1_033_pre5.zip

 

I also fixed the DELAY_MS parameter, delay should be handled properly now (it was running twice the speed before if MBNG was showing the main screen on LCD)

 

Best Regards, Thorsten.

Link to comment
Share on other sites

Hi Thorsten,

 

this is amazing. Thank you soooo much. I'm getting really close now. I can almost feel it (though still loads of work to) ;)

 

I would start literally jumping for joy if I wasn't surrounded by colleagues who would look very bewildered. So happy in the prospect of getting past this stage of the project.

 

BR Mathis

Edited by mumblecake
Link to comment
Share on other sites

At first I had the wires swapped on the DOs which meant that as the DI was always creating a midi signal on change that I created a nice flip flop. Managed to pull the plug of the PSU for the coils before anything started to disintegrate. I quickly made the same swap in the config and everything started working: A manual change changed whether the stop was pulled or not in the software while a click in the software changed the physical position of the switch.

 

Soooo satisfying when everything starts to come together.

 

More determined than ever to see this project through to the end!

Link to comment
Share on other sites

Quick question: The ngc config needs to have a 6 Bit enable mask for the onboard AIs:

 

e.g.

AIN enable_mask=110000

 

the Core_STM32F4 does however provide 8 AIs

 

do I need to make the mask an 8 Bit mask in order to not leave the last two AIs in an ambiguous state (I only want to use 2 AIs)?

Link to comment
Share on other sites

Hi, I've got another question.

 

I have the following:

 

ngc:

 

EVENT_BUTTON id=65  type=CC chn=5 cc=0 fwd_id=sender:8

EVENT_BUTTON id=72  type=CC chn=5 cc=7

 

EVENT_RECEIVER id=8 fwd_id=sender:8 type=CC chn=5 cc=7
EVENT_SENDER id=13 hw_id=8 if_equal=0   fwd_id=sender:9 type=Meta meta=RunSection:2
EVENT_SENDER id=14 hw_id=8 if_equal=127   fwd_id=sender:10 type=Meta meta=RunSection:3
EVENT_SENDER id=15 hw_id=9 if_equal=button:72:127   fwd_id=LED:47:127 type=Meta meta=RunSection:1
EVENT_SENDER id=16 hw_id=9 if_equal=button:72:127   fwd_id=LED:48:0
EVENT_SENDER id=17 hw_id=10 if_equal=button:72:0 fwd_id=LED:47:0 type=Meta meta=RunSection:1
EVENT_SENDER id=18 hw_id=10 if_equal=button:72:0 fwd_id=LED:48:127

 

ngr:

 

if ^section == 1
#log "section 1"

 delay_ms 50
 set LED:33 0
 set LED:34 0
 set LED:35 0
 set LED:36 0
 set LED:37 0
 set LED:38 0
 set LED:39 0
 set LED:40 0
 set LED:41 0
 set LED:42 0
 set LED:43 0
 set LED:44 0
 set LED:45 0
 set LED:46 0
 set LED:47 0
 set LED:48 0
endif

if ^section == 2
log "Off"
endif

if ^section == 3
log "On"
endif
 

The idea is the following: Up to now the solenoids would have always engaged when an external midi command came in. I wanted to change that so that the solenoids would only engage when their respective button (Button:72) was in the wrong position. Therefore I have split the received message into the cases of "off" and "on" (Sender IDs: 13 & 14) and forwarded those to the sender events which should switch the button off (Sender: 15 &16) or on (Sender: 17 &18)

 

For testing purposes I also attached the same mechanism to another button (button:65). I also created new dummy scripts to be able to follow what is happening.

 

When I actuate Button:65 everything works and Button:72 is repeating the state of 65. There are no log messages in MIOS Studio which is not surprising as the scripts which would display "on" or "off" get cancelled in the chained event which launches script section 1.

 

When send the correct midi signal nothing moves but I get "on" and "off" displayed in the MIOS studio meaning that the event did not get forwarded and section 1 never launched.

 

This is surprising me as the maximum nesting level of four is not reached (should be two unless I'm counting wrong).

 

Does anyone have an idea?

 

edit: could it have to do with timing in that the when the midi command is received that the current state of button:72 is not available while when actuating button 65 it still is, as the read out has just finished?

Edited by mumblecake
Link to comment
Share on other sites

It seems that there is a contradiction:

 

EVENT_BUTTON id=72  type=CC chn=5 cc=7
EVENT_RECEIVER id=8 fwd_id=sender:8 type=CC chn=5 cc=7

BUTTON:72 and RECEIVER:8 listen to the same CC number (cc=7, chn=5)

 

BUTTON:72 will get the received value

Thereafter RECEIVER:8 forwards to all (hw_id)SENDER:8

 

EVENT_SENDER id=13 hw_id=8 if_equal=0   fwd_id=sender:9 type=Meta meta=RunSection:2
EVENT_SENDER id=14 hw_id=8 if_equal=127   fwd_id=sender:10 type=Meta meta=RunSection:3

SENDER:13 forwards to SENDER:9 if the received value was 0

SENDER:14 forwards to SENDER:10 if the received value was 127

 

EVENT_SENDER id=15 hw_id=9 if_equal=button:72:127   fwd_id=LED:47:127 type=Meta meta=RunSection:1
EVENT_SENDER id=16 hw_id=9 if_equal=button:72:127   fwd_id=LED:48:0

SENDER:15 and SENDER:16 listen to (hw_id)SENDER:9 (which forwarded if the received value was 0)

But: they will only react if BUTTON:72 is 127 - but the MIDI event set BUTTON:72 to 0 before

 

Same for SENDER:17 and SENDER:18

EVENT_SENDER id=17 hw_id=10 if_equal=button:72:0 fwd_id=LED:47:0 type=Meta meta=RunSection:1
EVENT_SENDER id=18 hw_id=10 if_equal=button:72:0 fwd_id=LED:48:127

They only react if BUTTON:72 is 0, but it has been set to 127 via MIDI before.

 

Best Regards, Thorsten.

Link to comment
Share on other sites

Ohhh,

 

so the button is also receiving the midi command ... I though it was only sending it. Ok, I will decouple the button and the message sending by introducing another sender. Will see how feasible this will be ... even if it works it will clutter the ngc file quite badly ... I might just end up accepting the solenoid activation for simplicities sake.

 

Thanks a lot for shedding some light on this.

 

BR Mathis

Link to comment
Share on other sites

  • 2 weeks later...

Finally got all 43 SAMs wired in (43 digital in + 86 digital out)

 

I wanted to quickly give a configuration reference in case someone in the future wants to do something similar (this thread has captured quite a few of the caveats of the configuration and scripting).

 

To freshen up. I set out to do the following:

 

Firstly: it needs to be possible to manually change over the SAM. The controller should recognise this and send out a midi signal to the computer (cc signal)

 

Secondly: An automatic change is requested by an incoming midi signal (same cc signal).

   - If the SAM is already in the requested position: don't do anything.

   -  the requested value is different

      - The script should now disable the opposite coil (just in case it was still active)

      - it should activate the correct coil

      - wait for 100ms (I do not want to wait on the din as if the button is stuck we get to a situation where the current stays on indefinitely)

      - switch the coil off (probably best to switch every coil off)

      - if the digital input flips it should ignore this and not send out a midi signal as it is simply obeying a command. The computer expects the command to

        having been executed and doesn't need confirmation

 

one problem was that when you fire a script section while the previous iteration hasn't finished executing yet, the previous execution will be stopped and a new one will be launched. This meant that only a wait and a switch off command could go into the script as otherwise anything before the wait would possibly not get executed.

 

So here it is:

 

my digital in is on Button:65

while my digital outs are on LED:33 (Off coil)

and LED:34 (on coil)

 

ngc:

 

#part for manual switch actuation. Sending of the CC event needs to be part of separate sender as otherwise "if_equal" comparison with button value will fail

EVENT_BUTTON id=65  fwd_id=sender:1
EVENT_SENDER id=1 type=CC chn=5 cc=0

 

#part for automated switch actuation. Forward to forking logic as part of Senders with hw_id=101

EVENT_RECEIVER id=1 fwd_id=sender:101 type=CC chn=5 cc=0

#if requested off go to Senders with hw_id=102
EVENT_SENDER id=101 hw_id=101 if_equal=0   fwd_id=sender:102

#if requested on go to Senders with hw_id=103
EVENT_SENDER id=102 hw_id=101 if_equal=127   fwd_id=sender:103

#switch off logic. If Switch is in on position activate off coil and deactivate on coil. Also start script section 1. If switch was already in off position: don't do anything
EVENT_SENDER id=103 hw_id=102 if_equal=button:65:127   fwd_id=LED:33:127 type=Meta meta=RunSection:1
EVENT_SENDER id=104 hw_id=102 if_equal=button:65:127   fwd_id=LED:34:0

#switch on logic. If switch is in off position activate on coil and deactivate off coil. Also start script section 1. If switch was already in on position: don't do anything
EVENT_SENDER id=105 hw_id=103 if_equal=button:65:0 fwd_id=LED:33:0 type=Meta meta=RunSection:1
EVENT_SENDER id=106 hw_id=103 if_equal=button:65:0 fwd_id=LED:34:127

 

ngr:

 

if ^section == 1

#deactivate sending of messages. An automated change request has been made ... I don't need to inform the origin of the change request that the change has been performed
set_active (id)SENDER:1 0

#wait 100ms ... that's roughly how long it takes for the switch to change.
delay_ms 100

#switch has now been fully actuated. Reactivate sending of values to become responsive to manual changes again.

set_active (id)SENDER:1 1
set LED:33 0
set LED:34 0

endif

 

hope that might be useful to someone at some point.

 

BR Mathis

Link to comment
Share on other sites

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

×
×
  • Create New...