Need guidance using 7 segment displays

Hi all,

I have a project where I need to create a variety of indicators using encoders with 7 segment displays. I saw a video on youtube of someone doing this with an Arduino card, so I thought I'd ask here for help. I need to state that I know practically nothing about eletronics and would need quite a bit of help with this or possibly even someone offering a service for compensation. I don't even know if an Arduino board (or multiple boards) is the best way to go on this.

Here's a few examples of some indicators I need...

  • Two digit display cycling from 01-20
  • Three digit display cycling from 108-111
  • Two digit display cycling from .10 to .95
  • One digit display cycling between 1-7 or 1-9

Anyone willing to help out a complete newb and get me off the ground with this?? :smiley:

Just google:-

arduino seven segment

lots of examples

Hi,
if you haven't solved your problem yet, i made a code some days before in order to hook your arduino up to a 7 segment display with up to 3 digits!
At the head of the code, you're able to choose the type ( common anode or commen cathode) and the frequency!


// Triple Digit Display by Simon Schrampfer --------------------
int delaytime = 3; //the time a digit is shown
boolean common = 1; // common anodes --> 1; common cathodes --> 0
//----------------It's your turn here!---------------------

//---------------Don't change anything below---------------
boolean off;
const byte patterns[10][7] = {
{ 1,1,1,1,1,1,0 }, // = 0
{ 0,1,1,0,0,0,0 }, // = 1
{ 1,1,0,1,1,0,1 }, // = 2
{ 1,1,1,1,0,0,1 }, // = 3
{ 0,1,1,0,0,1,1 }, // = 4
{ 1,0,1,1,0,1,1 }, // = 5
{ 1,0,1,1,1,1,1 }, // = 6
{ 1,1,1,0,0,0,0 }, // = 7
{ 1,1,1,1,1,1,1 }, // = 8
{ 1,1,1,1,0,1,1 } // = 9
};
byte pattern1[7];
byte pattern2[7];
byte pattern3[7];

void setup()
{
pinMode(2, OUTPUT); //A
pinMode(3, OUTPUT); //B
pinMode(4, OUTPUT); //C
pinMode(5, OUTPUT); //D
pinMode(6, OUTPUT); //E
pinMode(7, OUTPUT); //F
pinMode(8, OUTPUT); //G
pinMode(9, OUTPUT); //DP

//common anodes or cathodes
pinMode(10, OUTPUT); //D1
pinMode(11, OUTPUT); //D2
pinMode(12, OUTPUT); //D3
if (common==1)
{
off = 0;
}
else
{
off = 1;
}
}

void loop()
{
for (int i=999;i>0;i--)
{
for (int t=0;t<20;t++)
{
printall(i);
}
}

}
void printall(int value)
{
givepattern1(givedig1(value));
givepattern2(givedig2(value));
givepattern3(givedig3(value));
switchcommon(1);
printpattern(pattern1);
turnoff();
switchcommon(2);
printpattern(pattern2);
turnoff();
switchcommon(3);
printpattern(pattern3);
turnoff();
}
int givedig1(int value)
{
if (value>999){return 9;}
byte val = value/100;
if (val >= 1)
{
return val;
}
else
{
return 0;
}
}
int givedig2(int value)
{

if (value>999){return 9;}
int oth = value/100;
int dif = value-oth100;
byte val = dif/10;
if (val >= 1)
{
return val;
}
else
{
return 0;
}
}
int givedig3(int value)
{
if (value>999){return 9;}
int oth = value/100;
int dif = value-oth
100;
int nxt = dif/10;
byte val = dif-nxt*10;
return val;
}
void switchcommon(byte which)
{
if (which==1){
digitalWrite(10,common);
digitalWrite(11,off);
digitalWrite(12,off);}
if (which==2){
digitalWrite(10,off);
digitalWrite(11,common);
digitalWrite(12,off);}
if (which==3){
digitalWrite(10,off);
digitalWrite(11,off);
digitalWrite(12,common);}
}
void givepattern1(int digit1){
for (int g=0;g<10;g++){
pattern1[g]=patterns[digit1][g];
}
}
void givepattern2(int digit2){
for (int g=0;g<10;g++){
pattern2[g]=patterns[digit2][g];
}
}
void givepattern3(int digit3){
for (int g=0;g<10;g++){
pattern3[g]=patterns[digit3][g];
}
}
void printpattern(byte onepattern[7])
{
for (int i=2; i<9; i++)
{
int a = (i)-2;
boolean com;
if (common==1)
{
if (onepattern[a] == 1)
{
com = 0;
}
else
{
com = 1;
}
}
digitalWrite(i,com);
}
delay(delaytime);
}
void turnoff()
{
for (int b=2; b<9; b++)
{
digitalWrite(b,common);
}
delay(1);
}

I'd use the Max7219 or Max7221

I just bought a few on Ebay for $3 each

http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=300526362443&ssPageName=STRK:MEWNX:IT

@Simon_S - when posting code, please use the # icon on the editor's toolbar.

 byte val = value/100;
  if (val >= 1)
  {
    return val;
  }
  else
  {
    return 0;
  }
}

Any reason not to simply "return val;" ?

I think you may not have tested "printpattern" very thoroughly (Hint: and if common is zero?)

@AWOL

Any reason not to simply "return val;" ?

I think you may not have tested "printpattern" very thoroughly (Hint: and if common is zero?)

I'm sorry for the buggy code.
You're right, simply returning "val" is the better solution :D.
Yes, there's a bug in "Printpattern", but this is easy to solve (never tried it out while "common" was 0).
There may also should be a method which uses "printall" in order to show a value for a certain amount of time, but in some cases, such as simply reading out the value of a sensor, "printall" will do the job quite nice :).

If anybody wants it, i will upload a rectified and improved version of it as soon as there's time left to hook my display up once again (tomorrow?) :slight_smile:

I've made a few changes to the code, like solving the bug in "printpattern" and shorten the "givedigit_" methods.
Moreover, i added i method to show a value on the display for a certain amount of time.
I had no time to test it out in this version, but i can't see any reason why it should not work ;).

// Triple Digit Display by Simon Schrampfer --------------------
int delaytime = 3;                        //the time a digit is shown
boolean common = 1;                       // common anodes --> 1; common cathodes --> 0
//----------------It's your turn here!---------------------



//---------------Don't change anything below---------------
boolean off;
const byte patterns[10][7] = { 
                               { 1,1,1,1,1,1,0 },  // = 0
                               { 0,1,1,0,0,0,0 },  // = 1
                               { 1,1,0,1,1,0,1 },  // = 2
                               { 1,1,1,1,0,0,1 },  // = 3
                               { 0,1,1,0,0,1,1 },  // = 4
                               { 1,0,1,1,0,1,1 },  // = 5
                               { 1,0,1,1,1,1,1 },  // = 6
                               { 1,1,1,0,0,0,0 },  // = 7
                               { 1,1,1,1,1,1,1 },  // = 8
                               { 1,1,1,1,0,1,1 }   // = 9
                             };
byte pattern1[7];
byte pattern2[7];
byte pattern3[7];

void setup()
{
  pinMode(2, OUTPUT); //A
  pinMode(3, OUTPUT); //B
  pinMode(4, OUTPUT); //C
  pinMode(5, OUTPUT); //D
  pinMode(6, OUTPUT); //E
  pinMode(7, OUTPUT); //F
  pinMode(8, OUTPUT); //G
  pinMode(9, OUTPUT); //DP
  
  //common anodes or cathodes
  pinMode(10, OUTPUT); //D1
  pinMode(11, OUTPUT); //D2
  pinMode(12, OUTPUT); //D3
  if (common==1)
  {
    off = 0;
  }
  else
  {
   off = 1;
  }
}


void loop()
{ 
  for (int i=999;i>0;i--)
  {
    for (int t=0;t<20;t++)
    {
      printall(i);
    }
  }


}
void printall(int value)
{
  givepattern1(givedig1(value));
  givepattern2(givedig2(value));
  givepattern3(givedig3(value));
  switchcommon(1);
  printpattern(pattern1);
  turnoff();
  switchcommon(2);
  printpattern(pattern2);
  turnoff();
  switchcommon(3);
  printpattern(pattern3);
  turnoff();
}
void printfor(int value, int ms) //not tested yet!
{
	int rounds = ms/(delaytime*3+3);
	for (int t=0;t<rounds;t++)
    {
      printall(value);
    }
}
int givedig1(int value)
{
  if (value>999){return 9;}
  byte val = value/100;
  return val;
}
int givedig2(int value)
{
  
  if (value>999){return 9;}
  int oth = value/100;
  int dif = value-oth*100;
  byte val = dif/10;
  return val;
}
int givedig3(int value)
{
  if (value>999){return 9;}
  int oth = value/100;
  int dif = value-oth*100;
  int nxt = dif/10;
  byte val = dif-nxt*10; 
  return val;
}
void switchcommon(byte which)
{
  if (which==1){
    digitalWrite(10,common);
    digitalWrite(11,off);
    digitalWrite(12,off);}
  if (which==2){
    digitalWrite(10,off);
    digitalWrite(11,common);
    digitalWrite(12,off);}
  if (which==3){
    digitalWrite(10,off);
    digitalWrite(11,off);
    digitalWrite(12,common);}
}
void givepattern1(int digit1){
    for (int g=0;g<10;g++){
  pattern1[g]=patterns[digit1][g];
  }
}
void givepattern2(int digit2){
    for (int g=0;g<10;g++){
  pattern2[g]=patterns[digit2][g];
  }
}
void givepattern3(int digit3){
    for (int g=0;g<10;g++){
  pattern3[g]=patterns[digit3][g];
  }
}
void printpattern(byte onepattern[7])
{
  for (int i=2; i<9; i++)
  {
    int a = (i)-2;
    boolean com=0;
    if (common==1)
    {
      if (onepattern[a] == 1)
     {
        com = 0;
     }
      else
     {
       com = 1;
     }
    }
	else
	{
		if (onepattern[a] == 1)
		{
			com = 1;
		}
	}
    digitalWrite(i,com);
  }
  delay(delaytime);
}
void turnoff()
{
  for (int b=2; b<9; b++)
  {
    digitalWrite(b,common);
  }
  delay(1);
}

It strikes me that you're unlikely to change a common cathode display for a common anode one mid-program, so why not just flip the patten once?

@AWOL

It strikes me that you're unlikely to change a common cathode display for a common anode one mid-program, so why not just flip the patten once?

To do that, not only the pattern has to be changed but also whether a common cathode or anode is connected to the digit which is wanted to be on...
The second point is, that my sketch enables me to use the display in other projects smoothly. The final purpose is to traslate this code for the libraries.

Altogether I'm able to use 7-Segment Displays of different types in every situation quickly and smoothly.
Or do u know any better solution for my purposes out there?

To do that, not only the pattern has to be changed but also whether a common cathode or anode is connected to the digit which is wanted to be on...

Which can be done once, in the class's own constructor or "begin" method.
Just a thought.
YMMV.