8x7 Segment Display module for Arduino (595 Driver)

I got this from module from dx, manual can be found here:
http://m5.img.dxcdn.com/CDDriver/CD/sku.250813.rar

I am really new and I’ve been struggling for the past couple of days to make the 7 segment do what I want.

I am trying to display a 1 on the first 7 segment (MSB) while cycling the adjacent 7 segment from 0 to 9. The cycling works, however, I can’t get the first 7 segment to consistently show a 1. I can see a 1, but it flickers very quickly. I’m really not sure what to do from here.

int latchPin =  5; //RCK
int clockPin = 6; //SCK
int dataPin = 7; //DIO
byte num[10] = {B11000000, B11111001, B10100100, B10110000, B10011001, B10010010, B10000010, B11111000, B10000000, B10011000};


void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}


void loop() {

  for (int x = 0; x < 10 ; x=x+1){

      digitalWrite(latchPin,LOW);
      shiftOut(dataPin,clockPin,MSBFIRST,1 );
      shiftOut(dataPin,clockPin,MSBFIRST,num[1]);
      digitalWrite(latchPin,HIGH);
    
      digitalWrite(latchPin,LOW);
      shiftOut(dataPin,clockPin,MSBFIRST,2);
      shiftOut(dataPin,clockPin,MSBFIRST,num[x]);
      digitalWrite(latchPin,HIGH);
      delay(300);
  }
}

Hi, I’m not surprised its not working. With this type of display, the Arduino must perform the multiplexing, and your sketch isn’t doing that fast enough. That delay(300) should be more like delay(3). But that will blur the changing patterns on the second digit.

Try this:

int latchPin =  5; //RCK
int clockPin = 6; //SCK
int dataPin = 7; //DIO
byte num[10] = {B11000000, B11111001, B10100100, B10110000, B10011001, B10010010, B10000010, B11111000, B10000000, B10011000};


void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}


void loop() {

  for (int x = 0; x < 10 ; x=x+1){

    for (int y = 0; y < 50; y++){

      digitalWrite(latchPin,LOW);
      shiftOut(dataPin,clockPin,MSBFIRST,1 );
      shiftOut(dataPin,clockPin,MSBFIRST,num[1]);
      digitalWrite(latchPin,HIGH);
      delay(3);
    
      digitalWrite(latchPin,LOW);
      shiftOut(dataPin,clockPin,MSBFIRST,2);
      shiftOut(dataPin,clockPin,MSBFIRST,num[x]);
      digitalWrite(latchPin,HIGH);
      delay(3);
    }
  }
}

Paul

Oh wow, it works! Thanks PaulRB, that’s really interesting. There is no blur, it looks good. I don’t understand multiplexing, so I guess I’ll have to read up on it.

The interesting part is I can remove both delays and still achieve the desired result. However, i can slow down or increase the speed of the alternating numbers by changing the amount of cycles y goes through

  for (int x = 0; x < 10 ; x=x+1){

    for (int y = 0; y < 1000; y++){

      digitalWrite(latchPin,LOW);
      shiftOut(dataPin,clockPin,MSBFIRST,1 );
      shiftOut(dataPin,clockPin,MSBFIRST,num[1]);
      digitalWrite(latchPin,HIGH);
     // delay(5);
    
      digitalWrite(latchPin,LOW);
      shiftOut(dataPin,clockPin,MSBFIRST,2);
      shiftOut(dataPin,clockPin,MSBFIRST,num[x]);
      digitalWrite(latchPin,HIGH);
     // delay(5);
    }
  }

This makes me wonder, how would one accurately calculate the time required for the number to transition into the next number? Is it safe to assume that y < 1000 cycles would be equivalent to 1 second? Is there a proper way to do the calculations?

Also, are there better 7 segments you’d recommend? (thanks in advance)

I put that extra loop in your code because it was a "quick-n-dirty" way to get it working. If you need precise timing, you dont do it that way, for the reason you figured out already. You avoid using loops and delays and instead use the millis() function. I can write something for you this evening to demonstrate.

What do you mean by "better" 7 seg displays? Bigger, brighter...?

I'd appreciate that, I will read up on the millis() function in the time being and see if I can also figure it out and compare my results to yours.

(I was under the impression that my type of display was "harder" to work with so I was wondering what other types of displays would be more ideal to buy in the future.)

OK, try this:

int latchPin =  5; //RCK
int clockPin = 6; //SCK
int dataPin = 7; //DIO
byte num[10] = {B11000000, B11111001, B10100100, B10110000, B10011001, B10010010, B10000010, B11111000, B10000000, B10011000};

byte digit[2];

int currDigit, value;

unsigned long multiplexTime, updateTime;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}


void loop() {

  unsigned long timeNow = millis();

  //Is it time to update the value displayed?
  if(timeNow - updateTime > 300) {

    //Increase the value
    value++;
    if (value > 99) value = 0;

    //Work out the units and tens digits and convert them to segment patterns
    digit[0] = num[ value % 10 ];
    digit[1] = num[ value / 10 ];

    //Record the time that the value was updated
    updateTime = timeNow;
  }
  
  
  //Is it time to light the next digit?
  if (timeNow - multiplexTime > 3) {

    //Move on to the next digit
    currDigit++;
    if (currDigit > 1) currDigit = 0;

    //Send digit's pattern to the display
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 1 << currDigit );
    shiftOut(dataPin, clockPin, MSBFIRST, digit[currDigit] );
    digitalWrite(latchPin, HIGH);

    //Record the time that the digit was sent
    multiplexTime = timeNow;
  }

}

For a beginner, displays based on max7219 chip like this one might be easier to use. Those chips do the multiplexing for you, so the Arduino doesn’t have to keep sending the digits over and over, it can just send them once.