At the moment I am using a separate function to display byte arrays like these:

const PROGMEM unsigned char arab4[] = {
  0x00, 0x00, 0x00, 0x00, 
  0xf0, 0xff, 0xff, 0x01, 
  0xf8, 0xff, 0xff, 0x01, 
  0xf8, 0xff, 0xff, 0x00, 
  0x04, 0xf8, 0x0f, 0x00, 
  0x00, 0x7c, 0x00, 0x00, 
  0x00, 0x0e, 0x00, 0x00, 
  0x80, 0x03, 0x00, 0x00, 
  0xc0, 0x01, 0x00, 0x00, 
  0x60, 0x00, 0x00, 0x00, 
  0x20, 0x00, 0x00, 0x00, 
  0x10, 0x00, 0x00, 0x00, 
  0x18, 0x00, 0x00, 0x00, 
  0x08, 0x10, 0x06, 0x00, 
  0x0c, 0x70, 0x0f, 0x00, 
  0x04, 0xf8, 0x0f, 0x00, 
  0x04, 0x78, 0x06, 0x00, 
  0x06, 0x20, 0x00, 0x00, 
  0x06, 0x80, 0x00, 0x00, 
  0x06, 0xc0, 0x01, 0x00, 
  0x06, 0xc0, 0x03, 0x00, 
  0x0e, 0xe0, 0x01, 0x00, 
  0x1c, 0x80, 0x01, 0x00, 
  0x1c, 0x00, 0x00, 0x00, 
  0x7c, 0x00, 0x00, 0x00, 
  0xf8, 0x00, 0x00, 0x00, 
  0xf0, 0x07, 0x00, 0x00, 
  0xe0, 0x7f, 0x00, 0x3c, 
  0xc0, 0xff, 0xff, 0x0f, 
  0x00, 0xff, 0xff, 0x01, 
  0x00, 0xf0, 0x1f, 0x00,
  0x00, 0x00, 0x00, 0x00};

My function for displaying uses Adafruit libraries

#include <RGBmatrixPanel.h>
#include <Adafruit_GFX.h>

Finally my Function:

void xbm32_n (const PROGMEM unsigned char bild[32],word cchsv) {

int i = 0;

    for(int k=4*i;k<(4+4*i);k++)

    for(int ii = 0; ii<8; ii++){ 

       int bit = ((pgm_read_byte(&(bild[k]))) >> ii) & 1;
       if(bit == 1) { matrix.drawPixel(ii+8*k-4*8*i, i, cchsv);}}} 

   i++   ; 

The inner workings are as follows:

The function draws each 32 bit row with the color chosen on the Panel depending on the 4 bytes in each "row" of the hex array.

Essentially 2 loops (to draw the row in byte increments) with outer while loop (to move to next row). The calculation of the pixel positions can be seen inside the matrix.drawPixel(x-pos,y-pos,color-value) Adafruit-function, and were made up by experimenting long hours.

See for the whole .ino File here

Notes on the file

It also features among others

(like a displaying shifting 8x8 symbol-array saved in const PROGMEM byte IMAGES2[][8] used in the function bildlauf(1,...)

an updated function void xbm32_4c(char bild[32],word* cchsvar[4], int duration,int cseq[4])) where:

  • word* cchsvar[4] points to four color data values

  • cseq[4] is the sequence for displaying the colors in each panel quadrant

The subdivision of the panel is realized via if() and else if() commands checking the conditions for positions:
x = (ii+8*k-4*8*i) </> some value
&& y = i </> some value

Function input:

  • bild[32] is used for the hex array as in my case arab4[]
  • cchsv is a color data value . I am using sparkfun 32 LED Matrix and found the following function for hsv color space to work well:

      word hsvcolor(int h, int s, int b ) { //Try HSV colors http://colorizer.org/
      int hue1, sat1, bright1;
      word result;
      hue1=map(h, 0, 360, 0, 1535);
      sat1=map(s, 0, 100, 0, 255);
      bright1=map(b, 0, 100, 0, 255);
      result = matrix.ColorHSV(hue1,sat1,bright1,true); 
      return result;

Current Issues to solve:

I am using Font Forge to create XBM Files in helping me create the hex letter array, but found it very clumsy to export, as the width size must be a multiple of eight to adjust height by deleting 0x00 rows.

At the moment I am searching for easier ways to "correct" the exported XBM arrays (like using 8x8 Editor 8x8 Editor, only for 32x32 Matrices). Is there a possibility for this?

Alternatively it would also help to create a function to truncate hex arrays to fit 32x32 dimensions somehow.

Additionally, in Arabic there is the issue of variant glyphs for the different letter positions (isolated, medial, initial, final). It seems possible to create byte arrays for all variants but "correcting" each bitmap so that a scrolling effect (I plan to upgrade to 64x32 LED Matrix) "adds up" visually seems daunting. I am happy for suggestion on realizing this challenge as well.

I am aware that there is a Adafruit function for bitmaps: void Adafruit_GFX::drawBitmap()
I couldn't get it to work with my hex array, also the possibility on how to change quadrant colors or other subdivisions lead me to write my own version I modified from 8x8 Panel case. I am not sure whether there are inefficiencies in the code I have written, I therefore am happy for suggestions.


The solution to creating Arabic characters with typographic ligature and scrolling them, is:

Using the application RTB RichText to Bitmap :

  1. Set width-size of bitmap in increments of 32*n while using a height initially bigger than 32
    (saving the bmp will allow for cropping of rows so that bigger letters can be produced, a bit offset to fit height 32)

  2. Saving the bmp and editing it (take care that bitmap rows are saved in rows, if not switch scanning line mode)

    Also the byte endian for output must be rightly chosen: ("Lsb" for pc-editing, uploading to arduino for use in the function provided here, it is in "Msb")

    The cropped characters bitmap must be then reloaded into RTB Pixel Editor on a fitting canvas (generate an empty one) and set to a different scanning mode (rows now in columns) with byte endian Msb

  3. Group the array of hex elements in pairs of four (you can use notepad++ and
    regex find: (((0[xX][0-9a-fA-F,]{2})[,]){3}((0[xX][0-9a-fA-F,]{2})))
    replace: {/1}

Using a suiting arduino scrolling function (on top of adafruit libraries)

  1. Insert 32x(4_hex) chunks of your bitmap data in the file provided above as array element in:
    const PROGMEM unsigned char I[][32][4]= {{here},{here},...,{here}}

  2. Adjust main loop code for scrolling direction (here r to l) via increment or decrement and number of scrolls (panel-size is here chosen 32):

    int es=64; while (es>0) { scroller01(I,32,dpink,es,go); --es; }

  3. Verify if you need to load a chunk of your bitmap group to const PROGMEM unsigned char I[][32][4] , so that scrolling is fluid and does not jump when the arduino re-cycles

The Question got solved in detour via another question in this exchange (see here ). I am answering it to resolve parts of it.

The scrolling is slow when extended fully onto 64x32 Panels with arduino Mega 2560.
For a clip see:


If somebody comes up with a more efficient,faster way, please do share!

  • Seems to get downvoted without explanation after two years. At least share your opinion when doing so. Jan 16 '19 at 0:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.