RGB Matrix Hat - Python with Forked Libraries

Moderators: adafruit_support_bill, adafruit

Forum rules
Talk about Adafruit Raspberry Pi® accessories! Please do not ask for Linux support, this is for Adafruit products only! For Raspberry Pi help please visit: http://www.raspberrypi.org/phpBB3/
Locked
User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

When Adafruit created the RGB Matrix Hat, they also created a fork of Henner Zeller's "rpi-rgb-led-matrix" library to use a modified pinout. Since then, Henner has continued updating his library, including better pinouts to minimize flicker and expand the number of displays. He states about the Adafruit library, "that fork is ancient, so I stronlgy suggest to use this original library instead." (He also provides a suggestion to make a hardware modification to the Hat to use his new pinouts.)

That said, I feel the Python library in Adafruit's fork is better than his (easier to use). So, my question to either the folks at Adafruit or anyone who has experimented with this: Has anyone used Adafruit's older Python library with Henner's newer version of his "rpi-rgb-led-matrix" library? If so, what are the steps?

User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

Just to provide a bit more information about what I'm attempting and why...

I downloaded the latest version of the "hzeller/rpi-rgb-led-matrix" library from GitHub, then transplanted Adafruit's "rgbmatrix.cc" Python library into it and added it to the Makefile. Everything compiled without errors, and it produced the expected "rgbmatrix.o" and "rgbmatrix.so" files. However, when I attempted to run an existing Python script that works with Adafruit's older "rpi-rgb-led-matrix" library, I receive the error:

undefined symbol: _ZN10rgb_matrix9RGBMatrixC1EPNS_4GPIOEii

I honestly don't know enough about C++ programming to figure out what needs to be updated to make this work. I'm hoping someone else has, or can at least point the way.

Although Henner Zeller has his own Python library, it lacks many good features of the Adafruit Python library, such as ImageFont, SetImage, etc.

User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

One other note -- Henner Zeller has responded to others inquiring about the Adafruit Python library, to which he replies, "They have used a fork of my library a while ago, added the Python library and then essentially abandoned - maybe we can motivate them to refresh the Python interfacing with the current version of the code?" (https://github.com/hzeller/rpi-rgb-led-matrix/issues/91)

User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

Okay, before anyone says, "egads, this guy is irritating," I just want to announce -- I fixed the problem! I realize I should be making a pull request on GitHub, but I honestly don't know what (or how) to do that because this update would require an entire update to the "adafruit/rpi-rgb-led-matrix" library first to get it up to sync with "hzeller/rpi-rgb-led-matrix", but for those adventurous individuals who may want to attempt this themselves, here's what I did:

1. First, make sure you have a folder on your Pi with the latest "hzeller/rpi-rgb-led-matrix" library unpacked.

2. Then, copy from the older "adafruit/rpi-rgb-led-matrix" library the file "rgbmatrix.cc" into the root of the above folder.

3. To update "rgbmatrix.cc", make the following edits:

From lines 26 to 40, change:

Code: Select all

static PyObject *RGBmatrix_new(
  PyTypeObject *type, PyObject *arg, PyObject *kw) {
	RGBmatrixObject *self = NULL;
	int              rows, chain;

	if((PyTuple_Size(arg) == 2) &&
	   PyArg_ParseTuple(arg, "II", &rows, &chain)) {
		if((self = (RGBmatrixObject *)type->tp_alloc(type, 0))) {
			self->matrix = new RGBMatrix(&io, rows, chain);
			Py_INCREF(self);
		}
	}

	return (PyObject *)self;
}
to

Code: Select all

static PyObject *RGBmatrix_new(
  PyTypeObject *type, PyObject *arg, PyObject *kw) {
	RGBmatrixObject *self = NULL;
	int              rows, chain, parallel;

	if((PyTuple_Size(arg) == 3) &&
	   PyArg_ParseTuple(arg, "III", &rows, &chain, &parallel)) {
		if((self = (RGBmatrixObject *)type->tp_alloc(type, 0))) {
			self->matrix = new RGBMatrix(&io, rows, chain, parallel);
			Py_INCREF(self);
		}
	}

	return (PyObject *)self;
}
In summary, a third argument called "parallel" is required because the more recent "hzeller" library supports 1, 2 or 3 parallel interface chains. Note that along with adding the "parallel" argument in three places, you also need to update PyTuple_Size(arg) == 3 and PyArg_ParseTuple(arg, "III"... (three capital-I) to pass the extra argument.

Then, I needed to remark out lines 241 to 250 as these were causing a compile error:

Code: Select all

/* static PyObject *SetWriteCycles(RGBmatrixObject *self, PyObject *arg) {
	uint8_t b;

	if((PyTuple_Size(arg) == 1) && PyArg_ParseTuple(arg, "B", &b)) {
		io.writeCycles = b;
	}

	Py_INCREF(Py_None);
	return Py_None;
} */
Not sure if this routine is required anymore anyway; it's not one I ever used.

4. Once that was done and saved, you need to edit the root "Makefile" file to add this library to the build:

On line 3, append "rgbmatrix.so":

Code: Select all

BINARIES=led-matrix minimal-example text-example rgbmatrix.so
Then further down at line 37 (probably not critical where), add:

Code: Select all

 # Python module
 rgbmatrix.so: rgbmatrix.o $(RGB_LIBRARY)
          $(CXX) -s -shared -lstdc++ -Wl,-soname,librgbmatrix.so -o $@ $< $(LDFLAGS)
 
5. Next, recompiled the library with:

Code: Select all

make clean
make
6. And finally, within your Python scripts, you'll need to update the call that initializes the matrix object to pass the new third "parallel" parameter:

Code: Select all

matrix = Adafruit_RGBmatrix(32, 4, 1)
That seemed to do the trick. I haven't tested yet whether these updates allow the library to support the second or third parallel chains, but those don't apply to the RGB Matrix HAT which only has one output anyway, so just leave the last argument "1" if that's what you're using. I also recommend making the hardware change suggested by Henner (solder a jumper wire between GPIO 4 and 18) and adding the directive #DEFINES+=-DADAFRUIT_RGBMATRIX_HAT_PWM to the Makefile as these enable PWM to reduce flicker.

I'm hoping someone who knows more about GitHub than I can incorporate these updates properly.

User avatar
adafruit2
 
Posts: 22148
Joined: Fri Mar 11, 2005 7:36 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by adafruit2 »

thanx! we'll check it out

there's always a trade-off between "bleeding edge" and "consistency"
for example, most people do not want to do any hardware changes to the HAT, they just want to run some code and get something displaying. for that, the fork works very well.
sure, its old, but thats not necessarily bad, since we have to make sure the code is guaranteed to work with the HAT and the original code base does not out of the gate (and some customers were confused by that)

User avatar
Sarala_18
 
Posts: 10
Joined: Tue May 24, 2016 2:36 am

Re: RGB Matrix Hat - Python with Forked Libraries

Post by Sarala_18 »

What is the basic function of RGB matrix HAT? Does that in anyway contribute to PWM? Can i run my matrix without the HAT?

User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

The HAT does three things. It provides a convenient interface between HUB75 displays and the Raspberry Pi IO connector; it level-shifts the 3.3 volt Pi outputs to 5 volts, which is needed for some HUB75 displays; and it adds a real-time clock for the Pi -- not directly related to RGB matrices, but useful for the Pi to tell time when not connected to a network.

The PWM feature is something Henner Zeller added to his library mid-way through its development. Originally, he simply clocked all the timing through code, and since the Pi is a microprocessor rather than microcontroller, the timing wasn't 100% stable, resulting in flicker. He since modified his library to support a pinout whereby one critical timing pin uses the microprocessor's built-in PWM timing function. This makes the display flicker much less.

He modified his library after Adafruit created the HAT, which means the HAT doesn't support that PWM pin. He has, however, continued to support the Adafruit RGB Matrix HAT in his library, and there are compile switches that can be enabled to continue using the HAT unmodified. Or, if someone is inclined, he has suggested a simple modification to the HAT to connect pin 4 to pin 18, and then change the compile switches in the library so the Adafruit HAT can also share the benefit of the PWM pin.

One does not need to use the HAT. Henner's library mentions some of the other options on his GitHub page.

User avatar
Sarala_18
 
Posts: 10
Joined: Tue May 24, 2016 2:36 am

Re: RGB Matrix Hat - Python with Forked Libraries

Post by Sarala_18 »

I want to glow each LED of my 64x32 RGB matrix statically . Is that possible anyway?

User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

It depends on what you mean "statically".

If you mean each LED with a solid colour (no PWM shading), then simply create your program to use nothing but 100% values for any given colour. You can also configure the matrix library to use a varying amount of PWM e.g. "Bits used for PWM. Something between 1...11" -- setting PWM to 1 would do that.

However, if you mean drive the display without 1/8 or 1/16 scanning, no, that isn't possible. The HUB75 displays are hard-wired to only show two rows at a time. The controller (e.g. Raspberry Pi) has to constantly scan output to the rows over and over, and persistence of vision creates the illusion of a solid screen. To achieve a static screen without scanning, you would need a matrix of LED's based on something like NeoPixels or DotStars whereby each LED has its own driver and can stay on indefinitely. (That would also require 8x to 16x more power.)

User avatar
Sarala_18
 
Posts: 10
Joined: Tue May 24, 2016 2:36 am

Re: RGB Matrix Hat - Python with Forked Libraries

Post by Sarala_18 »

Yes, i was reffering to the scanning mode. I understood that if i want a full display then the scanning comes into work. Faster the scanner, more static it appears. But what if i glow only one LED of some particular row? Does that mean that the LED glows with 100% power?

User avatar
ethur
 
Posts: 17
Joined: Sat Jan 10, 2015 8:51 pm

Re: RGB Matrix Hat - Python with Forked Libraries

Post by ethur »

You could do this, but only if you create your own timing scheme for controlling the output pins (not with with Henner's library). You'd have to directly manipulate the A, B, C (and D, if present) row address lines, clock the the pixel data across to select the LED(s) you want to turn on, stop clocking, and then leave the OE (output enable) line steady to keep it lit up.

I say "LED(s)" in plural because you can do this with any pixels on up to two rows simultaneously, as long as they are half the display height apart. For example, on a 16-row display, it could be any number of pixels on rows 1 and 9, or 2 and 10, or 3 and 11, etc.

Locked
Forum rules
Talk about Adafruit Raspberry Pi® accessories! Please do not ask for Linux support, this is for Adafruit products only! For Raspberry Pi help please visit: http://www.raspberrypi.org/phpBB3/

Return to “Adafruit Raspberry Pi® accessories”