Shift Register LED Matrix Control Bitwise Operations and Bitmask Assistance

Hey y’all,

I’m making a simplified version of this from scratch, using a Teensy 3.2: Shawn Wasabi - HOTTO DOGU (live original stuff) - YouTube

My first post for a complex issue that I’m struggling with. It concerns 8-bit byte manipulation for the purpose of lighting 16 LEDs (matrix) with 16 buttons (matrix) via shift registers.

My circuit is working and the correct LEDS are lighting via correctly addressed buttons. The issue I’m having lies with effectively adding and subtracting individual bits within the 8-bit bytes being sent to the shift registers, in order to have multiple LEDS light simultaneously. At present, only 1 LED lights at a time, even if multiple buttons are pressed. The last one pressed, lights the corresponding LED. This is because each shift out overwrites the previous one. When two or more buttons are pressed, I want to compare them, add them together, and when one is released, subtract them, thus keeping LEDS illuminated ONLY for the corresponding buttons.

I know the solution lies with bitmasks, but I can’t quite get my head around it. Here’s what I need to do.

B10001000 = lights the first LED in the matrix
B10000100 = lights the second LED in the matrix

B10001100 = lights both first and second LEDs in the matrix

I can bitwise operate this effectively but ‘break;s’ in my code are preventing the operations from acting cumulatively, and each new shift out will overwrite the last. I just need some code layout assistance with this, and advice on how to avoid using breaks.

The more complex issue is the bitwise operations on more than one shift register. The LED matrix I have built is of RGB LEDs with common ANODE. So first of all, the bitwise operation is inverted. Secondly, the last 4 bits sent to the second shift register are handling the anodes, so its bitmath is not inverted, but the first 4 bits are inverted. Let me illustrate. Here’s the actual bitwise operations I’m working with.

dataToSend1 is for red and green rows
dataToSend2 is for blue rows and anode columns

All LEDs Off
dataToSend1 = B11111111;
dataToSend2 = B11110000;

All RED LEDs On
dataToSend1 = B00001111;
dataToSend2 = B11111111;

As you can see, the bitmath requirements are a bit squiffy. Inverted for the first 12 bits, and not for the last 4 bits. I know the solution lies with bitmasks and shifting, but even with all I have read on the subject, I can’t work out how to code it.

I need to take the two 1’s and 0’s associated with a single button press, and apply them to the appropriate dataToSend bytes, thus illuminating the LEDs simultaneously, and extinguishing them as a button is released.

The code is attached, and it works flawlessly, apart from the aforementioned challenges.

Thank you for reading.

Matt.

MIDI_FIGHTER_TEENSY_PROTOTYPE.ino (15.2 KB)

but 'break;s' in my code are preventing the operations from acting cumulatively

That's not it at all. It is that every time you test that a key is pressed, you send some data.

You need to initialize the variable, then, in a loop, test each key, modify the variable, and then, when the loop is done, send the data in the variable.

Right. So the breaks are not adversely affecting the code? Ok.

So initialise the datatosend with default all off, then modify that variable in the loop and send once at the end. Gotcha.

PaulS:
That's not it at all. It is that every time you test that a key is pressed, you send some data.

You need to initialize the variable, then, in a loop, test each key, modify the variable, and then, when the loop is done, send the data in the variable.

I did the above and it's working. Thanks for that.

I'm still having trouble manipulating the bitwise operations because of the common anode and dual shift registers. Any help would be appreciated.