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

Meta bug: Support HUB08/HUB12 #531

Open hzeller opened 6 years ago

hzeller commented 6 years ago

Hub12 is very similar to Hub75, but the Output-enable has positive level (I think), and of course we can control many more panels with the outputs, as we only need Red or Red/Green and the free GPIO pins can be used for more panels.

So needed to implement

This is a meta bug as this has come up sufficiently often in separate bug entries, but it is easier to collect collected changes on a single one.

Some bugs requesting this are #527 #400 #270 #254 #208 #99

lbnshrivas commented 6 years ago

Hi Hzeller,

I have written a multiplex mapper for HUB12 panel and have run it successfully (so far only on a single panel. Should work multiple panels as well). Will test the same on multiple panels and will let you know. Please note that mine is a 32x16 HUB12 single color panel. My panel is internally divided into four parts (128x4). I have written this mapper by keeping my panel in mind and its working fine. Also, I have enabled the sub-panel flag in lib Makefile.

In case if you feel then you can include this mapper into your library so that others can also use it in case if they have the same panel.

`class P10SingleColorHUB12Mapper : public MultiplexMapperBase { public: P10SingleColorHUB12Mapper(const char *name) : MultiplexMapperBase(name, 4){}

void MapSinglePanel(int x, int y, int *matrix_x, int *matrix_y) const {
    if (y / 4 == 0) {
        *matrix_y = y % 4;
        if (x / 8 == 0) {
            *matrix_x = x + 24;
        } else if (x / 8 == 1) {
            *matrix_x = x + 48;
        } else if (x / 8 == 2) {
            *matrix_x = x + 72;
        } else if (x / 8 == 3) {
            *matrix_x = x + 96;
        }
    } else if (y / 4 == 1) {
        *matrix_y = y % 4;
        if (x / 8 == 0) {
            *matrix_x = x + 16;
        } else if (x / 8 == 1) {
            *matrix_x = x + 40;
        } else if (x / 8 == 2) {
            *matrix_x = x + 64;
        } else if (x / 8 == 3) {
            *matrix_x = x + 88;
        }

    } else if (y / 4 == 2) {
        *matrix_y = y % 4;
        if (x / 8 == 0) {
            *matrix_x = x + 8;
        } else if (x / 8 == 1) {
            *matrix_x = x + 32;
        } else if (x / 8 == 2) {
            *matrix_x = x + 56;
        } else if (x / 8 == 3) {
            *matrix_x = x + 80;
        }

    } else if (y / 4 == 3) {
        *matrix_y = y % 4;
        if (x / 8 == 0) {
            *matrix_x = x;
        } else if (x / 8 == 1) {
            *matrix_x = x + 24;
        } else if (x / 8 == 2) {
            *matrix_x = x + 48;
        } else if (x / 8 == 3) {
            *matrix_x = x + 72;
        }
    }
}

};

static MuxMapperList CreateMultiplexMapperList() { MuxMapperList result = new MuxMapperList();

// Here, register all multiplex mappers from above. result->push_back(new StripeMultiplexMapper()); result->push_back(new CheckeredMultiplexMapper()); result->push_back(new SpiralMultiplexMapper()); result->push_back(new ZStripeMultiplexMapper("ZStripe", 0, 8)); result->push_back(new ZStripeMultiplexMapper("ZnMirrorZStripe", 4, 4)); result->push_back(new CoremanMapper()); result->push_back(new P10SingleColorHUB12Mapper("P10SingleColor"));

return result; } `

lbnshrivas commented 6 years ago

Apart from above changes I have made the following changes as well :

virtual void SendPulse(int time_spec_number) { io_->SetBits(bits_); Timers::sleep_nanos(nano_specs_[time_spec_number]); io_->ClearBits(bits_); }

thetechknight commented 5 years ago

Since quite a few changes are needed to make this adaptable to Hub12/monochrome, Maybe the library needs forked so its rpi-hub12-led-matrix? or rpi-monochrome-led-matrix?

Not sure if these tiles are fast enough to do a good enough greyscale, but if not, then maybe dithering libraries are needed to convert the RGB24bit to R/G/B summing to dithering like they did in the old days of computers.

Sorry just kind of spitballing here.

jawedsoft commented 4 years ago

hello everyone, Thank you Mr. Zeller and everyone else who has contributed to make this library.

I am newbie to the world of rPi.

I came across some very cheap p10 modules with Hub12 interfaces. I am keen to interface it with a 40-pin rPI.

After having gone through a lot of google searches I have finally ended up on this Git Page and this issue(#531). I feel that I am very close to getting the panels to work with the first gen of 40-pin rPI.

I have taken care of the OE, Gnd, A, B, Clock and SCLK pins. I am not able to figure out where to connect the Data pin. For now I have connected it to the R1 pin.

I am getting a lot of gibberish on the screen. But when I scroll the demo, the gibberish scrolls across the screen smoothly.

So to troubleshoot, I have multiple places to look into. Before getting into it, just wanted to know if the changes suggested by Mr. Ibnshrivas are already a part of the library..or do I need to make those changes manually.

regards, Jawed

hzeller commented 4 years ago

yes, data is essentially one of the color pins. The HUB12 are typically only one (red) or two (red/green) colors, so they have much less data lines. I am not sure if they are also segmented in two half-panels as the HUB75, but of not, then there will be only one or two data lines.

My suspicion is that the digital levels for some of the signals are inverted, see above in the thread. Should be fairly straight-forward to add, I just didn't get around to it because I don't own a HUB12 panel, so couldn't really test.

smitkant commented 4 years ago

Apart from above changes I have made the following changes as well :

  • Have changed the Assertion statement in framebuffer.cc:209 to allow 4 rows. Currently its only allowing 8 rows or more than that. Since my panel's internal mapping is 128x4 so I need to make this change as well to allow less than 8 rows.
  • Have made OE high through software by changing the code in gpio.cc

    define PWM_CTL_POLA1 (0<<4) // CH1 Polarity (0=(0=low 1=high) 1=(1=low 0=high)

virtual void SendPulse(int time_spec_number) { io_->SetBits(bits_); Timers::sleep_nanos(nano_specs_[time_spec_number]); io_->ClearBits(bits_); }

@lbnshrivas thanks for you work on this . I tried setting the following as per your comments

Unfortunately am unable to get anything useful working . Just see some leds light up.When I kill the test(ctrl+c) the leds stay on . I have connected the PI3B+ pins directly to the Hub12. Also am using Raspbian on my PI

My panel setup sounds similar to yours . 32x16 (2 panels) with following pins on HUB12 , which I have connected as per the diagram here . I have attached R0,G0 to R1 and G1. Any thoughts would be very helpful

A B C CK ST R0 G0 D


OE GND GND GND GND GND GND

smitkant commented 4 years ago

@hzeller have been trying to understand the library better . you've done a great job with this . Wanted to understand the multiplex mapper a bit better , especially the MapSinglePanel function . Could you point me in teed ruction to understand this and led multiplexing in general a bit better. Thanks a ton.

threiner commented 3 years ago

Hi Hzeller,

I have written a multiplex mapper for HUB12 panel and have run it successfully (so far only on a single panel. Should work multiple panels as well). Will test the same on multiple panels and will let you know. Please note that mine is a 32x16 HUB12 single color panel. My panel is internally divided into four parts (128x4). I have written this mapper by keeping my panel in mind and its working fine. Also, I have enabled the sub-panel flag in lib Makefile.

In case if you feel then you can include this mapper into your library so that others can also use it in case if they have the same panel.

`class P10SingleColorHUB12Mapper : public MultiplexMapperBase { public: P10SingleColorHUB12Mapper(const char *name) : MultiplexMapperBase(name, 4){}

void MapSinglePanel(int x, int y, int *matrix_x, int *matrix_y) const {
  if (y / 4 == 0) {
      *matrix_y = y % 4;
      if (x / 8 == 0) {
          *matrix_x = x + 24;
      } else if (x / 8 == 1) {
          *matrix_x = x + 48;
      } else if (x / 8 == 2) {
          *matrix_x = x + 72;
      } else if (x / 8 == 3) {
          *matrix_x = x + 96;
      }
  } else if (y / 4 == 1) {
      *matrix_y = y % 4;
      if (x / 8 == 0) {
          *matrix_x = x + 16;
      } else if (x / 8 == 1) {
          *matrix_x = x + 40;
      } else if (x / 8 == 2) {
          *matrix_x = x + 64;
      } else if (x / 8 == 3) {
          *matrix_x = x + 88;
      }

  } else if (y / 4 == 2) {
      *matrix_y = y % 4;
      if (x / 8 == 0) {
          *matrix_x = x + 8;
      } else if (x / 8 == 1) {
          *matrix_x = x + 32;
      } else if (x / 8 == 2) {
          *matrix_x = x + 56;
      } else if (x / 8 == 3) {
          *matrix_x = x + 80;
      }

  } else if (y / 4 == 3) {
      *matrix_y = y % 4;
      if (x / 8 == 0) {
          *matrix_x = x;
      } else if (x / 8 == 1) {
          *matrix_x = x + 24;
      } else if (x / 8 == 2) {
          *matrix_x = x + 48;
      } else if (x / 8 == 3) {
          *matrix_x = x + 72;
      }
  }
}

};

static MuxMapperList CreateMultiplexMapperList() { MuxMapperList result = new MuxMapperList();

// Here, register all multiplex mappers from above. result->push_back(new StripeMultiplexMapper()); result->push_back(new CheckeredMultiplexMapper()); result->push_back(new SpiralMultiplexMapper()); result->push_back(new ZStripeMultiplexMapper("ZStripe", 0, 8)); result->push_back(new ZStripeMultiplexMapper("ZnMirrorZStripe", 4, 4)); result->push_back(new CoremanMapper()); result->push_back(new P10SingleColorHUB12Mapper("P10SingleColor"));

return result; } `

Hi, thnaks for making this. is this now implemented in the libary?

hzeller commented 3 years ago

HUB12 has not been implemented in this library (yet? I don't have a HUB12 to test, so we'd need someone who has to send a pull request.)

threiner commented 3 years ago

I have 6 boards here so i ould test it.