Value to Color + Value to Intensity in loop for pads color 0 / black / off

I’m not sure if this is a bug or just how it works. But I noticed that if I send to my pads multiple value to color 0 (black/off) and followed by (or following) value to intensity messages quickly in a loop, the former (and possibly the latter) is ignored. So basically, I’m looping, sending the colors and intensities but the lights that are currently on (color != 0) do not turn off (color == 0). If I put a delay between each pair of messages, I can get it to work, but it has to have at least about a 7 msec delay. Is this a limitation of the controller? It doesn’t seem to affect other colors, only with black. I did read somewhere that the intensity is ignored for black/off, but it seems the color is ignored too in this case and the pad light stays on. I’ve worked around it by simply not sending intensity when the color is black, but I wonder if it’s maybe a bug in the firmware.

Hello @lucian!

Welcome to our forum!

Let me see if I understand.

You are using some coded application, or Max patch (PD, isadora, touchdesigner or similar) to do the following:

for X
               for all buttons
                                send value to color with color with X value
                                wait Y ms
                                send value to intensity 
                                wait Z ms
               wait P ms

So if X is != 0 and Y and Z take any value, it all works fine
But if X is == 0 and Y is less than 7 (ms), then the last color remains on, and it doesn’t turn to black, which is expected.

Is this correct?
Do you wait after changing the color?
Do you think the intensity value matters?
Can you share the file or the code or patch that you prepared to achieve this?

I tried this with a Qt app that only sends to 8 buttons (to more buttons, but only 8 are configured with Value to Color and Value to intensity), something like the loop above, with X changing from 10 to 0, Y = Z = 1 ms and P = 400ms (also tried P = 1ms) and I get the expected behavior, all buttons turn off with the last X value being 0.
I set intensity values that go down from 110 to 10 in jumps of 10 on each loop round.

Please let me know a bit more about your setup and what you’re trying to do.

@francoytx
Yes, that’s basically it, but I didn’t try adding the Y delay. I only tried adding the Z delay. Here is my code using Juce. Basically the same as what you have. Hopefully it’s fairly straight forward to understand from it. It includes the early return below as a fix: don’t send the intensity when sending color 0 / black / off. I tried changing the order, sending intensity first or last but that doesn’t seem to make a difference.

        void setPadColor(int col, int row, juce::uint8 color, int midiChannel, int actualCols)
        {
            const int index = (row * actualCols) + col;
            const auto message = juce::MidiMessage::noteOn(midiChannel, index, color);
            juceOutputDevice->sendMessageNow(message);

                // Fix intensity not clearing when black / 0 / off color being sent by not sending intensity
                if (color == 0)
                    return; // don't send intensity for black / off

                const auto intensity = 64; // various intensities get sent
                const auto intensityMsg = juce::MidiMessage::noteOn((int)MidiChannels::VALUE_TO_INTENSITY, index, intensity);
                juceOutputDevice->sendMessageNow(intensityMsg);
        }

called from:

            for (int y = 0; y < rows; ++y)
            {
                for (int x = 0; x < cols; ++x)
                {
                    auto color = 0; // any other color seems to work fine w/ intensity
                    setPadColor(x, y, color, (int)MidiChannels::SEQUENCER_PADS, cols);
// works if I put a usleep(7000) call here to sleep 7ms or more or when running in a debugger
                }
            }

Oh I see!

Adding a delay between messages might be a good idea!

Actually the MIDI devices expect 31.25 kbps (kilo-bits per second), that’s ~1000 messages per second at most.
31250/8 (bits/byte) = 3906 bytes / 3 (bytes / message) ~= 1300 messages

This is why Wikipedia says:
A three-byte MIDI message requires nearly 1 millisecond for transmission

You’d think USB communications would be faster than old 70’s MIDI bandwidth but USB hosts polls devices about 1000 times / second, so actually you still get a similar bandwidth.

So it’s a good practice to put a small delay between messages, unless you can find a way to put all of them in a single USB packet.

This said, we found some improvements to make to the way we handle LED feedback in our controllers which you’ll get in the soon-to-come firmware update :slight_smile:

1 Like

I wonder why the issue doesn’t show up when just turning pads on / off but only with the intensity on black and no other color. From the linked article it seems that a lot of these messages should fit together into a single USB packet by default, assuming they are sent quickly enough, and that USB MIDI can actually be quite a bit faster than DIN MIDI. The strange thing though is that whatever is going on, it only seems to affect the black/off messages coupled with the intensity messages, not the other other colors colors and their intensity messages or any other note/cc messages. Perhaps it not really a timing issue, but an issue that is resolved with a small delay. Right now I’m just avoiding sending intensity for black/off as it doesn’t make much sense anyway and the less sent the better as I’m trying to avoid lag with the display anyway.