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.59k stars 1.15k forks source link

Qiang-Li Q3 64x64 panel, now works. #942

Open rttgnck opened 4 years ago

rttgnck commented 4 years ago

I have spent some time figuring out why my ABCDE Q3F32v4.1 Qiang-Li 64x64 panel does not work correctly with the Adafruit Matrix Hat. I had not tried it direct wire.

After much time I have come up with an address type for the panel that works based on the ShiftRegisterRowAddressSetter.

Below you will find the rowsetter code that I found works for this specific panel. I need to git pull a clean copy of the project and make the appropriate changes to submit a pull request, but I thought I post this here first in case anyone had any suggestions.

class QiangliQ3SixtyFourRowAddressSetter : public RowAddressSetter { public: QiangliQ3SixtyFourRowAddressSetter(int double_rows, const HardwareMapping &h) : doublerows(double_rows), rowmask(h.e | h.d | h.c | h.b | h.a), clock(h.a), data(h.b), bk(h.c), en1(h.d), en2_(h.e),
lastrow(-1) { } virtual gpio_bits_t need_bits() const { return rowmask; }

virtual void SetRowAddress(GPIO *io, int row) { row = row+1; gpio_bits_t ra = 0;

  if (row == last_row_) return;

  // so far I have found that these either turn on or off the row, switch Set and Clear to turn off the rows
  // io->SetBits(bk_);
  // io->ClearBits(bk_);

  io->SetBits(clock_);

  if (row % 8 == 0) {
     io->SetBits(data_);
  } else {
     io->ClearBits(data_);
  }

  io->ClearBits(clock_);
  if (row >= 1 && row <= 8) {
     io->ClearBits(en1_);
     io->ClearBits(en2_);
  }
  if (row >= 9 && row <= 16) {
     io->SetBits(en1_);
     io->ClearBits(en2_);
  }
  if (row >= 17 && row <= 24) {
     io->ClearBits(en1_);
     io->SetBits(en2_);
  }
  if (row >= 25 && row <= 32) {
     io->SetBits(en1_);
     io->SetBits(en2_);
  }
  last_row_ = row;

}

private: const int doublerows; const gpio_bits_t rowmask; const gpio_bitst clock; const gpio_bitst data; const gpio_bitst bk; const gpio_bitst en1; const gpio_bitst en2; int lastrow; };

hzeller commented 4 years ago

Are you working on a pull request for this ?

rttgnck commented 4 years ago

I had taken a break on that project for some other stuff. But I will get to it this weekend.

darrenmlouw commented 4 years ago

Could you explain the timings for the latch and enable line, or anything out of the ordinary with the HUB75E interface.

rttgnck commented 4 years ago

This was found through trial and error mostly. I didn't have to change/add anything outside of this. It's still a bit flickery and changing the usual settings for dither don't help much, and it does still have some partially lit pixels when certain others are activated which nanoseconds helped a bit. Now it's still an ABCDE panel, so only the --led-row-addr-type was altered. It's not ABCDE applies directly to the row. It has Sn5266 drivers where A is clk, B is data, C I found just turns on or off the row. D is EN1, E is EN2. D and E define which of 1-8, 9-16, 17-24, 25-32. B isn't data data, it tells when to do the switching for each 8-sets SP5266. It's basically another version of a ShiftRowAddressSetter.

Like I said though, I didn't look at the logic on the CLK or Latch pin on the HUB75E port. It's still partly direct address row setter and acts as such, but by 8s which is why if you don't toggle B each 8 it won't light up the next

  1. It's possible the Hubs CLK or lat pin may help with the flicker though, or further analysis of the C pin. I do have access to a simple 8-pin logic analyzer which I did use a bit in this. I do also have the CLK and LAT logged, but didn't look at them after I got all the rows lighting up in order with no duplicates.
darrenmlouw commented 4 years ago

So should pin A be connected to the same clock as the clk on the hub75e

darrenmlouw commented 4 years ago

So I found the datasheet for the chip, how would one turn row1/out1 on the Iterate to row2/output2 and so out? Open folder Downloads

darrenmlouw commented 4 years ago

Sorry my spelling was extremely bad, was meant to say “how would one turn row1/out1 on, then Iterate to row2/output2 and so on using B/data?

rttgnck commented 4 years ago

All I did was replace the class ShiftRegisterRowAddressSetter in the framebuffer.cc file with the above code and remade the library with sudo make from the lib folder. Then started the panel with sudo ./demo -D0 --led-rows=64 --led-cols=64 --led-gpio-mapping=adafruit-hat --led-row-addr-type=1. You can alrenatively use the DirectRowAddressSetter and replace with row lookup table. I don't have an algorithm for bitwise operations to create one, but I do have a manual table that can be used.

As far as I can tell, the "clock" pin used in this address setter class is NOT the same clk pin as the HUB75E port. I do not have the panel connected any longer to a logic analyzer. But I believe the clock pin (A) for this address setter merely defines when to change to the next 1 of the 8 rows, data_ (B) tells the panel when to switch to the next 8 of 32, and D and E set which sets of 8 are actually lit up. And for C I have not nailed down its function, but appears to be something like enable/disable the lit state of each line being called in the sets of 8.

Try replacing the ShiftRegisterRowAddressSetter with my QiangliQ3SixtyFourRowAddressSetter code (github didn't format it correctly you need all of the originally pasted code, if you use QiangliQ3SixtyFourRowAddressSetter then you will need to edit the switch in framebuffer.cc InitGpio function with a new one for QiangliQ3SixtyFourRowAddressSetter or reset the class name to ShiftRegisterRowAddressSetter.)

rttgnck commented 4 years ago

To address you most recent comment, B does not set the row, it tells the panel when to switch to the next 8. I believe A changes the row.

I am also using the Adafruit Matrix Bonnet and this panel may work completely different without it, I have not done a direct wire testing.

darrenmlouw commented 4 years ago

Thank you very much, you have helped me a lot. I am actually not using a rPi, I am trying to get it working on my FPGA.

RaspberryPiMatrix commented 3 years ago

I added the info you request to add to framebuffer.cc Now how do you Make it to work. Where do i select to use the QiangliQ3 in. Normally was rpi-rgb-led-matrix/binding/python/samples/ any of the programs. I am making a YouTube Channel (RaspberryPiMatrix) for raspberry pi Zero/3/4 for Matrix Displays. I got all other Matrix Displays to work. Trying to get this one to work. If you have a direct link for the files you created to make the QiangliQ3 to work would be appreciated. also i made the hat without using the adafruit-hat board. do you have the schematic for which pins/gpio to the 16 pin HUB75E. Thank You.