MAXMATRIX

Finding nothing about it I wanted to try writing a general purpose library to manage the MAX7219 in matrix mode trying to make it as flexible as possible. Since everything started by running a 8 x 64 alphanumeric display where it was necessary to point to a single character, the next step was to scroll it in the 4 directions.

To do this I used a memory buffer that has 2 hidden rows (up and down) and 2 hidden columns (right and left). Pixel internal coordinates always have their origin in the top right corner of a display and go down by digits (0 to 7). Display column numbers increase to the left (from 1 as do module numbers) and display row numbers increase down (from 1).

Once the buffer has been written it is moved to the display with an instant update and I was amazed at the speeds I managed to get. Then I passed the single pixel addressing through some placement text procedures. The font that I used single and includes printable characters from 32 to 127, to get its bytes I used a site listed within the source called MAX7219-ASCII.BAS and then wrote a VB program to be able to edit more characters easily.

Then, in order to display something on the display, you must first write to the buffer and then refresh the display.

MAX7219 Matrix Module

To make the whole thing more compact, I have used SMD mounting modules (blue with FC-16 DISY1) to connect more cascading modules without losing even one millimeter of space between them. You can buy the single modules or a single assembled composed of 4 cascading modules.

See connections between the FC-16 modules here

MAX7219 Matrix Module Library

Library can be found here : Firewing MAX-Matrix library

Download the compressed folder and with Firewing IDE open dragged it on editor window, will create a folder named MAX7219 in your UserLibrary

Then the library has as OPTION the number of lines and the number of displays per line (the columns). This way you can have rectangular or square displays where you can set the single pixel (addressable per pixel line / pixel column and base 0) to write a character at any point in it and to scroll in any direction or type in a display and write on a display (addressable by display line / display column and base 1).

See display map here

In the buffer there are then two hidden rows (top and bottom) and two hidden columns (left and right) to write hidden characters and then scroll them.

See digit/pixel map here

The font used is fixed-size characters but the library is still easily adaptable to the proportional fonts that are already used in the Swordfish LCD management libraries.

FC-16 Mechanical Support

For those who own a 3D printer, I found a project for the construction of a PLA material support to screw the modules even if they can fit them with 4 holes spaced 6mm in horizontal and 12mm vertically then when assembling the whole it is fixed to the original external holes.

See PLA mounting-plate here

Another system is to make squares to fasten one module to the other use a vetronite that I drilled with a cnc given the pitch between module and module is in mm not inches.

My low-cost tip here and Eagle board with g-code

Firewing 16 compiler:

To avoid problems due to error "in not alligned to Word (16 bit) boundary " with Firewing 16 compiler you must move the assignment of the vByte variable outside the for/next in soubroutine SetDoubledCharAtPixel().

Public Sub SetDoubledCharAtPixel(PixelRow As ushort,
                                 PixelCol As ushort,
                                 ASCIIChar As Char,
                                 optional Ditigits_8x8_Only As Boolean = False)

   dim vByte as byte                              //<----------------- NOW  
   For bDigit As byte = 0 To 7
        vByte = getASCIIRow(cbyte(ASCIIChar),     //<----------------- BEFORE
                            7 - bDigit, 
                            Ditigits_8x8_Only)
        For c as byte = 0 To 7
            SetPixel(PixelRow + bDigit * 2,
                     PixelCol + c * 2,
                     vByte.bits(7 - c))
            SetPixel(PixelRow + bDigit * 2 + 1,
                     PixelCol + c * 2,
                     vByte.bits(7 - c))
            SetPixel(PixelRow + bDigit * 2,
                     PixelCol + c * 2 + 1,
                     vByte.bits(7 - c))
            SetPixel(PixelRow + bDigit * 2 + 1,
                     PixelCol + c * 2 + 1,
                     vByte.bits(7 - c))
        Next
   Next
End Sub

Library test program:

Scroll

Clock = 80

'#option MAX7219_CS_PIN = _D10
'#option MAX7219_CLK    = _D13
'#option MAX7219_DO     = _D11


#option MAX7219_DISPLAYS_IN_ROW  = 4
#option MAX7219_DISPLAYS_ROWS    = 2

imports "MAX7219"

private sub Main()
   Dim s As String(60)
   Dim c As Byte
   Dim i As Byte

   s = "This is a scroll down and then scroll left example "
   Initialize()


   While true
      For c = 0 To Len(s) - 1
         SetHiddenRowCharAtPixel(HIDDEN_TOP_ROW_DIGIT,16,s(c))

         For i = 0 To TOTAL_COL_PIXELS - 1       
            Shift(SHIFTEnum.Down,$FF,3)
            DelayMS(1)
            Update()
         Next

         For i = 0 To 7
            Shift(SHIFTEnum.Left,2)
            DelayMS(30)
            Update()
         Next
      Next
   End While
end sub 

Loops

Clock = 80

'#option MAX7219_CS_PIN = _D10
'#option MAX7219_CLK    = _D13
'#option MAX7219_DO     = _D11


#option MAX7219_DISPLAYS_IN_ROW = 8
#option MAX7219_DISPLAYS_ROWS   = 2

imports "MAX7219"

Const HPix = MAX7219_DISPLAYS_IN_ROW * 8 
Const VPix = MAX7219_DISPLAYS_ROWS * 8 

private sub Main()
   Initialize()
   delayms(2000)
   dim v as bit = 1
   dim upd as boolean = True
   dim c as byte = 0 
   While true
       Dim HStart As ushort = 0
       Dim HCount As ushort = HPix - 1
       dim VStart As ushort = 0
       dim VCount As ushort = VPix - 1        
       While True   
           dim VPos as ushort = VStart       
           For i as ushort = HStart To HCount
               SetPixel(VPos,i,v)
               If upd Then Update() 
           Next
           If Not upd Then Update() 
           dim HPos as ushort = HCount
           For i as ushort = VStart To VCount
               SetPixel(i,HPos,v)
               If upd Then Update() 
           Next
           If Not upd Then Update() 
           VPos = VCount       
           For i as ushort = HCount To HStart Step - 1
               SetPixel(VPos,i,v)
               If upd Then Update() 
           Next
           If Not upd Then Update() 
           HPos = HStart
           For i as ushort = VCount To VStart Step - 1
               SetPixel(i,HPos,v)
               If upd Then Update()  
           Next
           If Not upd Then Update()  
           HStart +=1
           HCount -=1  
           VStart +=1
           VCount -=1

           If HStart>HPix/2 Or VStart>VPix/2 Then        
               exit while
           End If
       End While
       If v = 1 Then 
           v = 0
       Else
           v = 1 
       End If
       If c > 3 Then
           upd = Not upd
           c = 0 
       Else
           c = c + 1
       End If        
   End While
end sub

Shift & Intensity

Clock = 80

'#option MAX7219_CS_PIN = _D10
'#option MAX7219_CLK    = _D13
'#option MAX7219_DO     = _D11


#option MAX7219_DISPLAYS_IN_ROW  = 4
#option MAX7219_DISPLAYS_ROWS    = 2

imports "MAX7219"


private sub Main()
   Dim s As String(60) = "Hi!"

   Initialize() 

   while True

      For i as byte = 0 To Len(s) - 1
          SetCharAtDisplay(HIDDEN_TOP_DIGIT,i + 1,s(i))
      Next
      ShiftAndUpdate(TOTAL_COL_PIXELS + 8, 30,ShiftEnum.Down) 

      For i as byte = 0 To Len(s) - 1
          SetCharAtDisplay(HIDDEN_BOTTOM_DIGIT,i + 1,s(i))
      Next
      ShiftAndUpdate(TOTAL_COL_PIXELS + 8, 30,ShiftEnum.Up) 

      s = "This is a simple shift example.. "    
      SetCharAtDisplay(2,HIDDEN_RIGHT_DIGIT,32)
      For i as byte = 0 To Len(s) - 1
          SetCharAtDisplay(1,HIDDEN_RIGHT_DIGIT,s(i))
          ShiftAndUpdate(8, 30,ShiftEnum.Left)
      Next 
      ShiftAndUpdate(32, 30,ShiftEnum.Left)

      s = "Hi! "
      For i as byte = 0 To Len(s) - 1
          SetCharAtDisplay(HIDDEN_BOTTOM_DIGIT,i + 1,s(i))
      Next
      ShiftAndUpdate(16, 30, ShiftEnum.Up)
      delayms(2000)
      ShiftAndUpdate(32, 30, ShiftEnum.Right)

      For i as byte = (Len(s) - 1) to 0 step - 1
          SetCharAtDisplay(1,HIDDEN_LEFT_DIGIT,s(i)) 
          ShiftAndUpdate(8, 15, ShiftEnum.Right)
      Next

      ShiftAndUpdate(4, 15, ShiftEnum.Right)
      ShiftAndUpdate(4, 15, ShiftEnum.Down)
      delayms(1000)


      for i as byte = 0 to 100
         SetRegion(0,0,TOTAL_COL_PIXELS,TOTAL_ROW_PIXELS,0,PIXOpEnum.Reverse)   
         Update()
         delayms(20)
      next

      for i as byte = $F to $0 step -1 
         SetIntensity(i)
         delayms(500)
      next               

      for i as byte = $0 to $F 
         SetIntensity(i)
         delayms(500)
      next               

      ShiftAndUpdate(18, 10, ShiftEnum.AltCol) 

      delayms(2000)
   End While    
end sub