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?

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....

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.

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

Single Nixie tube need 10 pin from micro. It's not 7 segment display. And only 1 pin need to te activated at time.
So most of suggestion wont work.
Unfortunately you need 40 statements to set pins. eg
IF T1=0 THEN
A0=1
ELSE
A0=0
ENDIF
By time you write first post you could write 40 IF statements without any problem.
That way you probably get smallest program size.

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

If you are building a clock, the minutes digits never exceed 60 - you require 10 digits for the "ones" (0 - 9), but only 6 for the "tens" (0 - 5). So, it will be possible to map every possible minute on two ports or, in one word value. By writing in DATA statements the "ON" pattern for each possible minute, the DATA statements become a lookup table. For example at XX:34, the 70th DATA position (2 positions for each WORD value and allowing for "Zero" and 1 base offset ) contains the bit code (across two bytes) to turn on the 3 and the 4 on the relevant PORTs. Write the high byte to PORTB, the low to PORTA (or whatever). Of course some minutes - say 59 will be fully contained in the upper byte: 10000010_00000000 -because the two low order bits of the high byte are conscripted for the 9 and 0.

The Hours portion may be handled similarly. As before, you will use ten pins for the "ones" in the hours, but only - at most - three in the "tens" digit (0 - 1 - 2) . Place these values subsequent to the previous.

This method requires only two word variables - one for the minute value, one for the hour value and 144 - 168 EEPROM bytes. In truth, the values are easily calculated and it may be you determine only to calculate the bit value rather than store it.

Will set PORTC.0 and PORTD.2 HIGH (presumably turning on the "0" digit in both positions. It may be your transistors are active low and would therefore require the inverse bit values (%11111011_11111110). WARNING: I did NOT look up the specific syntax of the READ and DATA statements, you should verify these.

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

It seems that nobody paid attention to my routine.

i looked but failed to :-
1 understand how to feed the time from say two bcd encoded bytes into it
2 how it maps the resultant data onto the pins

perhaps you could explain more fully and develop the process a bit further

naming the var more meaningfully helps , i know when i'm deep in a pgm at the time its easy to see the big picture and keep track
but when i come back at a later time i wonder what was i doing here and why, i often wish i named things better with more comments

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

Originally Posted by sayzer

It seems that nobody paid attention to my routine.

I looked at it and, frankly, suggest that:

Code you write (and understand) is far more maintainable, and therefore "better" than code someone else writes that cannot be modified later. The difficulty in this specific case is that there are few options to IF THEN. You may look at SELECT CASE, but it will be only marginally different. Initially, I dismissed the topic because - it worked! It was only when I read Richard's comment "Look again" that I did so - and realized the inefficiency of reading, calculating, and setting each bit and digit individually that I thought about what I saw.

I maintain that code you understand is paramount. I made a suggestion for change because you can save a significant number of pins by dealing with HOURS and MINUTES as individual units (as I described) and, so long as you have EEPROM, you are perhaps able to save significant resources. It is also a possibility that the EEPROM map can be modified to enhance certain features. For example - you may, perhaps, define two sets of hour maps - on with the decimal lit and one without, then load alternates based on odd/ even seconds - thus, a "flashing" second indicator. When using matrix LEDs I find it handy to be able to redesign characters (via the map) without changing the code.

It will depend on your aim in this project. If you want only a Nixie Clock and have no intention of evolving your ability (in regard) and learning from it in the future, then any solution that "works" is good enough. You need not understand it or be comfortable modifying it. However, depending on future goals, starting with code you understand, having a flexible design, and continuing to revisit with a growing understanding become greater priorities.

As always, DIY is about solving your own priorities - and enjoying the satisfaction of doing it.

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

The reason why I'm using separate pins for each digit can be seen in this short video:
And as you can guess, there are no PIC16 chips with 40 available IO ports at all

I've finished first revision of PCB, and DS1302 now is mapped on PORTA.5-7 ports now. And it does not works. While segments can be turn on/off without issues on PORTA, clock chip gives no response. The MCU used is PIC16F1519 and config looks like this:

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

If you can " light up any digits via any pins in software", it is unlikely to be the configuration. More likely in my mind the I2C routines to retrieve clock data. Can you get Hour and Minute values to display on LCD or via the serial comms provided in PB? If you don't have any of the cheap TTL to Serial modules available on Ebay or Amazon for a few bucks, they are (with a serial cable) a worthwhile investment. A 4x20 LCD can also be very helpful in providing some troubleshooting output, if you haven't anything else.

Presuming you have serial, this should (configure the serial com screen (in PB) to match):

Should get you some output and a way to demonstrate you are getting output from the clock. You can read up on all the formatting codes, but start with "TEST", 13, then start adding variables when you're sure you've got it going.

Once you know you can output to serial... Here are some routines I use with the DS series clocks. I use the DS1337 - its supposed to be high accuracy, but I just found them in battery backed-up modules for cheap and... no fiddling with crystals, or wires.

I don't know how much help this is, you didn't really give enough info to go beyond what you say already works, but if you I2C routines look different, then maybe your issue is there. If you're looking for some way to troubleshoot, then maybe the LCD or serial stuff will get you started... just not sure how to help.

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

The animated turn on/off is created via a hardware trick, which we were using in times, when SN74141 was not widely available (~30 years ago). It requires 2 transistors per each digit, so this clock uses 60 pcs of MPSA42 transistors just to do this I'm planning to put this clock on instructables, so all details, including schematics and PCB will be available there.

For the code (I'm using one from PBP examples). Initially, I had test setup assembled on breadboard. DS1302 module was connected to PORTC.1-2-3 and worked fine. I had MAX7219 connected and code worked as it should. However, when moving to PCB, to ease process of PCB design, I had to move DS1302 to PORTA. So now it does not works. The reason might be that I've messed up with wiring, but I wanted to be sure to ask, whenever there might be some specific additional configs needed for PORTA.

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

Thanks, please post link to instructables.
Do you have pull up resistors on I2C lines?
Also post code for reading RTC, so we can help. This way is hard to guess what is wrong.
All address for used for I2C should be byte or word, for proper function off i2CREAD/WRITE.
I2C command uses variables size to send proper no of bits for addresses(8 or 16 bits).

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

I din't look at datasheet, so I assume that RTC is I2C.
RST is input, so it wont never go high. And your clock isn't selected.
Things like this:
RST = 0 ' Reset RTC
RST = 1 ' Ready for transfer
Can make a lot of problem. Depending on how long are your traces, etc it can fail. Look up about RMW issue on PIC.
You can try to add pauses, or slow down PIC clock. and try to use HIGH and LOW, this is little slower and it will set pin to output.
Also try to put LED on 3 pin used by RTC, and drive them with HIGH LOW, to see if they work.

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

This works, but only for ones of hours and ones for minutes. Does not works for tens of hours and tens for minutes. But the problem is, that I've copied this code from somewhere, and have no clue how it works...