Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

AD-501-B (w/ LC7932M LED driver ICs) 16x32 LED Display questions

Status
Not open for further replies.
Let me apologize for dragging this out. I'm just having trouble matching the schematic to your code and explanations.

What do you mean by?
all of the PCB labeling on the reverse side (IC's and components) are listed upright for reference.
Is there silkscreen info' on the reverse side of the board showing the bit numbers that correspond to columns and rows, or something like that?
 
Mike,

No problem here. I so much appreciate everything you do for me to solve this.

All I meant was that there was silkscreen component labeling (white on the PCB) (e.g. C4, R3, AD-501-B, etc..) this is how I knew how the board was oriented to make sure I did not have it upside down. I didn't think that mattered but for programming issues it might.

The 16x32 LED module is on the top side while the IC LED drivers and rest of the components are on the bottom side of the PCB. I have 10-11 wires soldered to the top side solder connections (of the bottom side plug in connector) for the connections to my SX-28 microcontroller. This microcontroller is on another Professional development board that Parallax makes.

Ask your questions away. There were no silkscreened bit numbers listed for the rows or columns.
 
Tim,

Thought I'd try writing a driver in BASIC for that OEM display. Just threw something together last night using Swordfish BASIC for the PIC.

Basically I defined our 64 byte/512 bit display buffer as a simple 16 element 32 bit array. You update the display by writing each array element (row) with new data. The interrupt routine drives one 32 bit row of the matrix each 1 msec interrupt cycle using data from the array.

Please note that I'm using features in Swordfish BASIC that may not be available in other versions of BASIC. Also, note that this BASIC interrupt routine uses approximately 25% of the total system processing time/resources. I'll publish another faster version later.

Where do I go to download SX/B and docs'?

Later, Mike

Code:
{
****************************************************************
*  Name    : OEM 16x32 Display v1.BAS                          *
*  Author  : Mike McLaren, K8LH                                *
*  Notice  : Copyright (c) 2007 Micro Applications Consultants *
*          : All Rights Reserved                               *
*  Date    : 07/16/07                                          *
*  Version : 1.0                                               *
*  Notes   :                                                   *
*          :                                                   *
****************************************************************
}
Device = 18F2520
Clock = 20

Dim Display(16) As LongWord         ' full 32 bit row size elements

Dim Row As Byte,                    ' row number, range 0..15
    RowPos As Word,                 ' 16 bit row ring counter
    mask As Word                    ' 16 bit shift register mask
    
Dim Sin_1 As LATB.0,                ' RB0
    Sin_2 As LATB.1,                ' RB1
    Sin_3 As LATB.2,                ' RB2
    CLK   As LATB.3,                ' RB3
    LAT   As LATB.4,                ' RB4
    STB   As LATB.5                 ' active low Output Enable

Dim Carry As STATUS.booleans(0)
    
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  scan 1 of 16 rows each 1 msec interrupt                          '
'                                                                   '
'  1265 cycles, 253.0 usecs, 25.3% ISR processing "overhead"        '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Interrupt TMR2_Interrupt()
    PIR1.1 = 0                      ' clear Timer 2 interrupt flag
    mask = %1000000000000000        ' initialize 16 bit test mask
    While mask <> 0                  '
      LATB = %00010000              ' CLK & STB lo, LAT hi
      If RowPos = mask Then         '
        Sin_1 = 1                   ' set row driver SR bit
      EndIf                         '
      If (Display(Row).word1 And mask) <> 0 Then
        Sin_2 = 1                   ' set 1st column driver SR bit
      EndIf 
      If (Display(Row).word0 And mask) <> 0 Then
        Sin_3 = 1                   ' set 2nd column driver SR bit
      EndIf                         '
      CLK = 1                       ' clock Sin data bits into SR's
      mask = mask >> 1              ' shift the mask bit
    Wend                            '
    LAT = 0                         ' latch data to driver outputs
    LAT = 1                         ' reset LAT hi
    Row = (Row + 1) Mod 16          ' bump Row for next interrupt
    RowPos = RowPos >> 1            ' bump RowPos ring counter bit
    If Carry Then                   '
      RowPos.15 = 1                 '
    EndIf                           '
End Interrupt

{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  subroutines                                                      '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Sub Init_TMR2()
    TMR2 = 0                        ' clear TMR2 register
    PR2 = 250 - 1                   ' 250 * 4 us = 1 ms interrupts
    T2CON = %00100101               ' '00100101', 4 usec 'ticks'
                                    ' '-0100---', postscale 5:1
                                    ' '-----1--', TMR2 on
                                    ' '------01', prescale 4:1
    PIE1.1 = 1                      ' enable Timer 2 interrupts
    INTCON.6 = 1                    ' enable peripheral interrupts
End Sub

{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  program                                                          '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Row = 0                             ' init Row
RowPos = %100000000000000           ' init RowPos ring counter bit

Init_TMR2                           ' init TMR2 for 1 msec interrupts
Enable(TMR2_Interrupt)              ' enable global interrupts

{ 1st frame }

Display(0) = %11111111111111111111111111111111
Display(1) = %01111111111111111111111111111110
Display(2) = %00111111111111111111111111111100
Display(3) = %00011111111111111111111111111000
Display(4) = %00001111111111111111111111110000
Display(5) = %00000111111111111111111111100000
Display(6) = %00000011111111111111111111000000
Display(7) = %00000001111111111111111110000000
Display(8) = %00000000111111111111111100000000
Display(9) = %00000000011111111111111000000000
Display(10)= %00000000001111111111110000000000
Display(11)= %00000000000111111111100000000000
Display(12)= %00000000000011111111000000000000
Display(13)= %00000000000001111110000000000000
Display(14)= %00000000000000111100000000000000
Display(15)= %00000000000000011000000000000000

{ additional frames }

End
 
Last edited:
Mike,

This looks good. I will review it further tonight and try to convert it into SX/B.

Here is a link for the SX/B documentation (PDF download) online help:

**broken link removed**



Here is a link for the SX/B program and other stuff:

**broken link removed**


THANKS!!
 
I was hoping that if I could show you one or two methods in BASIC that it might be more meaningful.

I'm trying other interrupt drivers. The one above uses a bit mask much like that found in your SX/B listing but the code produced is just way too big.

Hey, I think I just passed the Somerset exit (43) as I was driving south towards Nashville.

Take care, Mike
 
Mike,

Pretty cool you were near Somerset! I don't know the exits too well yet but you must have been coming either through Bowling Green, KY or from Lexington, KY.
I only moved down here a little over a year myself but adjusting well to the rural country life with my family.

I had a big problem with my work laptop yesterday in that it is shorting out the brick power supply. A Dell rep will be out to look at it either today or tomorrow so I am out of business as far as my projects go till then. I may have to get a new laptop but I hope my hard drive will be recovered.

I will let you know when I can look at the program.

Talk to you soon.

Thanks again.

Tim
 
Last edited:
Mike,

I looked at your code and much of it I did not follow (especially the interrupt - and you can't have 32 bit words only 16 bits. Bytes are 8 bits not 16 too. Here is my first stab at the conversion into SX/B:

Code:
' ==============================================
'
'   File...... 16x32LED_v6TEST2.SXB
'   Purpose... SX/B interface to AD-501-B
'   Author.... Mike McLaren, K8LH  / Timothy Gilmore
'   Notice.... Copyright (c) 2007 Micro Applications Consultants - All Rights Reserved
'   E-mail.... gilmoret@us.saic.com
'   Started... 16 JUN 2007
'   Updated... 
'
' ==============================================


DEVICE          SX28, OSCHS3, TURBO, STACKX, OPTIONX    'Use external 20 MHz resonator
FREQ            20_000_000
ID              "AD-501-B"

'Device = 18F2520
'Clock = 20

'Dim Display(16) As LongWord         ' full 32 bit row size elements
DisplayLo(16)	VAR	Word
DisplayHi(16)	VAR	Word


'Dim Row As Byte,                    ' row number, range 0..15
RowLo		VAR	Byte
RowHi		VAR	Byte

'Row_Position As Word,           ' 16 bit row ring counter
RowPosition	VAR	Word

'mask As Word                    ' 16 bit shift register mask
mask		VAR	Word   

'Dim Sin_1 As LATB.0,              ' RB0
'    Sin_2 As LATB.1,                ' RB1
'    Sin_3 As LATB.2,                ' RB2
'    CLK   As LATB.3,                ' RB3
'    LAT   As LATB.4,                ' RB4
'    STB   As LATB.5                 ' active low Output Enable
Sin_1         	PIN     RB.0
Sin_2         	PIN     RB.1
Sin_3         	PIN     RB.2
CLK         	PIN     RB.3
LAT         	PIN     RB.4
STB        	PIN     RB.5

    


' -------------------------------------------------------------------------
  INTERRUPT 1000  '1 ms interrupt
' -------------------------------------------------------------------------

GOTO TMR2_Interrupt


' ==============================================
  PROGRAM Start
' ==============================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

Init_TMR2	SUB



Start:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  program                                                          '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'}
Row = 0                             ' init Row
RowPosition = 1 << Row             ' init Row_Position ring counter

Init_TMR2                           ' init TMR2 for 1 msec interrupts
'Enable(TMR2_Interrupt)              ' enable interrupt handler

'{ 1st frame }

'Display(0) = %11111111111111111111111111111111
'Display(1) = %01111111111111111111111111111110
'Display(2) = %00111111111111111111111111111100
'Display(3) = %00011111111111111111111111111000
'Display(4) = %00001111111111111111111111110000
'Display(5) = %00000111111111111111111111100000
'Display(6) = %00000011111111111111111111000000
'Display(7) = %00000001111111111111111110000000
'Display(8) = %00000000111111111111111100000000
'Display(9) = %00000000011111111111111000000000
'Display(10)= %00000000001111111111110000000000
'Display(11)= %00000000000111111111100000000000
'Display(12)= %00000000000011111111000000000000
'Display(13)= %00000000000001111110000000000000
'Display(14)= %00000000000000111100000000000000
'Display(15)= %00000000000000011000000000000000

'WORDS are only 16 bits not 32 so Display(x) needs to be broken into DisplayLO(x) and DisplayHI(x) variables. 

'{ additional frames }

End

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  scan 1 of 16 rows each 1 msec interrupt                          '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'}
'Interrupt TMR2_Interrupt()
'    PIR1.1 = 0                      ' clear Timer 2 interrupt flag
'    mask = %1000000000000000        ' initialize 16 bit test mask
'    Row_Position = 1 << Row         '
'    While mask > 0                  ' (16 iterations)
'      LATB = %00010000              ' CLK & STB lo, LAT hi
'      If Row_Position = mask Then   '
'        Sin_1 = 1                   ' set row driver SR bit
'      EndIf                         '
'      If (Display(Row).word0 And mask) > 0 Then
'        Sin_2 = 1                   ' set 1st column driver SR bit
'      EndIf 
'      If (Display(Row).word1 And mask) > 0 Then
'       Sin_3 = 1                   ' set 2nd column driver SR bit
'      EndIf                         '
'      CLK = 1                       ' clock Sin data bits into SR
'      mask = mask >> 1              ' shift the mask bit
'    Wend                            '
'    CLK = 0                         ' reset CLK lo
'    LAT = 0                         ' latch data to driver outputs
'    LAT = 1                         ' reset LAT hi
'    Row = (Row + 1) Mod 16          ' bump Row for next interrupt
'End Interrupt

'{

TMR2_Interrupt:

'PIR1.1 = 0
mask = %1000000000000000
RowPosition = 1 << RowLo  ' Check this also for RowHi ?
DO WHILE mask > 0
  RB = %0001000
  IF RowPosition = mask THEN
    Sin_1 = 1
  ENDIF
  IF DisplayLo(RowLo).0 THEN
     IF mask > 0 THEN  'Check this also for DisplayHi and RowHi ?
       Sin_2 = 1
     ENDIF
  ENDIF
  IF DisplayLo(RowLo).1 THEN
     IF mask > 0 THEN  'Check this also for DisplayHi and RowHi ? 
       Sin_3 = 1
     ENDIF
  Endif
  CLK = 1
  mask = mask >> 1
LOOP
CLK = 0
LAT = 0
PAUSEUS 50
LAT = 1
ROW = ROW + 1
ROW = ROW // 16  'ROW = (ROW + 1) MOD 16

ISR_Exit:
  RETURNINT


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  subroutines                                                      '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'}
'Sub Init_TMR2()
'    TMR2 = 0                        ' clear TMR2 register
'    PR2 = 250 - 1                   ' 250 * 4 us = 1 ms interrupts
'    T2CON = %00100101               ' '00100101', 4 usec 'ticks'
                                    ' '-0100---', postscale 5:1
                                    ' '-----1--', TMR2 on
                                    ' '------01', prescale 4:1
'    PIE1.1 = 1                      ' enable Timer 2 interrupts
'    INTCON.6 = 1                    ' enable peripheral interrupts
'    INTCON.7 = 1                    ' enable global interrupts
'End Sub

'{

Init_TMR2:
     TMR2 = 0		'?
     PR2 = 250 -1	'?
     PR2CON = %00100101 '?
     PIE.1 = 1 '?
     INTCON.6 = 1 '?
     INTCON.7 = 1 '?
RETURN
 
SX/B is much more limited in its capabilities than I could have imagined. Seems to only allow small arrays of bytes only. Ouch! I'll have to study this more. My PIC example programs aren't going to help you much, though they are probably viable examples for PIC users.

Mike
 
Mike,

The SX28 chip has the most limitations at least in ram and array size (16 bytes) and 20 I/O pins but this is the only one in DIP form so it is easiest to work with on solderless breadboards. They also make an SX48 chip which has 36 I/O pins much more ram and arrays up to 232 bytes I believe but it is in a extremely small surface mount form. The obsolete SX52 is identical to the SX48 except that it is a bit larger (still surface mounted) but has 40 I/O pins. Parallax sells all of the chips on $10 proto boards which make it great to develop with. I used an SX52 protoboard on my 3 colored 16x16 clock (last project I made with your help). I could combine RB and RC outputs or RD and RE outputs into 16 bit WORD outputs for larger sizes. I suppose the SX28 could combine its RB and RC to do the same. Oh yea...all of the SX chips are $2.79 each so they are cheap.

Anyway, as you can see the SX may have some limitations but I don't need to learn assembly language (but can if needed or combined into SX/B) with it's SX/B interpretor language for FREE. It has come a long way in the last year and I am part of a BETA test program for new versions of SX/B so I have 1.51.37 (vs everyone else only gettting 1.51.03 for now).

Do you think going to a PIC chip for future projects with a BASIC compiler - I really don't want to have to learn assembly - which is why I was so attracted to the SX chips to begin with .... will be of any benefit at this point?

I really have no PIC knowledge at this point but may be willing to start or even AVR chips possibly.

I started with Parallax using their Basic Stamp II chips which were much easier to program - more commands but slower than the 4-50 MHz + speed of the SX chips. Converting Basic Stamp 2 code to SX/B code is usually not to hard for me to do either.

I would appreciate your comments on this.

Thanks!
 
Hi Tim,

The SX/B BASIC docs say it's a compiler not an interpretor and it really looks like a simple, capable, intuitive BASIC implementation. Let me study it a little more. I'm sure there's got to be a way to access a 64 byte display buffer quickly and efficiently (perhaps using GET and PUT or more directly using @address_of operations).

Don't "jump ship" for another processor yet. You listed some very good reasons for why you're developing with the SX family.

Later, Mike
 
Mike,

Your right it is a compiler not an interpretor. I use those words interchangibly and I should not.

Look at this code example that shows how to have a large array of 64 from an SX28 limited 16 byte array. Although I never quite figured it out how to use it in past applications. Let me know if this helps or not. I have plenty more code examples from Jon Williams (guy that wrote the PDF book - also known as JonnyMac).

I zipped it along with all of the others that may be helpfull to you. Look at Big_Array.sxb and WREAD.sxb in particular. Many of the other complete programs have good subroutines in them too.

Thanks.
 

Attachments

  • SX Code.zip
    885.4 KB · Views: 228
Tim,

I'll take a closer look at SX/B during the coming week. Meanwhile for your amusement and for those PIC users who may be considering purchasing one of those $12.90 USD 16x32 modules, here's an updated (untested) version of PIC demo software using Swordfish BASIC that features PWM brightness control and an improved performance assembly code ISR driver.

Mike

Code:
{
*********************************************************************
*  Name    : OEM 16x32 Display v3.BAS                               *
*  Author  : Mike McLaren, K8LH                                     *
*  Notice  : Copyright (c) 2007, Micro Applications Consultants     *
*          : All Rights Reserved                                    *
*  Date    : 07/21/07                                               *
*  Version : 3.0                                                    *
*  Notes   : v3 software features PWM brightness control and an     *
*          : assembly code ISR driver for improved performance      *
*          :                                                        *
*********************************************************************
}
Device = 18F2520
Clock = 16

Dim Display(16) As LongWord,        ' full 32 bit row size elements
    TempRow As LongWord             ' temp 32 bit variable

Dim i As Byte,                      '
    Row As Byte,                    ' row number, range 0..15
    Counter As Byte,                ' ISR counter var'
    RowPos As Word,                 ' 16 bit row ring counter
    Work0, Work1, Work2 As Word     ' 16 bit ISR work registers
    
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  scan 1 of 16 rows each 1 msec interrupt                          '
'                                                                   '
'  265 cycles, 53.0 usecs, 5.30% ISR processing "overhead"          '                                                                 '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Interrupt TMR2_Interrupt()
ASM
SR1     equ     0               ;' SR1 pin RB0 (row SR)
SR2     equ     1               ;' SR2 pin RB1 (column 1 SR)
SR3     equ     2               ;' SR3 pin RB2 (column 2 SR)
CLK     equ     3               ;' CLK pin RB3 (all SR's)
LAT     equ     4               ;' LAT pin RB4 (all SR's)

        bcf     PIR1,1          ;' clear Timer 2 interrupt flag
        rlncf   Row,W           ;' row number (0..15) x4
        rlncf   WREG,W          ;'
        addlw   Display         ;'
        movwf   FSR1L           ;' FSR1 = Display(Row).byte0
        clrf    FSR1H           ;'
        movff    POSTINC1,Work0+0
        movff    POSTINC1,Work0+1
        movff    POSTINC1,Work1+0
        movff    POSTINC1,Work1+1
        movff    RowPos+0,Work2+0
        movff    RowPos+1,Work2+1
        bsf     Counter,4       ;' counter = 16
v0      movlw   b'00000010'     ;' preload WREG
        rlcf    Work1+0,F       ;' rlcf lo byte
        rlcf    Work1+1,F       ;' rlcf hi byte
        rlcf    WREG,F          ;' pick up b2 (2nd column SR)
        rlcf    Work0+2,F       ;' rlcf lo byte
        rlcf    Work0+3,F       ;' rlcf hi byte
        rlcf    WREG,F          ;' pick up b1 (1st column SR)
        rlcf    Work2+4,F       ;' rlcf lo byte
        rlcf    Work2+5,F       ;' rlcf hi byte
        rlcf    WREG,F          ;' pick up b0 (row SR)
        movwf   LATB            ;' update port, [--010ddd]
        bsf     LATB,CLK        ;' toggle <CLK> [--011ddd]
        decfsz  Counter,F       ;' all 16 iterations?
        bra     v0              ;' no, branch, else
;'
;'  latch 48 bits of new SR data onto the driver IC outputs
;'
        bcf     LATB,LAT        ;' toggle <LAT> [--001ddd]
        bsf     LATB,LAT        ;' toggle <LAT> [--011ddd]
;'
;'  advance Row variable and RowPos ring counter for the next cycle
;'
        incf    Row,W           ;' Row++
        bcf     Row,4           ;' Row = Row % 16 (sort of)
        rrcf    RowPos+0,W      ;' rrcf lo byte into W to preserve C
        rrcf    RowPos+1,F      ;' rrcf hi byte
        rrcf    RowPos+0,F      ;' rrcf lo byte
End ASM
End Interrupt

{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  init PWM sub                                                     '
'                                                                   '
'  the STB inputs on all three 16 bit serial-to-parallel drivers    '
'  should be connected to the RC2/CCP1 "PWM" output                 '
'                                                                   '
'  the PWM period (and interrupts) are 1.0 msecs.  adjust display   '
'  brightness by setting PWM duty cycle value in CCPR1L;            '
'                                                                   '
'  CCPR1L = 50      ' 20% duty cycle, 80% brightness                '
'  CCPR1L = 100     ' 40% duty cycle, 60% brightness                '
'  CCPR1L = 150     ' 60% duty cycle, 40% brightness                '
'  CCPR1L = 250     '100% duty cycle, Display is off                '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Sub Init_PWM()
    TMR2 = 0                        ' clear TMR2 register
    PIR1 = 0                        ' clear interrupt flags
    T2CON = %00000010               ' '00000010'
                                    ' '-0000---', postscale 1:1
                                    ' '-----0--', TMR2 off
                                    ' '------10', prescale 16:1
                                    ' for 4-us Timer 2 'ticks'
    PR2 = 250 - 1                   ' 250 * 4 us = 1 msec PWM period
                                    ' and interrupt rate
    CCP1CON = %00001100             ' '00001100'
                                    ' '00------', unused bits
                                    ' '--00----', duty cycle lsb's
                                    ' '----1100', PWM mode
    CCPR1L = 25                     ' 10% duty cycle, 90% brightness
    PIE1.1 = 1                      ' enable Timer 2 interrupts
    INTCON.6 = 1                    ' enable peripheral interrupts
    T2CON.2 = 1                     ' turn on Timer 2
End Sub

{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  program                                                          '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Row = 0                             ' init Row
RowPos = %1000000000000000          ' init RowBit ring counter
Counter = 0                         ' init ISR counter var'

ADCON1 = %00001111                  ' setup RB3..RB0 to digital mode
PORTB = %00010000                   ' setup PORTB (SR <LAT> bit hi)
TRISB = %00000000                   ' PORTB all outputs

Init_PWM                            ' init PWM & Timer 2 interrupts
Enable(TMR2_Interrupt)              ' enable global interrupts

{ 1st frame }
                                                          
Display(0) = %11111111111111111111111111111111
Display(1) = %01111111111111111111111111111110
Display(2) = %00111111111111111111111111111100
Display(3) = %00011111111111111111111111111000
Display(4) = %00001111111111111111111111110000
Display(5) = %00000111111111111111111111100000
Display(6) = %00000011111111111111111111000000
Display(7) = %00000001111111111111111110000000
Display(8) = %00000000111111111111111100000000
Display(9) = %00000000011111111111111000000000
Display(10)= %00000000001111111111110000000000
Display(11)= %00000000000111111111100000000000
Display(12)= %00000000000011111111000000000000
Display(13)= %00000000000001111110000000000000
Display(14)= %00000000000000111100000000000000
Display(15)= %00000000000000011000000000000000

{ additional frames }

For i = 0 To 64
    TempRow = Display(15)           ' save bottom row temporarily
    Display(15) = Display(14)       ' downward repeating scroll
    Display(14) = Display(13)
    Display(13) = Display(12)
    Display(12) = Display(11)
    Display(11) = Display(10)
    Display(10) = Display(9)
    Display(9)  = Display(8)
    Display(8)  = Display(7)
    Display(7)  = Display(6)
    Display(6)  = Display(5)
    Display(5)  = Display(4)
    Display(4)  = Display(3)
    Display(3)  = Display(2)
    Display(2)  = Display(1)
    Display(1)  = Display(0)
    Display(0)  = TempRow
    DelayMS(100)                    ' delay 100 msecs per change
Next
End
 
Last edited:
Someone wrote me off list to ask about how you might use the PWM brightness control.

To make it a little easier to deal with and perhaps understand I created a subroutine in Swordfish BASIC to adjust the brightness setting which is actually the inverse of the PWM duty cycle.
Code:
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'  Sub Brightness(0..100)     0% black to 100% full brightness      '
'                                                                   '
'  15 cycles, 3.75 usecs (16 MHz), including call and return        ' 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Sub Brightness(pPercent As Byte)    ' CCPR1L = (250-(pPercent*2.5))
    Dim Temp As Byte                ' 
    Temp = pPercent * 2             '
    Temp = Temp + (pPercent >> 1)   '
    CCPR1L = 250 - Temp             ' set PWM duty cycle
End Sub                             '
Simply add a line in your MAIN program to change the display brightness level;
Code:
    Brightness(70)                  ' set brightness to 70% of full
Now you probably could also use the Brightness control to fade-to-black from the current level, put new information into the display buffer, then fade-from-black back to the current level, but, I would probably synchronize the brightness level changes to 16 row "frames" to avoid unwanted display artifacts. Sample fade-to-black code might look something like this;
Code:
{ display fade-to-black }

i = Level                           ' copy current 'Level'
While i <> 0                        ' fade from 'Level' to black
    While Row <> 15                 ' sync' to 16 row 'frame'
    Wend                            '
    Brightness(i)                   ' change brightness setting
    While Row <> 0                  ' wait for row 0 
    Wend                            '
    i = Integer(i - 5)              '
Wend                                '
Brightness(0)                       ' force black
 
Last edited:
Mike,

I thank you for your subroutine but I'm not quite following how it is to be applied in the Main routine. I would think brightness is controlled by the current limiting resistors so how is the Brightness control to be applied via software?

Thanks again.
 
tdg8934 said:
Mike,

I thank you for your subroutine but I'm not quite following how it is to be applied in the Main routine. I would think brightness is controlled by the current limiting resistors so how is the Brightness control to be applied via software?

The current limiting resistors control the MAXIMUM brightness, you can use PWM to adjust it anywhere between that maximum and zero.
 
tdg8934 said:
Mike,

I thank you for your subroutine but I'm not quite following how it is to be applied in the Main routine. I would think brightness is controlled by the current limiting resistors so how is the Brightness control to be applied via software?

Thanks again.
Sorry. I assumed that varying the brightness of a single LED using PWM was almost "basic studies" for anyone playing with microcontrollers these days. My first PWM experiment was varying the speed of a 12vdc fan.

Not sure where to refer you for study and you already know I'm not very good at explaining things.
 
Sorry to "resurect" this but I've just bought one of these displays as I thought, it was cheap and going to be simple for me (someone new to pic's) to get working

Arghh how wrong can I be? lol

My eventual plan is to interface this as part of a gps clock project where I'll have led's on the outer right for hours and minutes, and use this display in the middle to display such things as (scrolling display with some holds on it) time in yy:dd:hh:m:ss, day of week in letters, temperature inside and outside (thinking about putting sensors in the fridge and freezer maybe and displaying that also) and some other things not thought of yet.
It will be interfaced to a gps module which will update the time probably about once an hour to make sure its always right

Ambitious for someone who knows practically nothing about programming pic's but I'm hoping to give it a go

ONCE I can get this module figured out, first I've got to identify the connector on the back and then hopefully someone can put it in simple ways how it works, or ideally a sample basic program how to display a couple of letter and I can work from there.
Or something along those lines.
I know the easiest way would be to have a lookup table done for the various words I'd need there are only so many I'd need, or would it be better to do it individually each letter?
The scrolling from right to left is going to be a problem I've no idea how to get it to do that, but hopefully as I get to understand it I will
Thinking about it it shouldnt be that hard.
Another problem is going to be the dimming of the display at night, but with the examples already posted I hope I can get working on this.
(picbasic?although I "could" possibly convert from another form of basic)

The only tools I have available is an easypic 6 board and getting snippets of code from various places, disecting them and figuring out what they do and how they do it, and then modifying it to do exactly what I want.

There's no point in me trying to learn everything I need to about pics because I had a brain injust a couple of years ago, and I have serious memory problems, If I keep at something constantly I remember it, but once I leave it for a week or two it's all gone again and I have to start from scratch again, really annoying and depressing at times
but I'm used to it now
So I found the easiest way for me to do things is as I said above, reading, disecting, modifying various bits of code
if that makes sense.

So any ideas, suggestions, code snippets would all be more than welcome :)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top