Mikrobasic, Interrupts en multiplexen

Bavelt

Golden Member

Ik heb het zo ver dat een programma alle letters van het alfabet 'scrollt'
op de Matrix LED 8*8.
Best wel grappig :).

Alleen 'schokt' het nog wat, ik zou het liever wat vloeiender zien. Maar als ik de delay verlaag, gaat het te snel.

pic basic code:


Program Matrix_Kar

'Display Matrix Led 8 * 8, type 1088AS

Dim ClockPin   as sbit at LATB.4        'pin 10
    Latch      as sbit at LATB.3        'pin 9
    Datapin    as sbit at LATB.2        'pin 8

    Light      as Byte                  'Intensity
    Row        as Byte
    i1         as word
    j1         as word

const Font1 As Byte[220] = (                                   'Character table
  0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x3c, 0x00,
  0x3e, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x3e, 0x00,
  0x3c, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00,
  0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
  0x7e, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x7e, 0x00,
  0x06, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x7e, 0x00,
  0x3c, 0x66, 0x76, 0x06, 0x06, 0x66, 0x3c, 0x00,
  0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
  0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
  0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, 0x78, 0x00,
  0x66, 0x36, 0x1e, 0x0e, 0x1e, 0x36, 0x66, 0x00,
  0x7e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00,
  0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
  0xc6, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00,
  0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
  0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x3e, 0x00,
  0x60, 0x3c, 0x76, 0x66, 0x66, 0x66, 0x3c, 0x00,
  0x66, 0x36, 0x1e, 0x3e, 0x66, 0x66, 0x3e, 0x00,
  0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
  0x18, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x7e, 0x00,
  0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,
  0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,
  0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00,
  0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00,
  0x18, 0x18, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x00,
  0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  )

'===============================================================================
Sub Procedure Max_Write(Dim pRow, pDig0 as Byte)
'===============================================================================
 Latch = 0
 SPI1_Write(pRow)
 SPI1_Write(pDig0)
 Latch = 1
 delay_ms(1)
End sub

'===============================================================================
Sub Procedure Max7219_Init()
'===============================================================================
Max_Write(0x09, 0x00)
Max_Write(0x0B, 0x07)
Max_Write(0x0C, 0x01)
Max_Write(0x0A, 0x00)
End sub

'===============================================================================
Sub Procedure Display_Testen()      'Testen van het display; alle LEDS aan
'===============================================================================
Max_Write(0x0F, 0x01)
DELAY_MS(50)
Max_Write(0x0F, 0x00)
DELAY_MS(50)
End sub

'===============================================================================
Sub Procedure Uitzetten_Leds()      'Leds uitzetten per Row
'===============================================================================
FOR Row = 1 to 8
   Max_Write(Row, 0x00)
   delay_ms(5)
NEXT Row
End sub

'===============================================================================
Sub Procedure Aanzetten_Leds()      'Leds uitzetten per Row
'===============================================================================
FOR Row = 1 TO 8
   Max_Write(Row, 0xff)
   delay_ms(5)
NEXT Row
End sub

'===============================================================================
Main:

'===============================================================================
  OSCCON     = %01110000                                      '8Mhz internal
  ANSELA     = %00000000                                      'Port %   digital
  ANSELB     = %00000000                                      'Port %   digital
  TRISA      = %11111111
  TRISB      = %00000000
  PORTA      = %11111111
  SPI1_Init()
  Max7219_Init()
  Display_Testen()
  delay_ms(500)
  Uitzetten_Leds()

  'Loop ----------------------------------------------------------------------

  While True
     'toon_Karakters()
   For i1 = 0 to 25

   for j1 = 7 to 0 step -1
     For Row = 1 to 8
       Max_Write(Row, Font1[(i1*8) + (Row - 1)]<< j1)
     next Row
     Delay_Ms(50)
   next j1

  for j1 = 0 to 7
  For Row = 1 to 8
      Max_Write(Row, Font1[(i1*8) + (Row - 1)]>>j1)
   Next Row
   delay_ms(50)
   next j1
   
   next i1
  Wend

  End.
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

De volgende opgave is om een stukje tekst (als literal) in te voeren en de karakters 'herleiden' uit de tabel zodat die scrollend worden getoond.

Fouten zijn het bewijs dat je het probeert..

Op 2 januari 2020 23:48:17 schreef Bavelt:
Alleen 'schokt' het nog wat, ik zou het liever wat vloeiender zien. Maar als ik de delay verlaag, gaat het te snel.

Je moet een kleine vertraging inbouwen tussen de rijen, maw de bovenste rij 1 step naar links dan een vertraging en dan de 2 rij naar links.
Je kunt dan ook de algemene delay verminderen.

Ons oog ziet dat als een vloeiende beweging naar links, een beetje experimenteren is wel nodig.

LDmicro user.
Bavelt

Golden Member

Ik krijg er nog niet helemaal de vinger achter.
De bedoeling is de letters van het alfabet scrollend van rechts naar links door het display zien gaan.

Het werkt wel, maar niet mooi.
Ik heb 2 loops gemaakt, eentje van 7 naar 0 en daarna van 0 weer naar 7.
Het lukt me niet hier 1 loop van te maken (bv -7 naar + 7).

Het verschijnsel is dat tussen de twee loops een extra delay optreedt, waardoor het lijkt of het schokt.

pic basic code:


While True

   For i1 = 0 to 25
  
     for j1 = 7 to 0 step -1
        For Row = 1 to 8
           Max_Write(Row, Font1[(i1*8) + (Row - 1)]<<j1)
           delay_ms(5)
        next Row
     next j1

     for j1 = 0 to 7
        For Row = 1 to 8
        Max_Write(Row, Font1[(i1*8) + (Row - 1)]>>j1)
        delay_ms(5)
     Next Row
     next j1

   next i1
  Wend
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

In de tweede loop moet je niet van 0 tot 7, maar van 1 tot 6 tellen. Nu worden '0' en '7' twee keer uitgevoerd...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

In de tweede loop moet je niet van 0 tot 7, maar van 1 tot 6 tellen. Nu worden '0' en '7' twee keer uitgevoerd...

Dat was hem inderdaad waar ik overheen keek!

1 tot 6

1 tot 7 is overigens iets fraaier, anders blijft er 1 row nog staan terwijl de volgende al komt.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Nu heb ik een karaktertabel van A t/m Z.

pic basic code:


const Font1 As Byte[212] = (                                   'Character table
  0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x3c, 0x00,              'A
  0x3e, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x3e, 0x00,              'B
  0x3c, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00,              'C
  0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,              'D
  0x7e, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x7e, 0x00,              'E
  0x06, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x7e, 0x00,              'F
  0x3c, 0x66, 0x76, 0x06, 0x06, 0x66, 0x3c, 0x00,              'G
  0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,              'H
  0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,              'I
  0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, 0x78, 0x00,              'J
  0x66, 0x36, 0x1e, 0x0e, 0x1e, 0x36, 0x66, 0x00,              'K
  0x7e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00,              'L
  0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,              'M
  0xc6, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00,              'N
  0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,              'O
  0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x3e, 0x00,              'P
  0x60, 0x3c, 0x76, 0x66, 0x66, 0x66, 0x3c, 0x00,              'Q
  0x66, 0x36, 0x1e, 0x3e, 0x66, 0x66, 0x3e, 0x00,              'R
  0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,              'S
  0x18, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x7e, 0x00,              'T
  0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,              'U
  0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,              'V
  0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00,              'W
  0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00,              'X
  0x18, 0x18, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x00,              'Y
  0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00               'Z
  )]

Als ik nu een tekst wil maken, bv "Hallo", en gebruik maken van de tabel moet ik dus voor ieder karakter uit de string in de tabel zoeken welk karakter (element in de tabel) het betreft.

Wat is nu een handig methode daarvoor?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 4 januari 2020 16:25:04 schreef Bavelt:
Nu heb ik een karaktertabel van A t/m Z.

pic basic code:


const Font1 As Byte[212] = (                                   'Character table
  0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x3c, 0x00,              'A
  0x3e, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x3e, 0x00,              'B
  0x3c, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00,              'C
  0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,              'D
  0x7e, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x7e, 0x00,              'E
  0x06, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x7e, 0x00,              'F
  0x3c, 0x66, 0x76, 0x06, 0x06, 0x66, 0x3c, 0x00,              'G
  0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,              'H
  0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,              'I
  0x1c, 0x36, 0x36, 0x30, 0x30, 0x30, 0x78, 0x00,              'J
  0x66, 0x36, 0x1e, 0x0e, 0x1e, 0x36, 0x66, 0x00,              'K
  0x7e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00,              'L
  0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,              'M
  0xc6, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00,              'N
  0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,              'O
  0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x3e, 0x00,              'P
  0x60, 0x3c, 0x76, 0x66, 0x66, 0x66, 0x3c, 0x00,              'Q
  0x66, 0x36, 0x1e, 0x3e, 0x66, 0x66, 0x3e, 0x00,              'R
  0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,              'S
  0x18, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x7e, 0x00,              'T
  0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,              'U
  0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00,              'V
  0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00,              'W
  0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00,              'X
  0x18, 0x18, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x00,              'Y
  0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00               'Z
  )]

Als ik nu een tekst wil maken, bv "HALLO", en gebruik maken van de tabel moet ik dus voor ieder karakter uit de string in de tabel zoeken welk karakter (element in de tabel) het betreft.

Wat is nu een handig methode daarvoor?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Pointer/index naar positie in tabel:

pic basic code:


Dim MyChar As Char
MyChar = "K"                    'Display 'K'
Pointer = (MyChar - 0x41) << 3  '8 byte steps

[Bericht gewijzigd door Arco op zaterdag 4 januari 2020 16:57:48 (33%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het werkt.
Grappig om inderdaad de volgorde van de ASCII tabel aan te houden.

pic basic code:

While True
   For LenStr = 0 To (Length(str) - 1)
      CharX = Str[LenStr]
       for j1 = 7 to 0 step -1
          For Row = 1 to 8
             Max_Write(Row, Font1[((CharX - 0x41) <<3) + (Row - 1)]<<j1)
             delay_ms(1)
          Next Row
          delay_ms(50)
       Next j1

     for j1 = 1 to 7
        For Row = 1 to 8
           Max_Write(Row, Font1[((CharX - 0x41) <<3) + (Row - 1)]>>j1)
           delay_ms(1)
        Next Row
        delay_ms(50)
     next j1
   Next LenStr

Het betekent wel dat je dan je eigen interne tabel in principe moet opvullen.
(Spatie is de eerste in de ASCII tabel, terwijl de eerste "echte" letter, hoofdletter A dus, op 65 begint.
Hetzelfde tussen de Z en de a (zitten er 6 tussen).

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

En dan loop je tegen de grenzen van het geheugen aan (er over zelfs).

Natuurlijk is het ook op te lossen met:

pic basic code:


if CharX = " " then
                Max_Write(Row, Font1[((26) <<3) + (Row - 1)]<<j1)
             else
                Max_Write(Row, Font1[((CharX - 0x41) <<3) + (Row - 1)]<<j1)
             end if

(26 is het eerste blanco teken na de Z,in de tabel als 0x00 gedefiniëerd)

[Bericht gewijzigd door Bavelt op zaterdag 4 januari 2020 21:47:41 (10%)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Toch zoek ik nog naar de mogelijkheid om de dubbele loop te vervangen door eentje.
Puur om het klein te houden en dubbele statements te voorkomen.

pic basic code:


While True
   For LenStr = 0 To (Length(str) - 1)
      CharX = Str[LenStr]
       for j1 = 7 to 0 step -1
          For Row = 1 to 8
             Max_Write(Row, Font1[((CharX - 0x41) <<3) + (Row - 1)]<<j1)
             delay_ms(1)
          Next Row
          delay_ms(50)
       Next j1

     for j1 = 1 to 7
        For Row = 1 to 8
           Max_Write(Row, Font1[((CharX - 0x41) <<3) + (Row - 1)]>>j1)
           delay_ms(1)
        Next Row
        delay_ms(50)
     next j1
   Next LenStr 
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Valt weinig aan te versimpelen. Ze tellen in verschillende richtingen en naar verschillende waardes; ze hebben weinig gemeen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik ben al het hele weekend aan het puzzelen hoe ik de tekst naar een volgend display kan laten overgaan (scrollen).
Ik heb 6 Led Matrixen 8*8, aangestuurd door ieder zijn eigen Max7219.

Het lijkt er dus op dat je een schuifregister hebt van 6*8 = 48 rijen. Maar na 8 rijen gaat het wel over op een ander display.
om een karakter op het meest rechtse display te krijgen is het dus 6 * een Write.
Terwijl het de bedoeling is om naar links te scrollen.

Wellicht een tip hoe dit aan te pakken?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Gewoon de data 'omgekeerd' naar de displays sturen. (steeds 1 kolom naar links opgeschoven)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik had dan zoiets,

pic basic code:

Str = "HALLO123"

  'Loop ----------------------------------------------------------------------

  While True
   For i1 = (Length(str) - 1) to 0 step -1
   For j1 = 7 to 0 step -1
   For Row = 1 to 8
    max_Write(Row, Font1[((Str[i1 - 0] - 0x20) <<3) + (Row - 1)]<<j1,
                   Font1[((Str[i1 - 1] - 0x20) <<3) + (Row - 1)]<<j1,
                   Font1[((Str[i1 - 2] - 0x20) <<3) + (Row - 1)]<<j1,
                   Font1[((Str[i1 - 3] - 0x20) <<3) + (Row - 1)]<<j1,
                   Font1[((Str[i1 - 4] - 0x20) <<3) + (Row - 1)]<<j1,
                   Font1[((Str[i1 - 5] - 0x20) <<3) + (Row - 1)]<<j1
                   )
  Next Row
  Delay_ms(250)
  Next j1
  Delay_ms(250)
  Next i1

  Wend

Maar dat gaat dus niet goed.

Fouten zijn het bewijs dat je het probeert..
KGE

Golden Member

Bij mijn LED balk heb ik een soort 'framebuffer' gemaakt van 256 bytes die steeds door een vaste routine gescand wordt.
De bytes worden verticaal naar het display gestuurd.

Om dat het display minder dan 256 kolommen breed is (ik meen 60) kun je nu door je scan routine een offset (vanaf 0, de eerste byte in je framebuffer) mee te geven, simpelweg scrollen/schuiven.

Je kunt dan ook effecten als het beroemde 'STOP' en 'POLITIE' op je display laten verschijnen door simpelweg de offset om en om aan te passen. De vaste scan routine zorgt voor stabiele uitvoer.

Vanuit het hoofdprogramma hoef je nu alleen maar data in de framebuffer te schrijven.

Arco

Special Member

Als je routine wel van links naar rechts scrollt, moet andersom ook gaan (aleen kwestie van data omgekeerd aanbieden)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op deze manier werkt het:

pic basic code:

Str = "HALLO12345"

  'Loop ----------------------------------------------------------------------

  While True

   For i1 = 0 to (Length(str) - 1)
   For Row = 1 to 8
    For x1 = 0 to 5
    if i1 >= x1 then Inhoud[x1] = Font1[((Str[i1 - x1] - 0x20) <<3) + (Row - 1)] else Inhoud[x1] = 0x00 end if
    Next x1
    max_Write(Row, Inhoud[0], Inhoud[1],  Inhoud[2],
                   Inhoud[3], Inhoud[4],  Inhoud[5]
                   )
    Delay_ms(5)
  Next Row
  Delay_ms(350)
  Next i1

  Wend 
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

pic basic code:

if i1 >= x1 then Inhoud[x1] = Font1[((Str[i1 - x1] - 0x20) <<3) + (Row - 1)] else Inhoud[x1] = 0x00 end if 

Dit zit erin om te voorkomen dat je allerlei rommel op de 1e 5 displays krijgt voordat de eerste "echte" letter uit de string komt.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Het enige nadeel van bovenstaand is dat de tekst niet mooi 'vloeit',
Het is een beetje van tak-tak.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Als het van links naar rechts vloeiend loopt, is dat andersom ook zo... ;)
Ik begrijp niet goed wat je met 'rommel' bedoelt? (het display laat alleen zien wat je er naar toe stuurt...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Deze constructie die ik nu heb gemaakt is in beide richtingen niet vloeiend, omdat je per display steeds een cijfer maakt (er wordt niet geschoven tussen de rijen).

Als ik

pic basic code:

if i1 >= x1 then Inhoud[x1] = Font1[((Str[i1 - x1] - 0x20) <<3) + (Row - 1)] else Inhoud[x1] = 0x00 end if  

er niet inzet, dan zie je voor de 1e letter (H) allemaal tekens die niet in de string staan. Pas als de H helemaal links is gaat het goed.
Vandaar de 'blank'.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Je hebt zoals @KGE al opmerkt een buffer nodig om dat simpel en vloeiend te laten verlopen. (lengte gelijk aan de tekst * 8 bytes)
Je houdt een pointer/index bij die je bij iedere scroll aanpast. (scroll links:pointer ophogen, scroll rechts:pointer verlagen)
Dan vanaf die positie alle bufferbytes lezen en naar het display sturen.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

IK vind het best wel lastig hier een voorstelling van te maken moet ik zeggen.
Het is geen 1 display, maar 6 displays die je moet aansturen.

Fouten zijn het bewijs dat je het probeert..