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