Multi Row Panels - pixelmatix/SmartMatrix GitHub Wiki

The most common type of HUB75 panel displays two rows at once, using address lines to select the rows. For example, a "1/8 scan" (aka "MOD8", "8S") 32x16 panel uses three address lines (ABC) to select 8 possible addresses, and displays two rows for each address, for a total of 16 rows. (See more details on HUB75-Panels)

However, some HUB75 panels are sold that display more than two rows at once, such as a "1/4 scan" (aka "MOD4", "4S") 32x16 panel, which uses two address lines (AB) to select 4 possible addresses, and displays four rows for each address, also for a total of 16 rows. These panels are generally brighter as more LEDs are lit up simultaneously, but driving them is more complicated and the layout of pixels is not standardized.

How to check if you have a panel that requires special mapping?

  • Check the model number of your panel, does it tell you the mod/scan type of your panel, and is that less than half the height of your panel?
    • e.g. "8S" for 32 pixel hight panel
    • Look for the model number of the panel on the silkscreen on the back side of your panel (though you can't always trust the info)
  • What address lines are displayed on the pinout next to the HUB75 connector (input or output)? Does that give a clue as to how many address lines there are, and the MOD number?
    • (e.g. only seeing "A" "B" "C" might indicate that there's only three address lines, so the panel is 1/8 scan.
    • Note that this is sometimes incorrect
    • Note that some panels only have 2-3 address lines, but aren't MOD4 or MOD8 scan, they are "AB"/"AC"/"ABC" Panels (See more details on HUB75-Panels)
  • Run a test sketch, this could be something like FeatureDemo.
    • Does it look garbled?
    • Are all pixels driven?
  • Run the MultiRowRefreshMapping example sketch in test mode, are all pixels driven once and only once?

See MultiRowRefreshMapping.ino example sketch for more details on how to find out what mapping your panel has, and how to a new one if SmartMatrix Library doesn't already have a mapping.

Try these existing maps for multi-row panels:

  • SM_PANELTYPE_HUB75_16ROW_32COL_MOD2SCAN
  • SM_PANELTYPE_HUB75_16ROW_32COL_MOD4SCAN
  • SM_PANELTYPE_HUB75_16ROW_32COL_MOD4SCAN_V2
  • SM_PANELTYPE_HUB75_16ROW_32COL_MOD4SCAN_V3
  • SM_PANELTYPE_HUB75_32ROW_64COL_MOD8SCAN
  • SM_PANELTYPE_HUB75_64ROW_64COL_MOD16SCAN

Note: SM_HUB75_OPTIONS_C_SHAPE_STACKING isn't compatible with panels that require the Multi Row Refresh Mapping feature

How to use MultiRowRefreshMapping sketch

(Note this isn't a very easy process. If you're having trouble with it, please post to SmartMatrix Community and be as detailed as you can with how far you got, where you need help, or where the instructions are confusing)

This example can be used to determine the mapping of pixels onto a panel that refreshes multiple rows in parallel. e.g. each RGB channel on a HUB75 P10 32x16 /2 panel fills pixels across four rows at once, and in a non-linear order.

The example code moves a single pixel across the width of the display across one row at a time. To help reverse-engineer the mapping of a panel, we can "unwrap" the panel so a /2 panel looks like a 4-row high panel (/2 means the panel is addressed with two addresses, times two parallel RGB channels in a HUB75 pinout 2 x 2 = 4 rows) or a /4 panel looks like an 8-row high panel (4 address x 2 parallel channels = 8 rows)

Example for a 32x16 /2 panel: Under the "MODE_MAP_REVERSE_ENGINEERING" section, set:

  • kMatrixHeight = 4 (why? see above)
  • kMatrixWidth = (32x16)/kMatrixHeight = 128
  • kPanelType = SM_PANELTYPE_HUB75_4ROW_MOD2SCAN
  • Set SKETCH_MODE to MODE_MAP_REVERSE_ENGINEERING

Run the sketch, and record the output on the panel with video, so it's easy to scroll through the positions of pixels to analyze. You should see a red pixel move to 128 different locations on the panel, followed by a yellow pixel moving to 128 different locations, etc.

Use the recording of the red pixel positions to generate a map on graphing paper, the size of the actual panel. Starting with the first pixel that is shown, record "0" at the X/Y coordinates the pixel appeared on the panel. Continue until the last red pixel "127" is recorded. You can save some time by only recording the numbers of the first and last pixel in a row, and connecting them with an arrow.

Example Map Drawing

From the drawing, record the groupings of pixels from left-to-right, then top-to-bottom to generate a map for your panel, in this format:

  • {rowOffset, pixelOffset, numPixels/direction}
  • rowOffset = the row this group of pixels appears, offset from 0
  • pixelOffset = the order this pixel showed up when displayed by the sketch starting from 0(the number you wrote down in the graph paper)
  • numPixels/direction = the number of continuous pixels in this group, a positive number for left-to-right order, negative for right-to-left
  • The last row of the map is all zeros

Map corresponding to this example panel and the example photo:

  {0, 71,  -8},
  {0, 87,  -8},
  {0, 103, -8},
  {0, 119, -8},
  {2, 72,   8},
  {2, 88,   8},
  {2, 104,  8},
  {2, 120,  8},
  {4,  7,  -8},
  {4, 23,  -8},
  {4, 39,  -8},
  {4, 55,  -8},
  {6,  8,   8},
  {6, 24,   8},
  {6, 40,   8},
  {6, 56,   8},
  {0, 0, 0}   // last entry is all zeros

Panels Using Alt Addressing

If you see a column of pixels (2 or 4) lighting up, instead of a single pixel, your panel likely uses an alt addressing mode (where instead of the address being output binary encoded over the address lines, each address line corresponds to a row, and you ground a single address line to select a row). This has only been seen on /2 and /4 panels. Choose a panel type with alt addressing, e.g. SMARTMATRIX_HUB75_4ROW_MOD2SCAN_ALT_ADDX for reverse engineering, and you should see only one pixel light up instead of a column at a time. If your panel uses alt addressing, make sure you follow the step for PANEL_USES_ALT_ADDRESSING_MODE when you add a new map.

Add this map and panel definition to SmartMatrix Library:

  • Open SmartMatrixCommonHub75.h, add a new definition at the top for your panel. Give it the format
  • SM_PANELTYPE_NUMROW_NUMCOL_MODNSCAN filling in NUMROW, NUMCOL, MODNSCAN
  • Add entries for your new panelType to the CONVERT_PANELTYPE_TO_... Definitions
    • CONVERT_PANELTYPE_TO_MATRIXPANELHEIGHT - height of your panel
    • CONVERT_PANELTYPE_TO_MATRIXROWPAIROFFSET - HUB75 panels fill two rows in parallel, what's the spacing? (normally half of panel height)
    • CONVERT_PANELTYPE_TO_MATRIXSCANMOD - This is just the MOD_N_SCAN value for your panel
    • CONVERT_PANELTYPE_TO_MATRIXPANELWIDTH - What's the width of your panel? (This doesn't have to be exact for non-multi-row-scan panels, 32 is used by default
  • Open PanelMaps.cpp
    • Add your map with a unique name
    • Add new case for your new panelType to getMultiRowRefreshPanelMap(), returning your new panelMap
  • Now test your new panelType with the MODE_MAP_TESTING mode of this sketch

Testing Example 32x16 /2 Panel: Now this same sketch can be used to check if the mapping is being applied correctly to the panel Change the width/height/paneltype to match the actual panel (not unwrapped)

  • kMatrixWidth = 32
  • kMatrixHeight = 16
  • kPanelType = SM_PANELTYPE_HUB75_16ROW_32COL_MOD2SCAN`

Set SKETCH_MODE to MODE_MAP_TESTING

Now when the sketch runs, you should see the pixel go from left to right, top to bottom, covering all the pixels on your panel in the correct order