Control 8 x 7 Segment display.

I am going to take a wild guess here and say that is a 595 display just like the last guy. So it is going to want 64 bits of data for the 64 segments. Why not read up on ShiftOut and sent it FFFFFFFFFFFFFFFF (64 1 bits). I bet it illuminates all the segments. Then work it out which bit maps to what segment.

See "For accompanying circuit, see the tutorial on controlling a 74HC595 shift register." about a page down.

Set latchPin to the Arduino pin you have RCK connected to.
Set clockPin to the Arduino pin you have SCK connected to.
Set dataPin to the Arduino pin you have DIO connected to.

If you use the ShiftOut circuit, the capacitor on the latch line is wrong and should not be connected.

Thanks a lot for your help.

Now i can write "Hallo" :slight_smile:

But now i have the problem that only "o" will be displayed when i use the delay function.

My Code:

void loop()
{

 digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,1);
  shiftOut(data,clock,MSBFIRST,B10001001);
  digitalWrite(latch,HIGH);
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,2);
  shiftOut(data,clock,MSBFIRST,B10001000);
  digitalWrite(latch,HIGH);
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,4);
  shiftOut(data,clock,MSBFIRST,B11000111);
  digitalWrite(latch,HIGH);
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,8);
  shiftOut(data,clock,MSBFIRST,B11000111);
  digitalWrite(latch,HIGH);
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,16);
  shiftOut(data,clock,MSBFIRST,B11000000);
  digitalWrite(latch,HIGH);
  
  delay(1000);

}

It works fine without delay function.

I am not sure why you are telling your shift register chain to latch before you have all the data out there. I think by latching it every time with the delay you get the other letters displaying but only for an imperceptable amount of time and then O for a full second. Without the delay you get all the letters showing for the same imperceptable amount of time but at a 1/5 duty cycle which is why it works. Try this, hopefully it works better:

void loop()
{
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,1);
  shiftOut(data,clock,MSBFIRST,B10001001);
  shiftOut(data,clock,MSBFIRST,2);
  shiftOut(data,clock,MSBFIRST,B10001000);
  shiftOut(data,clock,MSBFIRST,4);
  shiftOut(data,clock,MSBFIRST,B11000111);
  shiftOut(data,clock,MSBFIRST,8);
  shiftOut(data,clock,MSBFIRST,B11000111);
  shiftOut(data,clock,MSBFIRST,16);
  shiftOut(data,clock,MSBFIRST,B11000000);
  digitalWrite(latch,HIGH);
  
  delay(1000);
}

Hi JoeN,

thanks for the quick answer.

When i use your code only the last Segment is activ ("O" will be shown).

Nightwolf83:
Hi JoeN,

thanks for the quick answer.

When i use your code only the last Segment is activ ("O" will be shown).

Wow, sorry to lead you down the wrong path. Gotta give that a think, not sure why it would behave that way. Anyone else have a good idea here?

I dont get the

  shiftOut(data,clock,MSBFIRST,1);
  shiftOut(data,clock,MSBFIRST,B10001001);

I usually take the latch low, then pump through all the Bbytes and take the latch high again.

The bytes will be latched into the right registers...

Thanks for your help Boffin1.

when i use this code

  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,B10101010);
  shiftOut(data,clock,MSBFIRST,B11111001);
  digitalWrite(latch,HIGH);

every second Segment shows "1" this is correct but i want to control every single segment for example the first "1" the second "2" ....

I tried also this code

  digitalWrite(latch,LOW);
  
  shiftOut(data,clock,MSBFIRST,B10101010);
  shiftOut(data,clock,MSBFIRST,B11111001);
   shiftOut(data,clock,MSBFIRST,B01010101);
  shiftOut(data,clock,MSBFIRST,B10010000);
  
  digitalWrite(latch,HIGH);

Now i see the the other segments I think this is also correct, because i overwrite the first Bytes. I don't know how can i control every single Segment.

A segment refers to the one line of a 7 segment display .... you are controlling every one of those individually with the 1s and 0s in the bitmap B10000000 etc....

i want to control every single segment for example the first "1" the second "2" ....

If you mean you want the first digit to be "1" and the second digit to be "2'" then depending on which way they have wired up the segments ( I will assume here a,b,c,d,e,f, dec.pt )

for a "1" you would shiftout B01100000 ( only segments a and b on )

for a "2" you would shiftout B110110100 ( only segments a, b d,e, and f on )

Sorry but could somebody show how connect the display?
(arduino? mega?)
I have the same.

thank you

I found I used the code

and the physical connection like this.

It work's in Arduino Mega R3.

#include <SPI.h>

const byte LATCH = 10;

const byte numberOfChips = 4;

byte LEDdata [numberOfChips]; // initial pattern

void refreshLEDs ()
{
digitalWrite (LATCH, LOW);
for (byte i = 0; i < numberOfChips; i++)
SPI.transfer (LEDdata );

  • digitalWrite (LATCH, HIGH);*
  • } // end of refreshLEDs*

void setup ()
{

  • SPI.begin ();*
    } // end of setup
    void showPattern (const unsigned int p1, const unsigned int p2)
  • {*
  • LEDdata [0] = highByte (p1);*
  • LEDdata [1] = lowByte (p1);*
  • LEDdata [2] = highByte (p2);*
  • LEDdata [3] = lowByte (p2);*
  • refreshLEDs ();*
  • delay (30);*
  • } // end of showPattern*

void loop ()
{
unsigned int pattern;

  • pattern = 1;*
  • for (int i = 0; i < 16; i++)*
  • {*
  • showPattern (pattern, pattern);*
  • pattern <<= 1;*
  • }*
  • pattern = 0x8000;*
  • for (int i = 0; i < 16; i++)*
  • {*
  • showPattern (pattern, pattern);*
  • pattern >>= 1;*
  • } *
  • pattern = 1;*
  • for (int i = 0; i < 16; i++)*
  • {*
  • showPattern (~pattern, ~pattern);*
  • pattern <<= 1;*
  • }*
  • pattern = 0x8000;*
  • for (int i = 0; i < 16; i++)*
  • {*
  • showPattern (~pattern, ~pattern);*
  • pattern >>= 1;*
  • } *

} // end of loop

@Nightwolf83

From the code you post, I believe your display is a multiplexed common anode type with two latched shift registers.
The second shift register, the one you shift out to first, controls which digit is on. You can turn on multiple digits at the same time, but then they will all show the same digit. So for all practical purposes, it makes sense to activate just one at a time.
The first shift register, the one you shift out to second, controls which segments are on. Since this is the cathode part of the LED's, a zero means on, and a one means off. Your segments are organized as DP-G-F-E-D-C-B-A. Google seven segment display and look at the pictures if you don't know the naming of the segments. You could also change your shiftout to LSBFIRST and the segments would be ordered in the normal order.

Now, since you can only have one digit on at a time, you just need to change quickly between them. The memory of the cells in your eye means that you will perceive it as if they are all on, albeit a bit dimmer.
If you go over all the digits at frequency of 100 Hz or more you will get a nice flicker free display. You could use the timer1 or timer2 overflow interrupt to trigger the code that changes which digit is on. By default it runs at a frequency of 490 Hz. So with your 8 digits, the display will scan at a frequency of 490/8 = 61 Hz. It's a bit low, but it probably won't be too annoying to look at.

I'm working on a library to ease the use of seven segment displays. If you are interested I could write a driver for your display type and have you test it for me.

Sure.
Thank you.
I'm trying to understand how manage the display.

Mi sample code
For arduino Mega.
Un digit each time.

#include <SPI.h>
const byte LATCH = 51;
 
void setup ()
{
  digitalWrite(SS, HIGH);
  SPI.begin ();
  SPI.setClockDivider(SPI_CLOCK_DIV8);
}

 
void loop ()
{
  unsigned int pattern;
  
 // 1 PUNTO
 // 2 cen
 // 3 arr izq
 // 4 aba izq
 // 5 aba
 // 6 aba der
 // 7 arr der
 // 8 arr
 
  digitalWrite (LATCH, LOW);
  SPI.transfer (B11111111); // TODO ON  
  SPI.transfer (B00000000); // 8 y punto ENCENDIDO
  digitalWrite (LATCH, HIGH);
  delay(300);

  digitalWrite (LATCH, LOW);
  SPI.transfer (B11111111); // TODO ON  
  SPI.transfer (B11111000); // siete
  digitalWrite (LATCH, HIGH);
  delay(300);

  digitalWrite (LATCH, LOW);
  SPI.transfer (B00000100); // centenas  
  SPI.transfer (B00000000); // 8
  SPI.transfer (B00000010); // decenas
  SPI.transfer (B11111000); // 7
  SPI.transfer (B00000001); // unidades
  SPI.transfer (B11111001); // 1
  digitalWrite (LATCH, HIGH);
  delay(1000);

 
  digitalWrite (LATCH, LOW);
  SPI.transfer (B10101010); // en 1 3 5 7
  SPI.transfer (B00000000); // 8chos
  digitalWrite (LATCH, HIGH);
  delay(300);

  digitalWrite (LATCH, LOW);
  SPI.transfer (B10000000);   // 8vo segment
  SPI.transfer (B11111001);   // un uno
  digitalWrite (LATCH, HIGH);
  delay(300);


  digitalWrite (LATCH, LOW);
  SPI.transfer (B01000000);   // 7mo segment
  SPI.transfer (B10100100);   // un DOS
  digitalWrite (LATCH, HIGH);
  delay(300);


// un 8 en el 8vo display
  digitalWrite (LATCH, LOW);
  SPI.transfer (B10000000);
  SPI.transfer (B10000000);
  digitalWrite (LATCH, HIGH);
  delay(300);
  

  
// 9 y punto
  digitalWrite (LATCH, LOW);
  SPI.transfer (highByte(0x10));
  SPI.transfer (lowByte (0x10));
  digitalWrite (LATCH, HIGH);
  delay(300);

// CERO y punto
  digitalWrite (LATCH, LOW);
  SPI.transfer (highByte(0x40));
  SPI.transfer (lowByte (0x40));
  delay(300);
  digitalWrite (LATCH, HIGH);

// letra o minuscula  
  digitalWrite (LATCH, LOW);
  SPI.transfer (highByte(0x23));
  SPI.transfer (lowByte (0x23));
  delay(300);
  digitalWrite (LATCH, HIGH);

  digitalWrite (LATCH, LOW);
  SPI.transfer (highByte(0xF));
  SPI.transfer (lowByte (0xF));
  delay(300);
  digitalWrite (LATCH, HIGH);

  digitalWrite (LATCH, LOW);
  SPI.transfer (highByte(0xA));
  SPI.transfer (lowByte (0xA));
  delay(300);
  digitalWrite (LATCH, HIGH);
  
  delay(1000);
}

I have the same display. I got it working today. Here is my sketch. It displays 0 to 7 on the 8 digits.

// Pin numbers
int rck = 5;
int sck = 6;
int dio = 7;

// Binary for 0 to 9
byte num[10]={B11000000, B11111001, B10100100, B10110000,
B10011001, B10010010, B10000010, B11111000, B10000000, B10011000};

// Positions
byte pos[8]={1, 2, 4, 8, 16, 32, 64, 128};

void setup() {
  pinMode(rck, OUTPUT);
  pinMode(sck, OUTPUT);
  pinMode(dio, OUTPUT);
}

void loop() {
  for (int j = 0; j < 8; j++) {
    digitalWrite(rck, LOW);
    shiftOut(dio, sck, MSBFIRST, pos[j]);
    shiftOut(dio, sck, MSBFIRST, num[j]);
    digitalWrite(rck, HIGH);  
    delay(2); // This keeps the flicker above 60 Hz
  }
}

Thanks everyone. I just got one of these today and appreciated the code snippets. Has anyone written or found a class for this display yet?

I made a video explaining the working of the display including the code and some examples of words you can make.

Just a little opinion, but "example of words" is pretty much a fool's errand on a 7 segment display. Graduate to 14 segment displays and this becomes a more reasonable possibility as you can actually display all (English) words.

i know, I'm still experimenting with the display. My dictionary only knows Beer, boob, yeah and hello

spco_mark:
i know, I'm still experimenting with the display. My dictionary only knows Beer, boob, yeah and hello

Well, at least it allows you to display the important words... :smiley: