marcmerlin / FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos

Various Arduino 2D demos that work all hardware backends supported by FrameBuffer::GFX
http://marc.merlins.org/perso/arduino/post_2020-03-16_Framebuffer_GFX_-Choosing-between-its-3-2D-APIs_-FastLED-XY_-NeoMatrix_-and-LEDMatrix_-and-detail-of-its-many-supported-hardware-backends.html
95 stars 19 forks source link

Documentation improvements #2

Closed liquid-light closed 5 years ago

liquid-light commented 5 years ago

Hej

I'm following your work since quite some time now. I'm very impressed about the progress and started (at least tried to start) to implement your code into some simpler test project. Unfortunately it's very difficult to find the right way to use your lib's.

Originally I've used FastLED together with LEDMatrix and LEDText from AaronLiddiment. But I see a lot of opportunity's by using Neomatrix together with LEDMatrix. Obviously the bigger font library of the Adafruit GFX library.

However, from my perspective there is no clear path that shows how to use all these API's together. It seems everything you offer is naturally grown. And this is absolutly natural in my eyes. But I would be really happy to see some simpler examples and documentation in order to understand fully how your combination of all these library's needs to be implemented in order to secure that they work as they are intended to work. Right now everything is quite confusing. (Even though it looks very promising)

marcmerlin commented 5 years ago

https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/master/LEDMatrix/NeoMatrix_LEDMatrix/NeoMatrix_LEDMatrix.ino is a basic example of using both APIs at the same time.

All the magic is now in https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/master/neomatrix_config.h Assuming you have a neomatrix, make sure you set

define M16BY16T4 or something equivalent (make up your own size)

define NEOPIXEL_MATRIX

Then go here https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/814d456638c1766c4176bcf3f9f0a99f18af22a0/neomatrix_config.h#L365 and and modify the variables accordingly. the only problem with LEDMatrix is this line https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/814d456638c1766c4176bcf3f9f0a99f18af22a0/neomatrix_config.h#L385 which is a pain to get right (you have to put - in the right place and it can be a fair amount of trial and error) Then you have to redefine here https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/814d456638c1766c4176bcf3f9f0a99f18af22a0/neomatrix_config.h#L396 which is its own way to defining how things are tiled.

The way things work is that both libraries write independently in the ledmatrix array that is created inside the LEDMatrix library (and that's why they both have their own mapping function). It's unfortunate that it works that way, but both were written independently and I just provide the glue to allow using both at the same time.

Does that help?

liquid-light commented 5 years ago

Wow, that's a fast reply. Thanks for the information's, but I found my way already through it before I posted. That was the reason why I posted. Btw.: I'm using APA102 LED's with a teensy 3.2. The LED's are glued together in a Horizontal ZigZag way. So no out-of-the-box matrix. I even don't know what the "M16BY16T4 " is or what it stands for.

I can totally understand that it's quite challenging to write some kind of "Standard operation procedure" (i.e. in the Github wiki system like AaronLiddiment LEDMatrix) for something that "just" glues different library's together. Especially if even these library's are not very well documented in some areas. And I think it would be (probably) the best to build a new library from scratch that combines these library's instead of dealing with the drawbacks by gluing them together. But this is definitely far away from my competences. And I guess most others have no time or other, more important, things to do.

The point is : After I've used your stuff for some time now I see the potential and I think that's the right track to a new standard. But I'm worried that it never get's there if it's so difficult to understand how to use it ;)

However (again) : I'm really happy that you've put all the effort into making these thing's even possible and I'll follow your progress anyways. ;) Thank you!

liquid-light commented 5 years ago

Ok, now it seems that I'm even more confused. I've used your original NeoMatrix_LEDMatrix example. This examples uses #include "config.h" and it works. The link (above) to your more recent example uses #include "neomatrix_config.h" Even if I #define LEDMATRIX at the very top I just get erros like : neomatrix_config.h: 67:82: fatal error: SmartLEDShieldV4.h: No such file or directory compilation terminated

If I remove these lines :

include // if you're using SmartLED Shield V4 hardware

include

include

I get the error : neomatrix_config.h: 95:2: error: #error Unknown architecture (not ESP32 or teensy 3.5\6)

error Unknown architecture (not ESP32 or teensy 3.5\6)

Further down the road I get this error : `neomatrix_config.h: 102:21: error: 'MATRIX_TILE_WIDTH' was not declared in this scope const uint16_t mw = MATRIX_TILE_WIDTH * MATRIX_TILE_H

neomatrix_config.h: 103:21: error: 'MATRIX_TILE_HEIGHT' was not declared in this scope const uint16_t mh = MATRIX_TILE_HEIGHT * MATRIX_TILE_V

neomatrix_config.h: 117:33: error: 'SMARTMATRIX_OPTIONS_NONE' was not declared in this scope see http*: docs.pixelmatix.com\SmartMatrix for options

neomatrix_config.h: 118:42: error: 'SM_BACKGROUND_OPTIONS_NONE' was not declared in this scope const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE)

neomatrix_config.h: 120:29: error: expected constructor, destructor, or type conversion before '(' token SMARTMATRIX_ALLOCATE_BUFFERS(matrixLayer, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions)

neomatrix_config.h: 121:38: error: expected constructor, destructor, or type conversion before '(' token SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions)

neomatrix_config.h: 125:12: error: 'MATRIX_TILE_WIDTH' was not declared in this scope cLEDMatrix<MATRIX_TILE_WIDTH, -MATRIX_TILE_HEIGHT, HORIZONTAL_MATRIX

neomatrix_config.h: 125:32: error: 'MATRIX_TILE_HEIGHT' was not declared in this scope cLEDMatrix<MATRIX_TILE_WIDTH, -MATRIX_TILE_HEIGHT, HORIZONTAL_MATRIX

neomatrix_config.h: 126:52: error: template argument 1 is invalid MATRIX_TILE_H, MATRIX_TILE_V, HORIZONTAL_BLOCKS> ledmatrix(false)

neomatrix_config.h: 126:52: error: template argument 2 is invalid

neomatrix_config.h: 138:1: error: 'SmartMatrix_GFX' does not name a type SmartMatrix_GFX *matrix = new SmartMatrix_GFX(matrixleds, mw, mh, show_callback)

neomatrix_config.h: In function void show_callback()

neomatrix_config.h: 144:5: error: 'backgroundLayer' was not declared in this scope backgroundLayer.swapBuffers(true)

neomatrix_config.h: 147:5: error: 'matrix' was not declared in this scope matrix->newLedsPtr(matrixleds)

neomatrix_config.h: 149:15: error: request for member 'SetLEDArray' in 'ledmatrix', which is of non-class type 'int ledmatrix.SetLEDArray(matrixleds)

neomatrix_config.h: In function int XY2(int, int, bool)

neomatrix_config.h: 516:12: error: 'matrix' was not declared in this scope return matrix->XY(x,MATRIX_HEIGHT-1-y)

neomatrix_config.h: In function uint16_t XY(uint8_t, uint8_t)

neomatrix_config.h: 520:12: error: 'matrix' was not declared in this scope return matrix->XY(x,y)

neomatrix_config.h: In function void show_free_mem()

neomatrix_config.h: 530:5: error: 'Framebuffer_GFX' has not been declared Framebuffer_GFX*: show_free_mem()

neomatrix_config.h: In function void matrix_setup(int)

neomatrix_config.h: 549:5: error: 'matrixLayer' was not declared in this scope matrixLayer.addLayer(&backgroundLayer)

neomatrix_config.h: 549:27: error: 'backgroundLayer' was not declared in this scope matrixLayer.addLayer(&backgroundLayer)

neomatrix_config.h: 658:5: error: 'matrix' was not declared in this scope matrix->begin()

neomatrix_config.h: 677:15: error: request for member 'DrawLine' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawLine (0, 0, ledmatrix.Width() - 1, ledmatrix.Height() - 1, CRGB(0, 255, 0))

neomatrix_config.h: 677:41: error: request for member 'Width' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawLine (0, 0, ledmatrix.Width() - 1, ledmatrix.Height() - 1, CRGB(0, 255, 0))

neomatrix_config.h: 677:64: error: request for member 'Height' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawLine (0, 0, ledmatrix.Width() - 1, ledmatrix.Height() - 1, CRGB(0, 255, 0))

neomatrix_config.h: 678:15: error: request for member 'DrawPixel' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(0, 0, CRGB(255, 0, 0))

neomatrix_config.h: 679:15: error: request for member 'DrawPixel' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(ledmatrix.Width() - 1, ledmatrix.Height() - 1, CRGB(0, 0, 255))

neomatrix_config.h: 679:35: error: request for member 'Width' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(ledmatrix.Width() - 1, ledmatrix.Height() - 1, CRGB(0, 0, 255))

neomatrix_config.h: 679:58: error: request for member 'Height' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(ledmatrix.Width() - 1, ledmatrix.Height() - 1, CRGB(0, 0, 255))

neomatrix_config.h: 681:15: error: request for member 'DrawLine' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawLine (ledmatrix.Width() - 5, 4, 4, ledmatrix.Height() - 5, CRGB(128, 128, 128))

neomatrix_config.h: 681:35: error: request for member 'Width' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawLine (ledmatrix.Width() - 5, 4, 4, ledmatrix.Height() - 5, CRGB(128, 128, 128))

neomatrix_config.h: 681:64: error: request for member 'Height' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawLine (ledmatrix.Width() - 5, 4, 4, ledmatrix.Height() - 5, CRGB(128, 128, 128))

neomatrix_config.h: 682:15: error: request for member 'DrawPixel' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(ledmatrix.Width() - 5, 4, CRGB(255, 64, 64))

neomatrix_config.h: 682:35: error: request for member 'Width' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(ledmatrix.Width() - 5, 4, CRGB(255, 64, 64))

neomatrix_config.h: 683:15: error: request for member 'DrawPixel' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(4, ledmatrix.Height() - 5, CRGB(64, 64, 255))

neomatrix_config.h: 683:38: error: request for member 'Height' in 'ledmatrix', which is of non-class type 'int ledmatrix.DrawPixel(4, ledmatrix.Height() - 5, CRGB(64, 64, 255))`

liquid-light commented 5 years ago

ok, If I set this at the very top of my sketch :

define M16BY16T4

define NEOPIXEL_MATRIX

define LEDMATRIX

It compiles (after I adjusted some variable names in the neomatrix_config.h in order to secure that they fit to my existing sketch) I've also added this line : FastLED.addLeds<APA102, 11, 13, BGR, DATA_RATE_MHZ(8)>(matrixleds, NUMMATRIX).setCorrection(TypicalLEDStrip); because I use (as mentioned) APA102 instead of WS2812B And I needed to reduce the datarate. Otherwise it doesnt work because of the long cable.

Now it compiles without errors. It still doesnt show anything, but I think I'll solve this as well somehow. Hopefully

marcmerlin commented 5 years ago

Ok, a few comments and answers. 1) documentation. Yeah, it takes a long time to write and often becomes out of date the day after you write it :) I gave some basic pointers but ultimately the documentation is the code.

2) M16BY16T4 is a name I made up for 16x16 matrices connected in tiled fashion. I only gave you that pointer because you can copy that section of code, call it M32BY32Z for a straight 32x32 zigzag, and then you change the init of both libs to match your wiring. If you haven't gotten FastLED::NeoMatrix to init on your matrix, you should do this first.

3) merging both libs, honestly I won't be doing this. LEDMatrix doesn't really offer much that NeoMatrix doesn't, so it's rare that anyone will run both libs at the same time. I gave some code that shows how to do it, but I don't have a plan to merge them, that'd be a fair amount of work. If you want to contribute LEDMatrix methods to Framebuffer::GFX, I would consider it, but I won't be the one doing it due to total lack of need :)

4) Yeah, the old NeoMatrix_LEDMatrix was more self contained, quicker to read but it didn't work on other backends last SmartMatrix or TFT screens, which is what neomatrix_config adds.

5) fatal error: SmartLEDShieldV4.h is because you are missing defines in neomatrix_config (or outside before including it) to select what driver you want to use . Go back to my first reply where I recommend

define M16BY16T4 or something equivalent (make up your own size)

define NEOPIXEL_MATRIX <- you are missing this I guess

6) neomatrix_config.h: 95:2: note that the code can't be plug and play and just know what your config is, you have to edit it to tell it what your config is. The #error is there exactly to tell you you have to write your own code there :)

7) LEDs not lighting up, after addleds, try matrixleds[0] = CRGB::Green . As long as that part doesn't work, you can't move forward. If it does work, you should be able to do matrix->drawPixel( ...

marcmerlin commented 5 years ago

Oh, and generally please try to anticipate what I may ask you and try stuff, or tell me what you did try to fix your error and why it didn't work, or why the current situation makes no sense. The config has to be modified, just running it through the compiler and pasting how it errors, is not very helpful. Ideally you should be able to figure out compiler/define errors and address them :)

liquid-light commented 5 years ago

Finally it's working. Sorry, I was quite frustrated at the time I wrote the last 2 posts.

and try stuff>

Believe me, that's something I always do. But sometimes it's good to get some external input to change the perspective. Finally I found the issue why nothing happened even though there was no compile error or warning. In the original LEDMatrix system I had to define my matrix like this : MATRIX_WIDTH 40 MATRIX_HEIGHT -9

In your system I can't do it this way. Instead I have to adjust this line : FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(matrixleds, MATRIX_TILE_WIDTH, MATRIX_TILE_HEIGHT, MATRIX_TILE_H, MATRIX_TILE_V, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG + NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_PROGRESSIVE);

This is new for me because I've never worked with the original NEOMATRIX. At the top I've included these lines now : `#define M16BY16T4

define NEOPIXEL_MATRIX

define LEDMATRIX

define DISABLE_MATRIX_TEST`

One other mistake I made was using the Arduino IDE. I've switched to Visual Studio. Visual Studio highlights the areas which are in use in the neomatrix_config.h if I define different things at the top of my sketch. The other areas are grey. This way it's way easier to follow all these if's and else if's in the neomatrix_config.h.

M16BY16T4 is a name I made up for 16x16 matrices connected in tiled fashion.

Well, that's the point. I can't find any information what this is. And this "M16BY16T4" looks like a typical way to name a chip or display controller (SSD1331, ILI9341, ESP8266, WS2812B, APA102C...) Anyway, now I know what it is.

And the point of this Issue was not to get support for my particular problem. At least not in the first place. ( I thank you very much of course anyway's) The point was to find a way to improve the transparency of your whole system in order to make it easier to understand for people who use it the first time.

So maybe, as soon as I've finished my actual project, I could help with some small, basic and simple "HowTo's". Just to get things rolling for people who are new to your Neomatrix-FastLED-LEDMatrix-AdafruitGFX-FramebufferGFX system.

Btw. Now that G+ is closed, is there another way (except Github) to get in contact? Did you move to Reddit as well?

liquid-light commented 5 years ago

I realized that changing one of the Matrix width or Height values to a negative value results in an overflow because in your version these variables are now uint16_t. Originally they were int16_t. That's the reason why it was possible to change the x0 y0 position by using negativ and positiv values. In NEOMATRIX this is done by this line : https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/814d456638c1766c4176bcf3f9f0a99f18af22a0/neomatrix_config.h#L396-L399

Unfortunately this doesn't influence the behavior of existing LEDMatrix code. In order to make this work I've changed these lines : https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/814d456638c1766c4176bcf3f9f0a99f18af22a0/neomatrix_config.h#L368-L376

to these : `const uint16_t MATRIX_TILE_WIDTH = 16; // width of EACH NEOPIXEL MATRIX (not total display) const int16_t MATRIX_TILE_HEIGHT= -16; // height of each matrix const uint8_t MATRIX_TILE_H = 2; // number of matrices arranged horizontally const uint8_t MATRIX_TILE_V = 2; // number of matrices arranged vertically

// Used by NeoMatrix const uint16_t mw = MATRIX_TILE_WIDTH MATRIX_TILE_H; const uint16_t mh = (MATRIX_TILE_HEIGHT -1) MATRIX_TILE_V; const uint32_t NUMMATRIX = mwmh;`

Of course I also had to change the MATRIX_TILE_HEIGHT in the FastLED_NeoMatrix defintion later and multiply it by -1.

It seems Neomatrix expects the x0 y0 in the top left corner in order to display text correct. LEDMatrix instead needs it in the bottem right in my particular case. otherwise all my animations are wrong. But I guess this is just my special situation

Edit: I guess you can close this issue. It's quite off topic now ;)

marcmerlin commented 5 years ago

MATRIX_HEIGHT -9 => you really don't want this. Everything assumes positive values. Please add the - in the LEDMatrix definition in front of the variable.

M16BY16T4 and naming, yes it's maybe not super obvious depending on your experience with more complex include files. If you'd like to submit a patch with more comments and/or a howto, please feel free. Believe it or not, but I already spent days writing blog entries, READMEs and docs for my libraries. Doesn't mean it's enough, but I already spent non trivial time on it :)

"Neomatrix expects the x0 y0 in the top left corner ", no it does not. It's up to you to define it. https://learn.adafruit.com/adafruit-neopixel-uberguide/neomatrix-library#tiled-matrices-18-16 https://github.com/marcmerlin/FastLED_NeoMatrix/blob/master/examples/matrixtest/matrixtest.pde#L10

Hope this helps and feel free to send me doc/comment updates where you think they are useful, it's a great way to contribute to projects :)

marcmerlin commented 5 years ago

actually, I'll add one last bit: if I were you I wouldn't go out of my way to use both libs unless you really have to. I supported this because I had to in a combined demo that included code I didn't write, but if I were to write code, I wouldn't use LEDMatrix at all. The only reason to use it IMO is if you want its fancy color wavy font support, or if you want its sprite support. If not, stick with Adafruit::GFX and FastLED directives.

marcmerlin commented 5 years ago

@liquid-light please check the new neomatrix_config.h , improved it to make it easier to read while adding ST7735 support. Thanks for your feedback which helped with this.