PWM control of 4 digit Seven Seg LED display


recently while searching else,  came across interesting code controlling 4 digit ( can extend further ) 7 seg displays. particularly impressed brightness control... worked well.

the original author nathan seidle / sparkfun electronics.  author ... have cleaned no change made logic.

thought share .. may find useful. ( of course uses many port pins. tried out since not happy saa1064 iic chip in terms of brightness control. )

code: [select]

/*
  [ code suitable common anode 7seg led display ]

  nathan seidle //spark fun electronics 2011 // 6-13-2011
 
  example of how drive 7 segment led display atmega
  without use of current limiting resistors. technique common
  requires knowledge of electronics - run risk of dumping
  current through segments , burning out parts of display.
  if use stock code should ok, careful editing the
  brightness values.

  code should work colors (red, blue, yellow, green) the
  brightness vary 1 color next because forward voltage
  drop of each color different. code written , calibrated the
  red color.

  display brightness :
  each digit on amount of microseconds
  off until have reached total of 20ms function call
  let's assume each digit on 1000us
  each digit on 1ms, there 4 digits, display off 16ms.
  that's ratio of 1ms 16ms or 6.25% on time (pwm).
  let's define variable called brightness varies from:
  5000 blindingly bright (15.7ma current draw per digit)
  2000 shockingly bright (11.4ma current draw per digit)
  1000 pretty bright (5.9ma)
  500 normal (3ma)
  200 dim readable (1.4ma)
  50 dim readable (0.56ma)
  5 dim readable (0.31ma)
  1 dim readable in dark (0.28ma)

  7 segments
  4 digits
  1 colon
  =
  12 pins required full control

  15 nov 2017

  checkout code below. working good. 500 brightness bit low green kingbright led.
  1000 seems ok. tried out on mega 2560.

*/
# include <ledflasher.h>

ledflasher heartbeat (13, 500, 500);

unsigned long scanmillis, scaninterval = 1000;

int digit1 = 2;  //pwm display pin 1
int digit2 = 3;  //pwm display pin 2
int digit3 = 4;  //pwm display pin 6
int digit4 = 5;  //pwm display pin 8
int sega = 6;    //display pin 14
int segb = 7;    //display pin 16
int segc = 8;    //display pin 13
int segd = 9;    //display pin 3
int sege = 10;   //display pin 5
int segf = 11;   //display pin 11
int segg = 12;   //display pin 15

int value =0;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void setup()
{
  serial.begin(9600);
  heartbeat.begin();
 
  pinmode(sega, output);
  pinmode(segb, output);
  pinmode(segc, output);
  pinmode(segd, output);
  pinmode(sege, output);
  pinmode(segf, output);
  pinmode(segg, output);

  pinmode(digit1, output);
  pinmode(digit2, output);
  pinmode(digit3, output);
  pinmode(digit4, output);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void loop()
{
  heartbeat.update();
 
  if ( millis() - scanmillis > scaninterval)
  {
  scanmillis = millis();
  value++;
  }
  displaynumber(value);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// digit order : msb leftside = d4; lsb rightside = d1.
// each digit lit specific (programmable)  duration of microseconds,
// , switched off. 4 digits done in succession.
// wait of 20ms ensues repeat above process.

void displaynumber(int todisplay)
{
#define display_brightness  1000
#define digit_on  high
#define digit_off  low

  long begintime = millis();

  (int digit = 4 ; digit > 0 ; digit--)
  {
    switch (digit) {
      case 1:
        digitalwrite(digit1, digit_on);
        break;
      case 2:
        digitalwrite(digit2, digit_on);
        break;
      case 3:
        digitalwrite(digit3, digit_on);
        break;
      case 4:
        digitalwrite(digit4, digit_on);
        break;
    }

    lightnumber(todisplay % 10);              //turn on right segments digit = remainder unit place digit
//    int result = todisplay % 10;
//    serial.println ( result) ;
    todisplay /= 10;

    delaymicroseconds(display_brightness);    //display digit fraction of second (1us 5000us, 500 pretty good)

    lightnumber(10);                          //turn off segments
    digitalwrite(digit1, digit_off);          //turn off digits
    digitalwrite(digit2, digit_off);
    digitalwrite(digit3, digit_off);
    digitalwrite(digit4, digit_off);
  }

  while ( (millis() - begintime) < 20) ;     //wait 20ms pass before paint display again
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void lightnumber(int numbertodisplay)         //given single number, turns on segments.... if 10, turn off
{
#define segment_on  low
#define segment_off high
  switch (numbertodisplay)
  {
    case 0:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_on);
      digitalwrite(segf, segment_on);
      digitalwrite(segg, segment_off);
      break;

    case 1:
      digitalwrite(sega, segment_off);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_off);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_off);
      digitalwrite(segg, segment_off);
      break;

    case 2:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_off);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_on);
      digitalwrite(segf, segment_off);
      digitalwrite(segg, segment_on);
      break;

    case 3:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_off);
      digitalwrite(segg, segment_on);
      break;

    case 4:
      digitalwrite(sega, segment_off);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_off);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_on);
      digitalwrite(segg, segment_on);
      break;

    case 5:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_off);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_on);
      digitalwrite(segg, segment_on);
      break;

    case 6:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_off);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_on);
      digitalwrite(segf, segment_on);
      digitalwrite(segg, segment_on);
      break;

    case 7:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_off);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_off);
      digitalwrite(segg, segment_off);
      break;

    case 8:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_on);
      digitalwrite(segf, segment_on);
      digitalwrite(segg, segment_on);
      break;

    case 9:
      digitalwrite(sega, segment_on);
      digitalwrite(segb, segment_on);
      digitalwrite(segc, segment_on);
      digitalwrite(segd, segment_on);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_on);
      digitalwrite(segg, segment_on);
      break;

    case 10:
      digitalwrite(sega, segment_off);
      digitalwrite(segb, segment_off);
      digitalwrite(segc, segment_off);
      digitalwrite(segd, segment_off);
      digitalwrite(sege, segment_off);
      digitalwrite(segf, segment_off);
      digitalwrite(segg, segment_off);
      break;
  }
}

i not use design. believe not limiting instantaneous current shorten life of both led segments , arduino pins.


Arduino Forum > Using Arduino > LEDs and Multiplexing > PWM control of 4 digit Seven Seg LED display


arduino

Comments

Popular posts from this blog

Error compiling for board Arduino/Genuino Uno.

Installation database is corrupt

esp8266 (nodemcu 0.9) client.write très lent ???