# sendNrpn broken: workaround

**URL:** <https://forum.electra.one/t/sendnrpn-broken-workaround/3310>\
**Category:** Bug reports\
**Tags:** lua\
**Created:** [October 19, 2024, 9:50pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310 "2024-10-19T21:50:22Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![NewIgnis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/newignis/32/767_2.png) [@NewIgnis](https://forum.electra.one/u/NewIgnis)\
**Post date:** [October 19, 2024, 9:50pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/1 "2024-10-19T21:50:22Z")

</div>

have been using sendNrpn in the past, but now it’s throwing errors:

`error running function 'runFunction': ctrlv2/slots/p065.lua:26: bad argument #0 to 'sendNrpn' (number expected, got table)`

In line 26 I’ve got the following, which should not generate any error…  
` midi.sendNrpn(1, 7, 6, 2)`

Because the documentation states the following syntax:

> **midi.sendNrpn(port, channel, parameterNumber, value)**

However the doc now mentions 5, not 4 arguments. In what order should they be?  
I get other errors if I add a boolean as fifth argument.

> A function to send a NRPN MIDI message.
> 
> > - `port` - integer, a port identifier(see [Globals](https://docs.electra.one/developers/luaext.html#globals) for details).
> > - `channel` - integer, a numeric representation of the MIDI channel(1 … 16).
> > - `parameterNumber` - integer, an identifier of the NRPN(0 … 16383).
> > - `value` - integer, a value to be sent(0 … 16383).
> > - `lsbFirst` - boolean, when true, the lsb and msb bytes will be swapped.

---

<div class="post-metadata">

**Author:** ![oldgearguy](https://avatars.discourse-cdn.com/v4/letter/o/f4b2a3/32.png) [@oldgearguy](https://forum.electra.one/u/oldgearguy)\
**Post date:** [October 19, 2024, 10:49pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/2 "2024-10-19T22:49:55Z")

</div>

I’ve been using the sendNrpn() method posted by someone else for a long time. The Lua version has been broken for a while. The webUI version does work.

```auto
function sendNrpn(port, channel, parameter, value)
    local parameterMSB = (parameter >> 7) & 0x7F
    local parameterLSB = parameter & 0x7F
    local valueMSB = (value >> 7) & 0x7F
    local valueLSB = value & 0x7F

    local messages = {
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 99, value = parameterMSB},
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 98, value = parameterLSB},
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 6, value = valueMSB},
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 38, value = valueLSB}
    }

    for i, msg in ipairs(messages) do
        midi.sendMessage(port, msg)
    end

```

---

<div class="post-metadata">

**Author:** ![NewIgnis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/newignis/32/767_2.png) [@NewIgnis](https://forum.electra.one/u/NewIgnis)\
**Post date:** [October 20, 2024, 2:11pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/3 "2024-10-20T14:11:40Z")

</div>

Thanks,

the workaround is very usable.  
For those who want to use it: then swap ‘midi.sendNrpn’ for sendNrpn’

---

<div class="post-metadata">

**Author:** ![martin](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/martin/32/145_2.png) [@martin](https://forum.electra.one/u/martin)\
**Post date:** [October 23, 2024, 8:17am UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/4 "2024-10-23T08:17:52Z")

</div>

sendNrpn is fixed in the upcoming release. I have added extra parameters to change order of bytes and including the reset bytes. The documentation will be updated.

---

<div class="post-metadata">

**Author:** ![NewIgnis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/newignis/32/767_2.png) [@NewIgnis](https://forum.electra.one/u/NewIgnis)\
**Post date:** [August 23, 2025, 11:55am UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/5 "2025-08-23T11:55:12Z")

</div>

Hi, sendNrpn is still broken but it’s a bit functional now:

- I had to add a dummy argument as argument 1 to make it work.
- the two loast arguments do not expect a boolean, so I changed them to 0 and 1
- It doesn’t respond to the reset 0/1 option. The reset CC 100 and 101 are always sent.

---

<div class="post-metadata">

**Author:** ![NewIgnis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/newignis/32/767_2.png) [@NewIgnis](https://forum.electra.one/u/NewIgnis)\
**Post date:** [August 24, 2025, 5:27pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/6 "2025-08-24T17:27:16Z")

</div>

Hi, is there a way to override the standard sendNrpn function for a bespoke one?

I tried this at the start of the script, to no avail.

```auto
local originalSendNrpn = midi.sendNrpn -- keep original
function mySendNrpn(port, channel, parameter, value)
    print("Custom NRPN code")
    local parameterMSB = (parameter >> 7) & 0x7F
    local parameterLSB = parameter & 0x7F
    local valueMSB = (value >> 7) & 0x7F
    local valueLSB = value & 0x7F
    local messages = {
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 98, value = parameterLSB},
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 99, value = parameterMSB},
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 6, value = valueMSB},
        {channel = channel, type = CONTROL_CHANGE, controllerNumber = 38, value = valueLSB}
    }
    for i, msg in ipairs(messages) do
        midi.sendMessage(port, msg)
    end
end

_G.midi.sendNrpn = mySendNrpn

```

---

<div class="post-metadata">

**Author:** ![oldgearguy](https://avatars.discourse-cdn.com/v4/letter/o/f4b2a3/32.png) [@oldgearguy](https://forum.electra.one/u/oldgearguy)\
**Post date:** [August 24, 2025, 5:46pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/7 "2025-08-24T17:46:34Z")

</div>

Martin may have that answer, but my only thought is to put the call into the custom version in each control (and have those controls be virtual)

---

<div class="post-metadata">

**Author:** ![NewIgnis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/newignis/32/767_2.png) [@NewIgnis](https://forum.electra.one/u/NewIgnis)\
**Post date:** [August 24, 2025, 6:05pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/8 "2025-08-24T18:05:00Z")

</div>

I did that before, but it’s a lot of work if first the preset is made and only afterwards you find out the default NRPN for that particalur preset isn’t quite what you need.

Thanks anway 🙂

---

<div class="post-metadata">

**Author:** ![martin](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/martin/32/145_2.png) [@martin](https://forum.electra.one/u/martin)\
**Post date:** [August 27, 2025, 7:46am UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/9 "2025-08-27T07:46:53Z")

</div>

I have fixed the `sendNrpn` function. The fix will be released in the upcoming release. The issue was caused by the optional interface parameter that was not included in your call. The fix covers both calling the function with and without the optional parameter.

regarding the function overriding, you can do that like this:

```auto
function midi.sendNrpn(port, channel, parameter, value)
    print("sendNrpn")
end

midi.sendNrpn(1, 7, 6, 2)

```

It works for any function. Any standard function can be overridden by redefining it in the global context.

---

<div class="post-metadata">

**Author:** ![NewIgnis](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.electra.one/newignis/32/767_2.png) [@NewIgnis](https://forum.electra.one/u/NewIgnis)\
**Post date:** [August 27, 2025, 4:33pm UTC](https://forum.electra.one/t/sendnrpn-broken-workaround/3310/10 "2025-08-27T16:33:54Z")

</div>

weird

I thought I tried that before going the more complex way. I’ll surely try again now 🙂  
Thanks Martin!
