In order to save some output pins for my arduino uno, I tried to use a 137 and a 4511 to drive a 4-digit 7seg,
while the 137 switches the digit and the 4511 switches the number to be displayed.
But there is some problems
==Problem 1: flashing==
At first I enable the IC's all the time. But the number and the digit does not change at the same time, and it will display as follows:
-- -- -- 4
-- -- -- 3
-- -- 3 --
-- -- 2 --
-- 2 -- --
-- 1 -- --
1 -- -- --
4 -- -- --
In order to solve this problem, I short both LE' pins and connect them to the arduino as an output. I enabled them only when all the values has been changed. The problem is now solved but it flashes. It seems that the scanning frequency is not high enough or there may be some mistakes in the program.
== Problem 2: Can't call a delay in loop() function==
In the testing program, I tried to call a delay function before the change of number to be displayed. But since the display function involves a scanning process, the delay freeze the scanning and hold it at the left-most digit. Can I still call the delay function if I change the program or it is an impossible thought?
I want to ask if it is a feasible project or it is just an impossible thought. If it is impossible, should I use a shift register instead of a demultiplexer, or I should use an other way to do that?
So you have 4511 driving anodes, and HC137 sinking current from common cathode per digit?
Change the '137 to a better part, like HC595 with ULN2003 for a current sink buffer, or a TPIC6B595 which is like both parts combined. Or HC595 and 4 NPN transistors.
After that, you will have coding issues to fix up. 4-digit display can be made to look very smooth and flicker free with good "blink without delay" coding. Every pass thru loop, you see how long its been since last update, and when enough time has passed you update the output. In this case, have an array of 4 digits that you send out.
The rest of the time, you do whatever your project does, including update the array.
cathodeArray[] = {0x01, 0x02, 0x04, 0x08,};
void setup(){
}
void loop(){
currentMillis = millis(); // all time elements declared as unsigned long, same as millis();
elapsedMillis = currentMillis - previousMillis;
if (elapsedMillis >= duration){ //duration = 3 (mS)
previousMillis = previousMillis + duration;
digitCount = digitCount +1; // 0,1,2,3,
if (digitCount == 4){ digitCount = 0;} // reset count
// turn off all cathodes
digitalWrite (TPIC6B595ss, LOW);
SPI.transfer(0);
digitalWrite (TPIC6B595ss, HIGH);
// set up the 4511 data at 4 output pins however you are doing that
// tbd
// turn on the next cathode
digitalWrite (TPIC6B595ss, LOW);
SPI.transfer(cathodeArray[digitCount]);
digitalWrite (TPIC6B595ss, HIGH);
} // end time check
// now do whatever your program does; finish that task in 3mS so the display can show the next digit
// 1/12mS = 83Hz refresh rate, very smooth.
// can slow down to 24 Hz, movie theater rate
// (1/24)/4 = 10.4mS if you wanted to spread the updates out.
Thanks all. I solved the first problem.
It was because I used Serial.print function to monitor the program and consumed quite a lot of resources of the PIC
knut_ny, I used 1 latch so I have to update digit by digit and time to time.
CrossRoads, thanks so much but it seems that I still can't call the delay in the loop() function. But the first problem has been solved by taking out the Serial.print commands. Thx.