Need to drive 40 pins on variable change, is there a way to do it in elegant way?

# Thread: Need to drive 40 pins on variable change, is there a way to do it in elegant way?

1. ## Need to drive 40 pins on variable change, is there a way to do it in elegant way?

Hello.

I'm building a nixie clock, which does not uses any specific decoder ICs or multiplexer. Instead, all nixie digits are connected to individual MCU pins via transistors. It uses DS1302 as clock source. Time received from DS1302 is converted into single number in 24 hour format, for example, it time is 15:53, this number will read as 1553. Using DIG statement I'm extracting individual digits from it, so I have 4 variables, called T1-T4, which have data for individual number to be displayed on specific digit. The pin numbers to which nixies are connected are aliases in the following way - A0-A9 for numbers in 1st digit, B0-B9 for numbers in 2nd digit, C0-C9 and D0-D9 for 3rd and 4th digits correspondingly. So now, to display time, I need to run the following code:

IF T1=0 THEN A0=1
IF T1=1 THEN A1=1
IF T1=2 THEN A2=1
IF T1=3 THEN A3=1
IF T1=4 THEN A4=1

and so on, total, 40 lines (not shown is code for extinguishing all non-used numbers, but I'm doing it at same time for all digits)

So question is, is there a way to avoid all these if-then lines and do it somehow in more elegant way?

Thanks in advance!  Reply With Quote

2. ## Re: Need to drive 40 pins on variable change, is there a way to do it in elegant way?

Arrays?

Code:
```A_Vals var word(4) 'A0-A9, B0-B9, C0-C9, D0-D9 in each element;
T_Vals var byte(4) 'T1-T4
i var byte
Tx var byte
Xx var word

Begin:

for i = 0 to 3      ' Clear array.
A_Vals(i) = 0
T_Vals(i) = 0
next i

Start:

for i = 0 to 3  ' Scan 0-3 => T1-T4
Tx = T_Vals(i)   ' Get the value of Tx variable.
Xx = A_Vals(i)   ' Get the value of Ax value.
Xx[Tx]= 1        ' Change Ax value based on Tx value.
A_Vals(i)=Xx     ' Get the value back.
next i

goto start

END```

' Now you have all your pins masked in array A_Vals;
' A0 => A_Vals(0) bit.0-bit.9
' A4 => A_Vals(3) bit.0-bit.9
'.....

' you have to read them back from A_Vals, and assign your corresponding pins on its bits 0-9.
' For example,
' xx = A_Vals(0)
' A0 = ax.0(0)
' A9 = ax.0(8)
'...
' xx = A_Vals(3)
' B0 = ax.0(0)
' B9 = ax.0(8)  Reply With Quote

3. ## Re: Need to drive 40 pins on variable change, is there a way to do it in elegant way?

How about a lookup table, 5 bytes (40 bits) wide and 10 deep (0-9).  Reply With Quote

4. ## Re: Need to drive 40 pins on variable change, is there a way to do it in elegant way?

Yes, table would be nice, but how to do with less iF-THEN ?  Reply With Quote

5. ## Re: Need to drive 40 pins on variable change, is there a way to do it in elegant way?

Here is a routine I wrote for my 6 digit nixie clock using 2 each HV5530P high voltage shift registers. That's 64 bits.
I use a 16F1825 14 pin processor running @ 10 Mhz. I don't like to use all of that hardware....

HVCLK VAR LATC.0 '0-SHIFT REGISTER CLOCK
HVSTB VAR LATC.1 '0-SHIFT REGISTER STROBE
HVDAT VAR LATC.2 '0-SHIFT REGISTER DATA
' ************************************************** ******************
CLOCKIT: 'ENCODE OUTPUT SEQUENCE AND SEND TO SHIFT REGISTER W/COLLONS
' ************************************************** ******************
'------------------------ 64 BIT ENCODE SEQUENCE ------------------------
'9876543210,9876543210,cc,9876543210,9876543210,cc ,9876543210,9876543210
'10's HOURs,1's HOURs ,::,10's MIN's,1's MIN's ,::,10'S SEC's,1'S SEC's
'------------------------------------------------------------------------
JUNK = 7 'FIRST CLEAR THE OUTPUT ARRAY
WHILE JUNK < 255
OUTPUTS(JUNK) = 0
JUNK = JUNK - 1
WEND
JUNK = 0 'NEXT SET THE OUTPUT ARRAY
WHILE JUNK < 6 'CYCLE THRU ALL 6 DIGITS TO DISPLAY
PATDOG = 1 'FEED THE DOG
SELECT CASE JUNK
CASE 0 'UNIT SECONDS 'BIT POSITION
OUTPUTS.0((JUNK * 10) + (SECONDS DIG 0)) = 1 '0-9

CASE 1 'TEN'S OF SECONDS
OUTPUTS.0((JUNK * 10) + (SECONDS DIG 1)) = 1 '10-19
OUTPUTS.0((JUNK * 10) + 10) = MINSECCOL '20
OUTPUTS.0((JUNK * 10) + 11) = MINSECCOL '21

CASE 2 'UNIT MINUTES
OUTPUTS.0((JUNK * 10) + 2 + (MINUTES DIG 0)) = 1 '22-31

CASE 3 'TEN'S OF MINUTES
OUTPUTS.0((JUNK * 10) + 2 + (MINUTES DIG 1)) = 1 '32-41
OUTPUTS.0((JUNK * 10) + 12) = HOURMINCOL '42
OUTPUTS.0((JUNK * 10) + 13) = HOURMINCOL '43

CASE 4 'UNIT HOURS
OUTPUTS.0((JUNK * 10) + 4 + (HOURS DIG 0)) = 1 '44-53

CASE 5 'TEN'S OF HOURS
'DISPLAY 10'S OF HOURS IF THERE IS SOMETHING TO DISPLAY
IF HOURS DIG 1 <> 0 THEN 'IF THERE IS A DIGIT TO DISPLAY
OUTPUTS.0((JUNK * 10) + 4 + (HOURS DIG 1)) = 1 '54-63
ENDIF

END SELECT
JUNK = JUNK + 1
WEND
SHIFTOUT HVDAT,HVCLK,MSBFIRST,[OUTPUTS(7)\8,OUTPUTS(6)\8,OUTPUTS(5)\8,OUTPUTS(4)\ 8,OUTPUTS(3)\8,OUTPUTS(2)\8,OUTPUTS(1)\8,OUTPUTS(0 )\8]
PULSOUT HVSTB,PULSE
RETURN  Reply With Quote

6. ## Re: Need to drive 40 pins on variable change, is there a way to do it in elegant way?

I typically use DATA statements (simple with internal EEPROM) to map each 7 segment character in a byte value. 'A' segment is least significant digit, 'G' segment is bit 6. Bit 7 is unused. For example, the number 8 is %01111111 (all segments on), 1 is %00000011, etc. I then read the bit value and write it to a port or series of pins. If you store the digits in the corresponding memory location, you may simply READ [DIGIT VALUE + 1] to retrieve the segment code.  Reply With Quote

#### Members who have read this thread : 33

You do not have permission to view the list of names.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts