A few years ago, I made a timer for photographic processes (which you can find information about here, and that is available here), which also has a 7-segment display. On this board the display is handled by the classic MAX7219 driver. Although it works very well, this chip has a kind of drawback : it's quite pricey, something like 9€/piece when bought by 10 at mouser's. That's half the price of all components I have for this project, for one of them ! And almost four times the price of the Atmega 328p running the board.
Of course, one can bought them on aliexpress / Ebay, they are much cheaper there. But are either counterfeit, or recycled, and not everyone of them will work.
So, I wanted to replace this component by something cheaper. Two shift registers should work, don't they ? This was one of the things I wanted to test with this project.
The first thing I wanted to be sure of is if they could be multiplexed. Shift registers are often used to drive 7 segments displays, but with one SR per digit, and as many SR chained as there are digits. It seems a waste of resource, as you could theoretically use of them to drive segments, and another one to select digit. The only thing is that the one used for digit selection would have inversed logic, so ts can sink current. So be it. It works perfectly, with one drawback (I'll come to it later).
Another thing I wanted to know : all programs or libraries I've read that use shift registers use bit banging. The protocol they use is quite close to SPI, so I wanted to try and use. There are two pro and one con.
- The first advantage is that there is no function to write : just use a SPI library. One line of code for init, and one for each byte you want to send. Bonus : there are four SPI modes, one beeing the exact timing we need to drive a 74HC595.
- The second pro, and the most important to me, is that on most microcontrollers there is a SPI hardware driver. So you just have to handle the bytes you want to send to the hardware, and can do something else in the meantime. Ok, the Arduino SPI library writes the byte to the SPI driver, but waits until the transfer is over, so the benefice of it is quite light.
- The con is that as there is no slave select line on the shift register, you cannot use the SPI bus with any other device, as any data exchanged on the bus would appear on the SR. In this case this is not a problem since there is only one device on the line, but it could be.
On the Arduino Nano I first tested it, the bus can be run at 8MHz. On the clock I've used the same clock frequency, but the chip runs at 20MHz, so 10MHz for SPI clock should be possible.
Last thing : on my timer I offer the user to set the brightness he needs. Could it be with serial registers too ? I supposed yes, as there is an OE (output enable) pin. If we apply PWM on it, we should be able do dim the brightness, yes ? Well, it works really well too. The only thing to take care of is that the OE pin is active low, so the PWM duty cycle is reversed. If using Arduino's analogWrite(), you just subtract the duty cycle you want from 255, and you're good. If working with hardware timers directly (that could enable a 16bit resolution), you can chose the pin behavior (set on 0, clear on compare, or clear on 0, set on compare). On Attiny series 1, it's even simpler : you can invert logic for any pin by setting a bit in setting register, so when you write 1 to this pin, it goes to 0, and vice versa.
Here we are : two shift registers used for driving a 7-segments display, with hardware SPI, brightness dimming. There are a few things to note, though :
- The global brightness is less than with a MAX7219. That maybe because of the multiplexing (but MAX7219 also multiplexes its output, so I don't thing this is the cause), but also about the value chosen for led series resistances. I'll have to give a try with other resistance value.
- The brightness is not the same for all numbers. 1s are far brighter than 3s or 0s. I think this comes from the shift register limitation : IT's sn74HC595 datasheet gives a max continuous current source / sink of 35mA per pin. It's ok, we are far less than that. But the max current through VCC or GND is 70mA, and here we probably demand more. A mosfet on each output could be a solution to handle more current and have an even brightness on the display, whatever the numbers displayed are.
- There can be a flicker when PWMing the display. With a refresh frequency of 1kHz (i.e. each millisecond the next digit is updated) the flickers disappears. I believe it's due to an interference between the display refresh rate and the PWM frequency.
That's all for today !
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.