Choosing a right appropriate led display driver

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello everyone.

im currently working on controlling 7 segment displays using display drivers.

and i have independent unit wise 7 segment displays like this.

and im working on 4 of these.

i mean 4 digit but they are separated

but when i searched the internet all maximum drivers do interface only this type.

and i find this in  max of these schematics.

are there any drivers to drive individual 4 digit?

you may suggest me to buy directly second one but its comparatively costly than individual

and i need to buy lot of 7 segment displays.

and also suggest me some low price drivers

saw max 7219 and max 6955 they are costly than uc itself.

thankssmiley

Salman

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I already said in another thread you would need to use multiplexing? If you google projects using AVR and multiple 7-seg you will find pages such as this:

 

http://www.ablab.in/0-to-9999-di...

 

The schematic there shows you roughly what is going on inside a multi-digit unit such as you show above.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How about two of these  modules for US$3.69 including delivery. Drive them via I2C.

 

http://www.ebay.com/itm/2-Pcs-TM...

 

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

salmanma6 wrote:
and im working on 4 of these.

i mean 4 digit but they are separated

So just wire them up in the same way that the "single-unit" modules are wired internally!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Is there a reason why you are designing with 7-segment displays?  For example,..

---they are cheap,

---they seem easy to use,

---they are available where I live,

---I only need to show a few digits to my user,

---my device needs to show 2-4 digits in total darkness,

---at my school or company, we have been using 7-seg displays for 30 years, and that's the way that we do things...

 

But...

  -- 7 segment displays aren't cheap.  Unless you buy hundreds of them at a time.

  --  They aren't easy.  YOU have to wire them, design a PCB for them, multiplex them, program them, troubleshoot them....

  --  They are available in <country> where I live , work, go to school.  Chinese distributors ship everywhere now.

 

  I recommend considering using a TFT display instead of 7-segment displays.   Here's an eBay link for one with 480x320 pixel resolution and a touch-screen interface.  With a touch screen, your application product looks great and doesn't need any buttons, encoders, or potentiometers.  And the TFT can display the digits big and bright in totally dark conditions.

 

  After buying all the 7-segment parts and the wires and the PCBs and the buttons, encoders, or potentiometers of your user-input interface, a TFT is either cheaper or price competitive to any 7-segment design.  And, finally,  7-segment designs are so...1970s.  I see them and I think the BeeGees and disco.

 

http://www.ebay.com/itm/TFT-3-5-...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

salmanma6 wrote:

you may suggest me to buy directly second one but its comparatively costly than individual

and i need to buy lot of 7 segment displays.

and also suggest me some low price drivers

saw max 7219 and max 6955 they are costly than uc itself.

 

I did think of writing a "MAX7219 equivalent" code for an AVR, I have a project which uses 45 x MAX7219 (360 digits).  I think it would be quite straightforward code, but I would have to write it and program 45 or so chips. I settled for buying cheap (probably dodgy) MAX7219 off ebay.

Otherwise there does not seem to be a cheaper alternative to MAX7219.

Bob. Engineer and trainee Rocket Scientist.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As there has been some interest in my display project, I have pushed it to github. Schematic https://github.com/bobc/bobc_har...

 

 

Each panel has 5 rows of 8 digits, each row served by one MAX7219. In this version, I am using 4 digit CC displays, since that is what I was able to buy cheaply in bulk from ebay or Aliexpress. Panels can be daisy chained together. The panel size is approx 100x100mm, which is designed to stay within cheap PCB manufacturing option for certain low cost PCB makers. I intend to combine 9 panels as a 3x3 set to form a novelty display for a clock (there is no commercial justification, just for fun!).

 

 

 

Bob. Engineer and trainee Rocket Scientist.

Last Edited: Fri. Jun 9, 2017 - 11:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Love your hat Bob.

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
Love your hat Bob.

You're a big fan, eh?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And I thought it was the latest in Hannibal headgear!

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, just some slightly non-standard PPE :)

Bob. Engineer and trainee Rocket Scientist.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That looks totally cool Bob!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

donotdespisethesnake wrote:
I did think of writing a "MAX7219 equivalent" code for an AVR,

 

For amusement only, I created a "MAX7219 simulator"

 


/*
 * Simulate a MAX7219
 *
 * Bob Cousins 2017
 * GPL v3
 */

#include <SPI.h>

byte spi_buf [2];
volatile byte spi_pos;

// display config
const byte num_digits = 4;
byte common_pin[] = {9, A5, A4, A3};
// G..A, DP
byte segment_pin [] = {8,7,6,5, 4,3,2,A0 };
int display_freq = 640;

int prescaler;
int timer1_counter;
byte next_digit;
byte digit_data[8];     // digit data, BCD code or pattern
byte digit_pattern[8];  // actual digit pattern corresponding to segments lit

struct control_t {
  byte decode_mode;
  byte duty_cycle;   // 0-15
  byte digits_displayed;
  bool shutdown; // bool
  bool display_test;
} control;

// built in font patterns
const byte rom_digit_pattern [] = {
 // pabcdefg
  0b01111110, // '0'
  0b00110000, // '1'
  0b01101101, // '2'
  0b01111001, // '3'
  0b00110011, // '4'
  0b01011011, // '5'
  0b01011111, // '6'
  0b01110000, // '7'
  0b01111111, // '8'
  0b01111011, // '9'
  0b00000001, // '-'
  0b01001111, // 'E'
  0b00110111, // 'H'
  0b00001110, // 'L'
  0b01100111, // 'P'
  0b00000000  // ' '
  };

void init_led_pins(void)
{
  int j;

  for (j=0; j < 8; j++)
  {
    pinMode (segment_pin[j], OUTPUT);
    digitalWrite (segment_pin[j], 0);
  }

  for (j=0; j < num_digits; j++)
  {
    pinMode (common_pin[j], OUTPUT);
    digitalWrite (common_pin[j], 1);
  }
}

int timer_value (int hz)
{
   return F_CPU /prescaler/hz;
}

int get_duty_count(void)
{
  return timer_value (display_freq)/16*(control.duty_cycle+1);
}

void show_digit (byte digit)
{
  byte j;
  byte pattern;

  digit = digit & 0x07;
  pattern = digit_pattern [digit];
  for (j=0; j < 8; j++)
  {
    if ( pattern & 1 )
      digitalWrite (segment_pin[j], 1);
    else
      digitalWrite (segment_pin[j], 0);

    pattern >>= 1;
  }
}

ISR(TIMER1_OVF_vect)        // interrupt service routine
{
  TCNT1 = timer1_counter;   // preload timer
  OCR1A = timer1_counter + get_duty_count();

  //digitalWrite (common_pin[next_digit], 1);

  if (!control.shutdown)
  {
    if (next_digit == control.digits_displayed)
      next_digit = 0;
    else
      next_digit++;
    //
    if (control.decode_mode & (1<< next_digit))
      digit_pattern[next_digit] = rom_digit_pattern [digit_data [next_digit] & 0x0F];
    else
      digit_pattern[next_digit] = digit_data [next_digit];

    show_digit (next_digit);
    digitalWrite (common_pin[next_digit], 0);
  }
}

ISR(TIMER1_COMPA_vect)
{
  digitalWrite (common_pin[next_digit], 1);
}

void process_command (void)
{
  byte index;

  index = spi_buf[0] & 0x0F;
  switch (index)
  {
    case 0: break; // no-op
    case 9:
      control.decode_mode = spi_buf[1];
      break;
    case 10:
      control.duty_cycle = spi_buf[1] & 0x0F;
      break;
    case 11:
      control.digits_displayed = spi_buf[1] & 0x0F;
      if (control.digits_displayed > num_digits-1)
        control.digits_displayed = num_digits-1;
      break;
    case 12:
      control.shutdown = (spi_buf[1] & 1) == 0;
      break;
    case 15:
      control.display_test = (spi_buf[1] & 1) == 1;
      break;
    default:
      if (index<=8)
      {
        digit_data[index-1] = spi_buf[1];
      }
  }

}

// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register

  spi_buf [spi_pos++] = c;

  // process buffer
  if (spi_pos == 2)
  {
    process_command();
    spi_pos = 0;
  }
} 

void setup() {

  control.shutdown = 1;
  next_digit = 0;

  init_led_pins();

  // initialize timer1
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  prescaler = 64;
  TCCR1B |= (1 << CS11)|(1 << CS10);    // set prescaler
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  TIMSK1 |= (1 << OCIE1A);   // 

  // Set timer1_counter to the correct value for our interrupt interval
  timer1_counter = 65536-timer_value (display_freq);

  TCNT1 = timer1_counter;   // preload timer
  OCR1A = timer1_counter + get_duty_count();

  // SPI setup
  // we send on master in, *slave out*
  pinMode(MISO, OUTPUT);

  // turn on SPI in slave mode
  SPCR = _BV(SPE);

  // get ready for an interrupt
  spi_pos = 0;   // buffer empty

  // now turn on interrupts
  // SPCR |= _BV(SPIE);
  SPI.attachInterrupt();

  interrupts();             // enable all interrupts
}

void loop() {
  // driven by interrupts
}

It is an Arduino sketch, but should be easily portable to any mega328. It doesn't implement all the features, and I am sure it has performance limits compared to the real thing.

 

If you are willing to exceed specs, you can even drive a display without external driver, but I think would probably use ULN2803A or similar. The Arduino on the right is an SPI master, running a standard 7seg demo. On the left, is the MAX7219 simulator directly driving 4 x 7 seg.

 

IMG_0133

 

 

Bob. Engineer and trainee Rocket Scientist.

Last Edited: Thu. Jun 15, 2017 - 01:47 PM