hzeller / rpi-rgb-led-matrix

Controlling up to three chains of 64x64, 32x32, 16x32 or similar RGB LED displays using Raspberry Pi GPIO
GNU General Public License v2.0
3.63k stars 1.15k forks source link

led-parallel Option not working for RGB (16x32) P10 Module #541

Closed lbnshrivas closed 6 years ago

lbnshrivas commented 6 years ago

Hi Hzeller,

Thank you so much for writing such a wonderful library.

I am facing an issue while trying to use this library for my HUB75 16x32 P10 RGB Modules. Would highly appreciate you or anyone in this forum can help me in this regard.

Issue I am facing over here is that I am not able to run the parallel modules through --led-parallel command line Option. I have got the PCB from OSH Park and have mounted the level shifter ICs on that and using those PCBs for lighting up my panels. My RGB panels has A,B & C address lines.

Things works fine if I use --led-parallel = 1 but when when I plug the other panel on my adapter board and give --led-parallel = 2 then 1st panel/chain works fine but the second up doesn't lightup at all.

Please note that I am using the below P10outdoor Transformer for showing the data on my board :

`// / P10outdoor Transformer Canvas / // class P10outdoorTransformer::TransformCanvas : public Canvas { public: TransformCanvas() : delegatee_(NULL) {}

void SetDelegatee(Canvas* delegatee);

virtual void Clear(); virtual void Fill(uint8_t red, uint8_t green, uint8_t blue); virtual int width() const; virtual int height() const; virtual void SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue);

private: Canvas *delegatee_; };

void P10outdoorTransformer::TransformCanvas::SetDelegatee(Canvas* delegatee) { delegatee_ = delegatee; }

void P10outdoorTransformer::TransformCanvas::Clear() { delegatee_->Clear(); }

void P10outdoorTransformer::TransformCanvas::Fill(uint8_t red, uint8_t green, uint8t blue) { delegatee->Fill(red, green, blue); }

int P10outdoorTransformer::TransformCanvas::width() const { return delegatee_->width() / 2; }

int P10outdoorTransformer::TransformCanvas::height() const { return delegatee_->height() * 2; }

void P10outdoorTransformer::TransformCanvas::SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) { int new_x = x; int new_y = y; int xoffset = 8 (x / 8); int yoffset = ((y + 4) % 8) / 4; new_x = x + 8 yoffset + xoffset; newy = (y % 4) + 4 * (y / 8); delegatee->SetPixel(new_x, new_y, red, green, blue); }

// / P10outdoor Transformer / // P10outdoorTransformer::P10outdoorTransformer() : canvas_(new TransformCanvas()) { }

P10outdoorTransformer::~P10outdoorTransformer() { delete canvas_; }

Canvas P10outdoorTransformer::Transform(Canvas output) { assert(output != NULL);

canvas->SetDelegatee(output); return canvas; }`

I have chained around 30 panels on Panel 1 output and things seems to working fine, though with a less refresh rate. But I would like to run the entire board with 3 parallel chains. I think I am missing something on the transformation part but yet not been able to figure out that.

Please find below the demo command which I have used to lightup my panels .

sudo ./demo -D12 --led-rows=8 --led-chain=2 --led-parallel=3 --led-gpio-mapping=regular --led-pwm-lsb-nanoseconds=50 --led-slowdown-gpio=2

Please note that in this, I have written a small text scroll program as an D12 option. Also, on the same lines I have tried option 1 and 2 i.e. -D1 and -D2 in demo program just to negate any possibility to or error in my code but the result remains the same. Option 4 (ColorPulseGenerator) seems to be working fine as in this case both the modules/panels lights up parallely and shows different colors.

Also, as per my understanding, in case if we -led-parallel option then both the modules/panels should show the same data on both the chains at the same time. Please correct me in case if their a gap in my understanding. Going forward I would like to use this parallel mechanism for showing different data on different chains.

Any help in this regard would be highly appreciated. Thanks in advance for all your support and for such a wonder library.

angelogoncalve commented 6 years ago

Try the test doing this:

sudo ./demo -D12 --led-rows=16 --led-chain=1 --led-parallel=3 --led-gpio-mapping=regular --led-pwm-lsb-nanoseconds=50 --led-slowdown-gpio=2 --led-cols=32 --led-row-addr-type=0 --led-multiplexing=1

or with this:

sudo ./demo -D12 --led-rows=16 --led-chain=1 --led-parallel=3 --led-gpio-mapping=regular --led-pwm-lsb-nanoseconds=50 --led-slowdown-gpio=2 --led-cols=32 --led-row-addr-type=2 --led-multiplexing=4

hzeller commented 6 years ago

Your TransformCanvas does not take the parallel panels into account @NeerajShrivastava04 . Have a look how the other multiplexers are doing it in multiplex-transformers.cc

Three might be a good chance that your display actually works without your own transformer, but just simply using one of the built-in transformers, that you can select with --led-multiplexing=1 (or 2, 3, 4..) as @angelogoncalve suggests.

lbnshrivas commented 6 years ago

Hzeller I have used this P10 transformer on the version of the library which didn't had the --led-multiplexing option. Also I have just tested my panels with the existing transformers (StripeTransformer, CheckeredTransformer, SpiralTransformer & ZStripeTransformer)in the latest lib with different -led-row-addr-type but with now result yet. With different in build transformers:

  1. Nothing is being light-up on my second panel
  2. My first panel is also not displaying the text properly.
lbnshrivas commented 6 years ago

I will just try to write my own transformer based on the given examples in the latest lib along with the mapping logic ( P10 transformer) which worked fine earlier.

hzeller commented 6 years ago

Sounds good. Essentially you need to make sure to factor out the parallel display coordinates first and then add them later again.

You might also have a look at the upcoming pixel-mapper branch. There, writing a new Multiplex Mapper is a bit simplified.

lbnshrivas commented 6 years ago

Hi Hzeller,

I have modified the ZStripeTransformer a little bit and have been able to light up my second panel as well (--led-parallel=2) . Please find below the modified ZStripeTransformer SetPixel() method.

` virtual void SetPixel(int x, int y, uint8_t r, uint8_t g, uint8t b) { // Transform from logic coords in panel coords
if (x < 0 || x >= width
|| y < 0 || y >= height_) return; const int chained_panel = x / panelcols; const int parallel_panel = y / panelrows;

const int within_panel_x = x % panel_cols_;
const int within_panel_y = y % panel_rows_;

const int xoffset =8 * (within_panel_x / 8);
const int yoffset = ((within_panel_y+4) % 8) / 4;

const int new_x = within_panel_x  + 8 * yoffset + xoffset;
const int new_y = (within_panel_y % 4) + 4 * (within_panel_y / 8);

const int display_new_x = chained_panel * 2 * panel_cols_ + new_x;
const int display_new_y = parallel_panel * panel_rows_ / 2 + new_y;

delegatee_->SetPixel(display_new_x, display_new_y, r, g, b);           

} `

I have modified the yoffset line to make it ((within_panel_y+4) % 8) / 4; instead of ((within_panel_y) % 8) / 4; But now the problem is that now it has become a 32x32 panel and when I ran the runtext.ppm file with demo option -D1 the top half of my image is being displayed on panel1 and bottom half on panel2. In case if run runtext16.ppm file again with demo option -D1, then image is being displayed only on panel 1 and panel 2 doesn't get light up at all.

sudo ./demo -D1 --led-rows=16 --led-cols=32 --led-chain=1 --led-parallel=2 --led-gpio-mapping=regular --led-pwm-lsb-nanoseconds=150 --led-slowdown-gpio=2 --led-row-addr-type=0 --led-multiplexing=4 --led-scan-mode=1 --led-pwm-bits=4 runtext.ppm

May be there is gap in my understanding but what I was expecting is that both the panel will show the same data at the same time. Can you please guide me and correct my understanding in terms of parallel option. In case if there is an issue with the transformer then can you please guide me a little bit more on that so that I can come up with the exact transformer for my panels.

Thanks in advance for your support and time. Really appreciate your efforts in the regard.

hzeller commented 6 years ago

( just a quick note, currently busy: the way transformers worked just changed this morning when I merged the pixel-mapper branch with master. Now, the way to transform panels is done in lib/multiplex-mappers.cc You will see that it is mostly the same, so it should be possible to do re-do your change there as well.

The confusing with parallel panels should be less, as you really only have to modify the pixel mapping for a single panel, the rest happens automatically. )

angelogoncalve commented 6 years ago

Try this:

new_x = ((x / 8) * 16) + (x % 8)

if y & 4 == 0: new_x += 8

new_y = (y % 4) + 4 * (y / 8)

lbnshrivas commented 6 years ago

Hi Hzeller,

I tried modifying the ZStripeTransformer in multiplex-mappers.c in the latest version of the library but with no luck. Please find below the video link for my display.

https://youtu.be/_dujSjXtrQs

I have modified the MapSinglePanel() method of ZStripeTransformer as below :

` void MapSinglePanel(int x, int y, int matrix_x, int matrix_y) const { static const int tile_width = 8; static const int tile_height = 4;

const int vert_block_is_odd = (((y+4) / tile_height) % 2);  //((y / tile_height) % 2);

const int even_vblock_shift = (1 - vert_block_is_odd) * even_vblock_offset_;
const int odd_vblock_shitf = vert_block_is_odd * odd_vblock_offset_;

//const int xoffset =8 * (x / 8);
//const int yoffset = ((y+4) % 8) / 4;

//*matrix_x = x  + 8 * yoffset + xoffset;
//*matrix_y = (y % 4) + 4 * (y / 8);

*matrix_x = x + (((x+even_vblock_shift)/tile_width) * tile_width) + odd_vblock_shitf;
*matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2));

}`

Over here I have modified the calculation of vert_block_is_odd and have added 4 with the value of before dividing it with tile_height. In case if modify this method in a way which I did for earlier version of lib (un comment the commented code and don't use the even_vblockoffset and odd_vblockoffset ) then my panel shows the data properly but the 2nd panel doesn't light up at all . Please note that I have connected 2 panels in parallel.

Even with the latest version of the library and with garbled data on panel, my 2nd panel is not at all lighting up. I am using the below command for lighting up my panel.

sudo ./demo -D1 --led-rows=16 --led-cols=32 --led-chain=2 --led-parallel=2 --led-gpio-mapping=regular --led-pwm-lsb-nanoseconds=150 --led-slowdown-gpio=2 --led-row-addr-type=0 --led-multiplexing=4 --led-scan-mode=1 --led-pwm-bits=4 runtext16.ppm

@angelogoncalve unfortunately there was no improvement on my panels with your suggestions as well.

Would highly appreciate any help in this regard.

angelogoncalve commented 6 years ago

Try this:

sudo ./demo -D1 --led-rows=16 --led-cols=32 --led-chain=2 --led-parallel=2 --led-gpio-mapping=regular --led-pwm-lsb-nanoseconds=150 --led-slowdown-gpio=2 --led-row-addr-type=2 --led-multiplexing=4 --led-scan-mode=1 --led-pwm-bits=4 runtext16.ppm

lbnshrivas commented 6 years ago

No its not working as well...Same result..

vapiper commented 6 years ago

@NeerajShrivastava04 see the issue #529. Can you make video without any transformers? The filling pattern should be from upper left corner to lower right corner, row by row.

angelogoncalve commented 6 years ago

Try this:

def transformer(x, y, red, green, blue): shift_even_quarter = 0 shift_odd_quarter = 0 if ((y / 4) % 2) == 0: shift_even_quarter = 4 else: shift_odd_quarter = 4

mx = x + ((x + shift_even_quarter) / 8) 8 + shift_odd_quarter my = y % 4 + 4 (y / 8)

return display.SetPixel(mx, my, red, green, blue)

lbnshrivas commented 6 years ago

My panels are working fine with the below modified ZStripeMultiplexMapper

` void MapSinglePanel(int x, int y, int matrix_x, int matrix_y) const { static const int tile_width = 8; static const int tile_height = 4;

const int vert_block_is_odd = (((y+4) / tile_height) % 2);

const int even_vblock_shift = (1 - vert_block_is_odd) * even_vblock_offset_;
const int odd_vblock_shitf = vert_block_is_odd * odd_vblock_offset_;

*matrix_x = x + ((x + even_vblock_shift) / tile_width) * tile_width + odd_vblock_shitf;
*matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2));

} `

So closing this issue.