changing a library

I made a large, high-intensity (1 watt) LED matrix display using hardware similar to Adafruit's 16x32 matrix display. (My 5 -oot-wide display is currently 8x32 pixels, with expansion coming). I did it this way, using the same HUB75 protocols so that I could use Adafruit's excellent library, RGBmatrixPanel, and their sample programs since I'm weak on programming with C++.

My display works but the (0,0)origin I chose was at top right of my display for ease in PCB layout. Adafruit's 16x32 display has origin at top left. Consequently, text is displayed in mirror image. (I looked at my display in mirror and it displays properly) See attached photo of my display. The ample program I used is Adafruit's "testshapes.ino" sketch where they write 16x32 in various colors to the display, on the top 8 rows.

So...my question, which I've posed to Adafruit, is "Can I change the library .cpp file to reflect a different origin or otherwise display my text properly?" Bouncing balls and smiley faces display properly of course since they don't care about starting points. It's only the text, static or scrolling that is affected.

I've played around with the ShiftOut command with other projects and note how it allows for MSB or LSB starts.

Take a look at the setRotation function - might be what you need, or at least give a hint at how to do it.

To answer your question- yes.
But you would need a lot of knowledge of C++ to do so.

Without any schematic or program code, we would only be guessing at a solution.

I am surprised that you got this far into the build without testing the code on the panels. It may be easier to rewire the LED matrix so that top-left is top-right? I don't know- there's no schematic.

An origin of top-right is quite unusual.

here is an option.
create a new tab.
copy and paste their library in that tab.
change how you call it
change the code in the library as you desire

What that does is to eliminate any revisions of that library from effecting your sketch and also gives you the ability to modify it as if it were your code.

it also makes it so other libraries of the same name do not mess you up.

Can you produce a wrapper function for each of the library functions you call that use coordinates, and within each function in your wrapper simply reverse the x ordinate?

I had a big long explanation in response to some of the replies above, and added photos and schematics, but when I posted, I got an error that "attachments were too large" and I lost everything. One of my photos hadn't been resized. Attached are schematics and one photo. The photo is of the logic board, two required for my display because they hold the DM13 and 74HC540s. First board has the Atmega and 74LS138 decoder, second board does not.
I've attached the Arduino sketch called scrolltextFE.ino which is my chopped-down version of Adafruit's demo program called "testshapes16x32".

MatrixLogic328.pdf (128 KB)

pixelboard.pdf (39.9 KB)

scrolltextFE.ino (1.42 KB)

In response to the replies:

  • Bill...what is setRotation function?

  • I don't know what a wrapper is.

  • The 74HC540's have inputs on left and outputs on right so it was logical to have the connections from the logic board (photo) to the pixel boards as shown. o/p zero is at top right of the chip, making the far right chip origin 0. It was a PCB design reason. I actually wanted (0,0) to be at the bottom left, like it is on a math x-y chart.

Create your own class (in your .ino file) inherited from the Adafruit class. Then you can tweak bits without messing up the original. And, you will have all of the original still running in yours.

-jim lee

I had a look at the library, and it depends on adafruit_GFX.h for display of characters. It has a drawPixel() function that drop in on the virtual void function in adafruit_GFX.h
Looking at the whole thing i think that setRotation() should modify the variable rotation

void RGBmatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t c) {
  uint8_t r, g, b, bit, limit, *ptr;

  if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height))
    return;

  switch (rotation) {
  case 1:
    _swap_int16_t(x, y);
    x = WIDTH - 1 - x;
    break;
  case 2:
    x = WIDTH - 1 - x;
    y = HEIGHT - 1 - y;
    break;
  case 3:
    _swap_int16_t(x, y);
    y = HEIGHT - 1 - y;
    break;
  }

and i think it should be set to '2'
setRotation is part of adafruit_GFX

void Adafruit_GFX::setRotation(uint8_t x) {
  rotation = (x & 3);
  switch (rotation) {
  case 0:
  case 2:
    _width = WIDTH;
    _height = HEIGHT;
    break;
  case 1:
  case 3:
    _width = HEIGHT;
    _height = WIDTH;
    break;
  }
}

and does exactly that.

Having looked at the code, I don't think a simple wrapper will work, so I would go with WildBill /Deva_Rishi and try that method.

I tried the setRotation function. Looked promising but did not work.
//matrix.setRotation(0);//L-R mirror image
//matrix.setRotation(1);//first panel only bottom to top mirror
//matrix.setRotation(2);//first panel only bottom to top but readable
//matrix.setRotation(3);//last panel top to bottom mirror

Maybe I didn't do it right? The statements above were in Setup.

I too think that the setting should be two. But in the library function drawPixel that deva_rishi posted, the case for 2 flips x and y. You only need to flip x, so comment the other bit out.

Wildbill, Can I use the function by deva_rishi "as-is?" do I just add it to the code? What parameters, if any, do I have to pass it? I tried just pasting the function in and running, but not sure if I had it right.

Like I said, I'm weak on C++. (Very strong on Motorola Assembler though...not a help here).

You are already using that code - it's in one of the Adafruit libraries. I suggest that you find that function and make the change above.

Maybe I didn't do it right? The statements above were in Setup.

You did it right, i just didn't quite give the proper instruction. I already thought that setRotation() was not the proper name for the function but it is.

My 5 -oot-wide display is currently 8x32 pixels, with expansion coming)

That explains why part of the display is lost in rotation = 2.

so that I could use Adafruit's excellent library, RGBmatrixPanel, and their sample programs since I'm weak on programming with C++.

For future reference, RGBmatrixPanel just deals with the hardware specific part, it is actually adafruit_GFX that does all the character & bitmap generation and the scroll functions etc. Looking at the project that you've created, i would actually just use WS2812's and create a drawPixel() function in a library that includes adafruit_GFX (some already exist that do it this way, but more so you get how this actually works)

I too think that the setting should be two. But in the library function drawPixel that deva_rishi posted, the case for 2 flips x and y. You only need to flip x, so comment the other bit out.

absolutely, well that bit i missed, really you can do whatever you want with the coordinates, but rotation needs to be either 0 or 2 or the width & height values are swapped. Actually i suggest you leave rotation as '0' , but add a line that inverts the x coordinate (as it is done in case '2') either just before or just after the switch-case

x = WIDTH - 1 - x; // just add this
switch (rotation) {
  case 1:
    _swap_int16_t(x, y);
    x = WIDTH - 1 - x;
    break;
  case 2:
    x = WIDTH - 1 - x;
    y = HEIGHT - 1 - y;
    break;
  case 3:
    _swap_int16_t(x, y);
    y = HEIGHT - 1 - y;
    break;
  }

So your rotation function should still work as originally intended. (here i am not 100% sure if the line should be before or after, but i think before) Of course to prevent an update to the library or the IDE from breaking your code, you should rename it and put it in your sketches/libraries folder (and change the ifdef statement at the very beginning of the .h file that prevent dual instances of the library from being compiled)

Thanks a lot Deva_Rishi...lots to digest for junior programmer like me. I'll try these things.

I've been trying lots of stuff, different libraries. There is even one called HUB75 (the protocol I'm using) but no examples. I've been at this for over a week. Graphics display okay, my own programs display okay. All I need to do is get scrolling text to display and to do that with Adafruit GFX library, need to define the origin.

I'll get back to this forum when it works!

lots to digest for junior programmer like me.

Hmm maybe i made it sound overcomplicated. It is just a few steps.

  • copy the RGBMatrixPanel library to you sketches/libraries folder and give the folder a new name say MyRGBmatrixPanel (if it isn't already there, then just copy it to a folder with the new name )
  • rename the .h & .cpp files to this new name
  • Open the .h file using notepad++ and modify it so these lines at the beginning reflect it's new name
#ifndef RGBMATRIXPANEL_H
#define RGBMATRIXPANEL_H
  • Open the .cpp file and change the include to the .h file#include "RGBmatrixPanel.h"to reflect it's new name. And add the line in the void drawPixel() function that swaps the direction of the x-coordinate.- Now you can refer to this 'new' library with it's new name, and if updates come in for the original, you won't lose your modifications.

Deva_Rishi,
Okay, I understand now...had to make those changes in the library. I did everything noted and named RGB_Matrix_Panel to RGB_Matrix_PanelFE (the FE is how I identify myself in programs) in the locations you specified.
And of course I change the #include in the sketch to fetch MY library. (Note the library is called RGB_Matrix-Panel, but inside the .h and .cpp files the underscores are not there).
But, when I try to compile I get errors:
Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"

scrolltext_8x32TestFE:19:1: error: 'RGBmatrixPanelFE' does not name a type; did you mean 'RGBmatrixPanel'?

RGBmatrixPanelFE matrix(A, B, C, CLK, LAT, OE, false);//must be true, flickering otherwise

^~~~~~~~~~~~~~~~

RGBmatrixPanel

scrolltext_8x32TestFE:28:28: error: 'matrix' was not declared in this scope

int16_t textX = matrix.width(),

^~~~~~

D:\ArduinoSketch\ProjectsDoneDoing\MatrixDM13\scrolltext_16x32FE\scrolltext_8x32TestFE\scrolltext_8x32TestFE.ino:28:28: note: suggested alternative: 'atoi'

int16_t textX = matrix.width(),

^~~~~~

atoi

D:\ArduinoSketch\ProjectsDoneDoing\MatrixDM13\scrolltext_16x32FE\scrolltext_8x32TestFE\scrolltext_8x32TestFE.ino: In function 'void setup()':

scrolltext_8x32TestFE:35:3: error: 'matrix' was not declared in this scope

matrix.begin();

^~~~~~

D:\ArduinoSketch\ProjectsDoneDoing\MatrixDM13\scrolltext_16x32FE\scrolltext_8x32TestFE\scrolltext_8x32TestFE.ino:35:3: note: suggested alternative: 'atoi'

matrix.begin();

^~~~~~

atoi

D:\ArduinoSketch\ProjectsDoneDoing\MatrixDM13\scrolltext_16x32FE\scrolltext_8x32TestFE\scrolltext_8x32TestFE.ino: In function 'void loop()':

scrolltext_8x32TestFE:46:3: error: 'matrix' was not declared in this scope

matrix.fillScreen(matrix.Color333(1,0,1));// R,G,B 7 is max

^~~~~~

D:\ArduinoSketch\ProjectsDoneDoing\MatrixDM13\scrolltext_16x32FE\scrolltext_8x32TestFE\scrolltext_8x32TestFE.ino:46:3: note: suggested alternative: 'atoi'

matrix.fillScreen(matrix.Color333(1,0,1));// R,G,B 7 is max

^~~~~~

atoi

scrolltext_8x32TestFE:54:18: error: 'textMin' was not declared in this scope

if((--textX) < textMin) textX = matrix.width();

^~~~~~~

D:\ArduinoSketch\ProjectsDoneDoing\MatrixDM13\scrolltext_16x32FE\scrolltext_8x32TestFE\scrolltext_8x32TestFE.ino:54:18: note: suggested alternative: 'textX'

if((--textX) < textMin) textX = matrix.width();

^~~~~~~

textX

scrolltext_8x32TestFE:55:3: error: 'hue' was not declared in this scope

hue += 7;//prints red only if commmented out, def=7

^~~

Multiple libraries were found for "Adafruit_GFX.h"

Used: D:\ArduinoSketch\libraries\Adafruit_GFX_Library

Not used: D:\ArduinoSketch\libraries\Adafruit-GFX-Library-master

Multiple libraries were found for "SPI.h"

Used: D:\ArduinoSketch\libraries\SPI

Not used: D:\ArduinoSketch\libraries\SPI-master

Not used: C:\Users\bobfo\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries\SPI

exit status 1

'RGBmatrixPanelFE' does not name a type; did you mean 'RGBmatrixPanel'?

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

SUCCESS!!
I changed all instances of RGBmatrixPanel to RGBmatrixPanelFE in the .cpp and .h files.

I tried rotation 0....no change
Rotation 2: Scrolling to the left, normal reading. IT WORKS!

Thanks one hell of a lot.

I changed all instances of RGBmatrixPanel to RGBmatrixPanelFE in the .cpp and .h files.

That is one way, the other is only including the new name, but leaving the object name the same in the sketch. 'RGBmatrixPanelFE' does not name a type; did you mean 'RGBmatrixPanel'?basically, yes you did !
anyway

Rotation 2: Scrolling to the left, normal reading. IT WORKS!

Great !