4 digits 7s display + 74HC595

Hello, is there any library or code sample you guys can suggest me for this purpose?
Will really appreciate it!

You have a common cathode display, & NPN transistors or ULN2003/ULN2803?

Shift data into the shift register, turn on cathode 0.
2mS later, turn off cathode
Shift data into the shift register, turn on cathode 1.
2mS later, turn off cathode
Shift data into the shift register, turn on cathode 2.
2mS later, turn off cathode
Shift data into the shift register, turn on cathode 3.
2mS later, turn off cathode

During the 2mS, do other stuff.
This is blink without delay style coding.

Thank you Mr CrossRoads

The displays are common anode
http://www.paralight.us/uploads/pdf/A-564SR%20GW.pdf

And these are the shift registers

5V power source

Ty ty, I think I have covered the wiring part, what I would like to see is the logic.
If I understand it correctly it's something like:

disable outputs
send a byte with the segments status
enable outputs

Is this correct?
I think I can get it really fast if I can get a commented piece of code, what is i'm looking for.

void loop(){
currentMillis = millis(); // all time elements are type unsigned long
elapsedMillis = currentMillis - previousMillis;
if (elapsedMillis >= duration){
previousMillis = previousMillis + duration;
indexCount = indexCount +1;
if (indexCount == 4){ indexCount = 0;}
PORTD =  PORTD & 0b00001111; // clear D4,5,6,7, used for digit select NPNs
digitalWrite (ssPin, LOW);
SPI.transfer (anodeArray[x]);
digitalWrite (ssPin, HIGH); //
PORTD = PORTD | cathodeArray[x]; // OR in walking 1 pattern, leave D0-1-2-3 unchanged
} // end time check
// do other stuff
} // end loop
byte cathodeArray[] = {
0b00010000, // walking 1 pattern for cathode drivers
0b00100000,
0b01000000,
0b10000000,
};

See if you can follow that. SPI for the anode shift register, D4-5-6-7 for the cathodes.

Thank you, I was unable to follow your code, but wrote something that got it working, at least the first step.

const int digits = 4;

const int latchPin = 7;
const int clockPin = 6;
const int dataPin = 5;

const int digitOne = 8;
const int digitTwo = 9;
const int digitThree = 10;
const int digitFour = 11;

const byte digit[10] =
{
B10000001, //0 ----------
B11110011, //1 ----------
B01001001, //2 ----------
B01100001, //3 ----------
B00110011, //4 ----------
B00100101, //5 ----------
B00000101, //6 ----------
B11110001, //7 ----------
B00000001, //8 ----------
B00100001, //9 ----------
};

void setup() {

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);


  pinMode(digitOne, OUTPUT);  
  pinMode(digitTwo, OUTPUT);
  pinMode(digitThree, OUTPUT);
  pinMode(digitFour, OUTPUT);


  digitalWrite(digitOne, HIGH);
  digitalWrite(digitTwo, HIGH);
  digitalWrite(digitThree, HIGH);
  digitalWrite(digitFour, HIGH);  

}
  
void update_display() {
	for (int i = 0; i < 10; i++) 
	{

		digitalWrite(latchPin, LOW);
		shiftOut(dataPin, clockPin, MSBFIRST, digit[i]); 	
      	delay(200);
		digitalWrite(latchPin, HIGH);
	}
}

void loop () 
{
	update_display();
	delay(200);
}

Now I need to realize how to write over some specific digit and not the four at the same time

I don't see how. You have all four cathodes turned all the time

digitalWrite(digitOne, HIGH);
digitalWrite(digitTwo, HIGH);
digitalWrite(digitThree, HIGH);
digitalWrite(digitFour, HIGH);

I see you did manage to incorporate an array to look up the font, that's a good sign

shiftOut(dataPin, clockPin, MSBFIRST, digit[i]);

CrossRoads:
I don’t see how. You have all four cathodes turned all the time

Yes, BTW they are common anode displays

This seems to work:

void update_display() { 
  

  for(int j = 0;j<4;j++)
  {


    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, digit[j]); 	
    digitalWrite(latchPin, HIGH);	
    digitalWrite(digits[j], HIGH);          
    delay(1);    
    digitalWrite(digits[j], LOW);          
  }
}

The problem is brightness gets too low which makes me think it is something wrong.

Rearrange a little

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, digit[j]);
digitalWrite(latchPin, HIGH);
digitalWrite(digits[j], LOW); // turn on the digit
delay(1);
digitalWrite(digits[j], HIGH); // turn off the digit

as LOW turns on the PNPs, and leave them on longer.
1/30/4 = 8.3mS.
So try 4mS.

Tried 4ms, no visible changes, brightness still low.
Should I use different resistors, using 1K atm.

I really appreciate your patience.

Yes, 220.

Hi,

Just a thought --- You might want to consider a MC14489 driver rather than a 74HC595

http://www.lucidtechnologies.info/db1-10.htm

Roger

Needs common cathode display tho: "LEDs wired with common cathodes are driven in a multiplexed-by-5 fashion."

jay98 has common anode.

Thank you guys, got it working with your help

I have 4 x 4-digits displays, with daisy chained 595 chips driving their segments. so I need only 3 arduino pins for segments, which is great, but I still have the digits wired directly to the arduino taking 16 pins.

That's the part I would like to improve now, I want to handle digits them the same way than segments, through the same IC, but my doubt is about the extra time that would take in the loop.

Will I be able to refresh the displays on time without flickering or any other issue?

Regarding my previous post about how to multiplex also the digits pins, this is what I tried
They are now handled through a second 595 chip.

int digits_number = 4;
int bytes = B0001;

 const int latchSegments = 7;
 const int clockSegments = 6;
 const int dataSegments = 5;
 
 const int latchDigits = 8;
 const int clockDigits = 9;
 const int dataDigits = 10;    
 
 byte byteRead;
  
 const byte digit[10] = 
 {
 B10000001, //0 -----------
 B11110011, //1 ----------
 B01001001, //2 ----------
 B01100001, //3 ----------
 B00110011, //4 ----------
 B00100101, //5 ----------
 B00000101, //6 ----------
 B11110001, //7 ----------
 B00000001, //8 ----------
 B00100001, //9 ----------
 };
     
 void setup() {
   
   Serial.begin(9600);
  
   pinMode(latchSegments, OUTPUT);
   pinMode(clockSegments, OUTPUT);
   pinMode(dataSegments, OUTPUT);
   
   pinMode(latchDigits, OUTPUT);
   pinMode(clockDigits, OUTPUT);
   pinMode(dataDigits, OUTPUT);      
  
   digitalWrite(dataDigits, HIGH);     

 }
     
 void update_display() {
   
     int d1 = 1;
     int d2 = 2;
     int d3 = 3;
     int d4 = 4;        

     bytes = B0001;     
     for(int j = 0;j<digits_number;j++)
     {     
       digitalWrite(latchSegments, LOW);
       switch(j)
       {
         case 0:
       shiftOut(dataSegments, clockSegments, MSBFIRST, digit[d1]); // 1
           break;
         case 1:
       shiftOut(dataSegments, clockSegments, MSBFIRST, digit[d2]); // 2
           break;
         case 2:
       shiftOut(dataSegments, clockSegments, MSBFIRST, digit[d3]); // 3 
           break;
         case 3:
       shiftOut(dataSegments, clockSegments, MSBFIRST, digit[d4]); // 4
           break;              
       }          

       digitalWrite(latchSegments, HIGH);         


       digitalWrite(latchDigits, LOW);
       shiftOut(dataDigits, clockDigits, MSBFIRST, bytes);          
       digitalWrite(latchDigits, HIGH);      

       digitalWrite(dataDigits, HIGH);            
       delay(4);
       digitalWrite(dataDigits, LOW);          

       bytes = bytes << 1;
     }
 }
     

 void loop ()
 {
         update_display();
         delay(1);
 }

And this is what I get (ignore last 2 digits, they are not wired)

As you can see there is some ghosting.

I think I understand what the problem is, every number is displayed in every display digit.
However, I don’t know how to fix it, because if I increase the delay between the digits pin HIGH and LOW, then they start flickering.

I think it’s impossible what I’m trying to do, isn’t it?

int digits_number = 4;
int bytes = B0001;

Are these variable types reasonable, given the size of the value being stored in them?

 const int latchSegments = 7;
 const int clockSegments = 6;
 const int dataSegments = 5;
 
 const int latchDigits = 8;
 const int clockDigits = 9;
 const int dataDigits = 10;

Are these?

     int d1 = 1;
     int d2 = 2;
     int d3 = 3;
     int d4 = 4;

Are these?

Why is there no data in the digits array to represent all segments off (i.e. display nothing in this position)?

What, exactly, are you attempting to display?

The switch inside the for loop looks pretty stupid. On any given pass through the loop, only one of the 4 cases will ever be executed, and the loop only makes 4 passes, executing the cases in order. Get rid of the for loop and the switch statement and cases. Just execute the 4 instructions in order.

PaulS:
Get rid of the for loop and the switch statement and cases. Just execute the 4 instructions in order.

What for?
If I do that I would be lightning always the same digit, and showing the same number.

What for?
If I do that I would be lightning always the same digit, and showing the same number.

I really don't understand this.

You have a for loop that iterates 4 times. On each pass through the loop, you execute one of the 4 statements. On the first pass, you execute the first one. On the second pass, you execute the 2nd one. On the 3rd pass, you execute the 3rd one, and on the 4th pass, you execute the 4th one.

How does that differ from getting rid of the loop, and just executing the 1st statement, the 2nd statement, the 3rd statement, and then the 4th statement?