Dot set / reset on MAX7912 matrix displays.

Place code snippets and demo code here
Post Reply
AndyGadget
Posts: 222
Joined: Mon Feb 15, 2021 1:44 pm
Has thanked: 124 times
Been thanked: 132 times

Dot set / reset on MAX7912 matrix displays.

Post by AndyGadget »

There are text MAX7912 text scrolling commands built in to Annex, but here is a routine for addressing individual dots written for the 4 in a row dot matrix display modules. Note this cannot be used in conjunction with the scrolling commands. (Running on 1.47.2 )

Code: [Local Link Removed for Guests]

' Dot set / reset by X/Y co-ords for MAX7219 Dot Matrix Displays.
' 0,0 is top left.
' N.B. This is incompatible with Annex built-in scrolling functions.


wlog "Start"
iobuff.dim(0,8)
iobuff.dim(1,64)

SPI.CSPIN 15
SPI.SETUP 10000000
DDat$ = ""

InitDisplay

do
  x = rnd(32) : y = rnd(8) : z = rnd(2)
  Dot x,y,z
loop

end


' SUBROUTINES
' ===========

' Usage Dot(X position, Y position, on/off)
' 1 = on, 0 = off
' Origin is 0,0 at top left corner.  Bottom right is 31,7
' (Unless you invert the display, of course :¬)

sub Dot(xx,yy,sr)
  
  c1 = (xx \ 8)             ' Integer part gives disp no. (0 to 3)
  c2 = (xx mod 8)           ' gives dot offset in byte (0 to 7)
  r1 = (yy mod 8)           ' gives row  (0 to 7)
  r2 = (yy \ 4)             ' gives dot offset in byte (0 to 7)
  DPtr = (((r1*4)+c1)*4)+3 ' Position of data byte in output string
  
  newbyte = &h80 >> c2
  oldbyte = val("&H"+mid$(DDat$,DPtr,2)) ' Existing byte from output string
  
  if sr = 1 then
    newhex$ = right$("00" + hex$(newbyte OR oldbyte),2)
  else
    newhex$ = right$("00" + hex$((NOT newbyte) AND oldbyte),2)
  endif
  
  DDat$ = left$(DDat$,DPtr-1) + newhex$ + right$(DDat$,128-DPtr-1)
  UpdateDisplay
end sub

sub ClearBuff
  DDat$="01000100010001000200020002000200030003000300030004000400040004000500050005000500060006000600060007000700070007000800080008000800"
end sub

sub UpdateDisplay
  ' Dump Display Data string to SPI buffer
  for cnt = 0 to 8
    iobuff.fromhex(1,DDat$)
    SPI.WRITE_IOBUFF(1,cnt*8,8)
  next cnt
end sub

sub InitDisplay
  ' Reg &H01 - Shutdown mode - Enable displays
  cdat$ = string$(4,"0C01")
  iobuff.fromhex(0,cdat$)
  SPI.WRITE_IOBUFF(0)
  
  ' Reg &H09 - Decode mode - No decode
  cdat$ = string$(4,"0900")
  iobuff.fromhex(0,cdat$)
  SPI.WRITE_IOBUFF(0)
  
  ' Reg &H0B - Scan limit - 8 rows
  cdat$ = string$(4,"0B07")
  iobuff.fromhex(0,cdat$)
  SPI.WRITE_IOBUFF(0)
  
  ' Reg &H0A - Intensity - Range &H00 to &H0F
  Int$ = "01"
  cdat$ = string$(4,"0A" + Int$)
  iobuff.fromhex(0,cdat$)
  SPI.WRITE_IOBUFF(0)
  
  ClearBuff
  UpdateDisplay
  
end sub


'     Layout of display data string.
'     ==============================
'     Top left of first display is    0180xxxxxxxxxxxx
'     Bottom right of last display is xxxxxxxxxxxx0801
'      ----    ----    ----    ----    ----    ----    ----    ----    ----    ----    ----    ----    ----    ----    ----    ----
'Disp  D1  D2  D3  D4  D1  D2  D3  D4  D1  D2  D3  D4  D1  D2  D3  D4  D1  D2  D3  D4  D1  D2  D3  D4  D1  D2  D3  D4  D1  D2  D3  D4
'Row   R1  R1  R1  R1  R2  R2  R2  R2  R3  R3  R3  R3  R4  R4  R4  R4  R5  R5  R5  R5  R6  R6  R6  R6  R7  R7  R7  R7  R8  R8  R8  R8
'#DNum  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
'#DPos  1   5   9  13  17  21  25  29  33  37  41  45  49  53  57  61  65  69  73  77  81  85  89  93  97 101 105 109 113 117 121 125
'
Last edited by AndyGadget on Sat Oct 29, 2022 8:57 pm, edited 3 times in total.
User avatar
cicciocb
Site Admin
Posts: 1997
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 428 times
Been thanked: 1336 times
Contact:

Re: Dot set / reset on MAX7912 matrix displays.

Post by cicciocb »

Nice Andy,
a good example on the use of IOBUFFERS.

Thanks
User avatar
cicciocb
Site Admin
Posts: 1997
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 428 times
Been thanked: 1336 times
Contact:

Re: Dot set / reset on MAX7912 matrix displays.

Post by cicciocb »

Just for the fun, have a look here
https://wokwi.com/projects/346886186659218003
User avatar
cicciocb
Site Admin
Posts: 1997
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 428 times
Been thanked: 1336 times
Contact:

Re: Dot set / reset on MAX7912 matrix displays.

Post by cicciocb »

Hi Andy,
I understood the problem, the parameters are not set when using the SPI.IOBUFFER functions.
I found the issue in the code.
AndyGadget
Posts: 222
Joined: Mon Feb 15, 2021 1:44 pm
Has thanked: 124 times
Been thanked: 132 times

Re: Dot set / reset on MAX7912 matrix displays.

Post by AndyGadget »

You saw my first edit before I removed it 😉
Yes, I did some tidying up at the end and accidentally removed a line in the initialization sub. Took longer to edit the post than to find the bug 🐞
User avatar
Fernando Perez
Posts: 378
Joined: Mon Feb 15, 2021 10:09 pm
Location: Santander (Spain)
Has thanked: 195 times
Been thanked: 267 times

Re: Dot set / reset on MAX7912 matrix displays.

Post by Fernando Perez »

Andy, you have worked extensively with the ESP32 and MAX7219 LED arrays.
I'm testing an ESP8266 with this program:

Code: [Local Link Removed for Guests]

' ESP8266: CS=GPIO15 - CLK=GPIO14 - DIN=GPIO13
CS = 15  
pin.mode CS, output
SPI.SETUP 10000000  ' SPI bus speed 10MHz 

writeMAX &H0F, 0   ' Test mode off (0 off)
writeMAX &H09, 0   ' Decode mode (0 no decode)
writeMAX &H0B, 7   ' Row scan limit 0/7 (7 all row)  
writeMAX &H0C, 1   ' Enable/disable display (1 enable)
writeMAX &H0A, 0   ' Brightness 0/15 (0 minimum)
wlog " END Init =============================="

clearMAX
wlog " END Clear ============================="
  
restore
for i = 0 to 9
  display
  wlog " END Digit ";i;" ==========================="
  pause 1000
next i

clearMAX
  
END

' ---------------------------------
SUB clearMAX
LOCAL i
  for i = 1 to 8
    writeMAX i, 0
  next i  
END SUB

' ---------------------------------
SUB writeMAX(opcode, value)
LOCAL r
  verBIN opcode, value
  pin(CS) = 0
  r = spi.byte(opcode)
  r = spi.byte(value)
  pin(CS) = 1
END SUB

' ---------------------------------
SUB display
LOCAL i, byte
  for i = 1 to 8
    READ byte
    writeMAX i, byte
  next i
END SUB      

' -----------------------------------
SUB verBIN(opcode, value)
LOCAL opcD$, valD$, opcB$, valB$
  opcD$ = str$(opcode)
  opcD$ = string$(3-len(opcD$), "0") + opcD$

  valD$ = str$(value)
  valD$ = string$(3-len(valD$), "0") + valD$
  
  opcB$ = bin$(opcode)
  opcB$ = string$(8-len(opcB$), "0") + opcB$
  
  valB$ = bin$(value)
  valB$ = string$(8-len(valB$), "0") + valB$
  
  wlog "Code=";opcD$;" (";opcB$;")", "Val=";valD$;" (";valB$;")"   

END SUB

' ==========================================================================================
DATA &b00000000,&b00011000,&b00100100,&b00100100,&b00100100,&b00100100,&b00011000,&b00000000
DATA &b00000000,&b00001000,&b00011000,&b00001000,&b00001000,&b00001000,&b00011100,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00001000,&b00010000,&b00100000,&b00111100,&b00000000
DATA &b00000000,&b00111000,&b00000100,&b00111000,&b00000100,&b00000100,&b00111000,&b00000000
DATA &b00000000,&b00000100,&b00001100,&b00010100,&b00111100,&b00000100,&b00000100,&b00000000
DATA &b00000000,&b00111100,&b00100000,&b00111000,&b00000100,&b00000100,&b00111000,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00100000,&b00111000,&b00100100,&b00011000,&b00000000
DATA &b00000000,&b00111100,&b00000100,&b00001000,&b00010000,&b00100000,&b00100000,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00011000,&b00100100,&b00100100,&b00011000,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00100100,&b00011100,&b00000100,&b00011000,&b00000000
And I get what I want:

https://mega.nz/file/CehjxIhD#R98T2LuLP ... S4QmRm0LY

But if I apply the same program to an ESP32, including only the SPI.CSPIN CS line:

Code: [Local Link Removed for Guests]

' ESP32: CS=GPIO5 - CLK=GPIO18 - DIN=GPIO23
CS = 5  
pin.mode CS, output
SPI.CSPIN CS
SPI.SETUP 10000000  ' SPI bus speed 10MHz 

writeMAX &H0F, 0   ' Test mode off (0 off)
writeMAX &H09, 0   ' Decode mode (0 no decode)
writeMAX &H0B, 7   ' Row scan limit 0/7 (7 all row)  
writeMAX &H0C, 1   ' Enable/disable display (1 enable)
writeMAX &H0A, 0   ' Brightness 0/15 (0 minimum)
wlog " END Init =============================="

clearMAX
wlog " END Clear ============================="
  
restore
for i = 0 to 9
  display
  wlog " END Digit ";i;" ==========================="
  pause 1000
next i

clearMAX
  
END

' ---------------------------------
SUB clearMAX
LOCAL i
  for i = 1 to 8
    writeMAX i, 0
  next i  
END SUB

' ---------------------------------
SUB writeMAX(opcode, value)
LOCAL r
  verBIN opcode, value
  pin(CS) = 0
  r = spi.byte(opcode)
  r = spi.byte(value)
  pin(CS) = 1
END SUB

' ---------------------------------
SUB display
LOCAL i, byte
  for i = 1 to 8
    READ byte
    writeMAX i, byte
  next i
END SUB      

' -----------------------------------
SUB verBIN(opcode, value)
LOCAL opcD$, valD$, opcB$, valB$
  opcD$ = str$(opcode)
  opcD$ = string$(3-len(opcD$), "0") + opcD$

  valD$ = str$(value)
  valD$ = string$(3-len(valD$), "0") + valD$
  
  opcB$ = bin$(opcode)
  opcB$ = string$(8-len(opcB$), "0") + opcB$
  
  valB$ = bin$(value)
  valB$ = string$(8-len(valB$), "0") + valB$
  
  wlog "Code=";opcD$;" (";opcB$;")", "Val=";valD$;" (";valB$;")"   

END SUB

' ==========================================================================================
DATA &b00000000,&b00011000,&b00100100,&b00100100,&b00100100,&b00100100,&b00011000,&b00000000
DATA &b00000000,&b00001000,&b00011000,&b00001000,&b00001000,&b00001000,&b00011100,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00001000,&b00010000,&b00100000,&b00111100,&b00000000
DATA &b00000000,&b00111000,&b00000100,&b00111000,&b00000100,&b00000100,&b00111000,&b00000000
DATA &b00000000,&b00000100,&b00001100,&b00010100,&b00111100,&b00000100,&b00000100,&b00000000
DATA &b00000000,&b00111100,&b00100000,&b00111000,&b00000100,&b00000100,&b00111000,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00100000,&b00111000,&b00100100,&b00011000,&b00000000
DATA &b00000000,&b00111100,&b00000100,&b00001000,&b00010000,&b00100000,&b00100000,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00011000,&b00100100,&b00100100,&b00011000,&b00000000
DATA &b00000000,&b00011000,&b00100100,&b00100100,&b00011100,&b00000100,&b00011000,&b00000000

The result I get is this:

https://mega.nz/file/vChiSTIb#qEOe3Nrdo ... hIPk8DOdo

Only the number 7 is seen correctly, the rest either have displaced bits or are not seen directly.
Could you help me?
Post Reply