Driving 2 groups of 5 7 segment displays

Hi,

I am Try to create two counters. I think I have got the counter part sorted as they now work as expected where they are broken down into individual digits that fit onto a single display but the part that I am currently struggle is to actually get that data to be display correctly. They are common Anode displays with the segments driven by two unl2003a chips, one for each row/counter. The Anode pins for each row are joined and connected an AVQ252G.

on my latest attempt I seem to have just two 0 displayed on the 1st and 4th digits while the others are not displaying anything at all.

/*
 * First draft for configuring 7 segment displays as part of counter project
 *
 * The Hardware consist of two banks of 5 seven segment displays, each row is controlled seperately by its
 * own matrice. The type used for this project are common anode. A prototyping board is used to arrange the 
 * connections from the Arduino into 3 jst connnects. The anode connections are brought out in the first 
 * header. The other two provide the individual segment connections for each row respectively.
 * connector provides the the annodes for all the displays. The other two provide the individual segment
 * connections for each row respectively. currently this just checks for input and increments the counter.
 * Once first stage testing has been done a reeal time clock will need to be factored in so that the daily
 * count resets. Finally got work as intended however there are issues refreshing the display fast enough
 * so may need to rethink and impment a timer instead.
 *
 * The mapping is as follows
 *
 * Connector 1 [Common Anodes]:
 *  
 * D16 | PH1 | 6
 * D6  | PH3 | 7
 * D7  | PH4 | 8
 * D8  | PH5 | 9
 * D9  | PH6 | 10
 *  
 *  
 * 
 * |ROW1_D1|ROW1_D2|ROW1_D3|ROW1_D4|ROW1_D5|
 * -----------------------------------------
 * |ROW2_D1|ROW2_D2|ROW2_D3|ROW2_D4|ROW2_D5|
 * 
 * Connector 2 [Row 1 segment connections]:
 * 
 * Pin | Port|Segment
 * D31 | PC6 | a
 * D32 | PC5 | b
 * D33 | PC4 | c
 * D34 | PC3 | d
 * D35 | PC2 | e
 * D36 | PC1 | f
 * D37 | PC0 | g
 * 
 * 
 * 
 * |D31 - PC6|D32 - PC5|D33 - PC4|D34 - PC3|D35 - PC2|D36 -PC1|D37 - PC0|
 * ----------------------------------------------------------------------
 * 
 * Connector 3 [Row 2 segment connections]:
 *
 *Pin | Port|Segment
 * D43 | PL6 | a
 * D44 | PL5 | b
 * D45 | PL4 | c
 * D46 | PL3 | d
 * D47 | PL2 | e
 * D48 | PL1 | f
 * D49 | PL0 | g
 * 
 * 
 * 
 */

#include <TimerOne.h>
 
 /* Variables to handle the display data */

//Format as a,b,c,d,e,f,g, dot

//number, in the format 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9
volatile byte numbers[10]={0x7E,0x30,0x6D,0x79,0x33,0x5B,0x5F,0x70,0x7F,0x73};

volatile byte row_sel[5]={0x02,0x08,0x10,0x20,0x40}; //Cycle through each column
volatile byte seg_reset = 0x00; //clear all outputs before going to the display

//volatile byte filter;
//volatile byte output;
volatile int seg_num = 0; //hold the current position of the display

volatile int pos;

unsigned long display_counter;
unsigned long display_counter_past;

volatile bool switch_digit = false;

int day_unit = 0;
int day_ten = 0;
int day_hun = 0;
int day_thou = 0;
int day_ten_thou = 0;

int tot_unit = 0;
int tot_ten = 0;
int tot_hun = 0;
int tot_thou = 0;
int tot_ten_thou = 0;

//Store the digit data into five columns to match the number of displays that we have.
volatile int display_data[2][5]={{day_unit, day_ten, day_hun, day_thou, day_ten_thou},  //Hold the data for the daily counter
                                 {tot_unit, tot_ten, tot_hun, tot_thou, tot_ten_thou}}; //Hold the data for the total counter

long int daily_counter;
long int daily_counter_prev;
long int total_counter;

 
/* Variables to deal with our input sources */

const int trigger1 = 18;
const int trigger2 = 19;
const int reset_but = 2; //place holder for RTC impelemention later

//int trig1_prev = HIGH;
//int trig2_prev = HIGH;

//unsigned long trig1_tracker; 
//unsigned long trig2_tracker; 

//unsigned long debounceDelay = 100;
  
//bool trig1_state;
//bool trig2_state; 


void setup() {
  // put your setup code here, to run once:

  //DDRE |= 0b00111011; //Matrix the Annode pin to control a whole column effectively
  DDRH |= 0xFA; //Config annode pins shared by each row of displays 
  DDRC |= 0x7F; //configure segement pins for daily counter
  DDRL |= 0X7F; //configure segement pins for daily counter

  Timer1.initialize(15000);
  Timer1.attachInterrupt(display_ref); // blinkLED to run every 0.15 seconds

  //attachInterrupt(digitalPinToInterrupt(trigger1),tray_handler1, LOW);
  //attachInterrupt(digitalPinToInterrupt(trigger2),tray_handler2, LOW);
  //pinMode(trigger1, INPUT);
  //pinMode(trigger2, INPUT);
  //pinMode(reset_but, INPUT);

  Serial.begin(19200);
  Serial.println("initalising");
}

void loop() {

  /*
  
  int aLoaded = digitalRead(trigger1); //Final input may not be very clean so need to include some debounce handling as well

  // If the switch changed, due to noise or pressing:
  if (aLoaded != trig1_prev) {
    // reset the debouncing timer
    trig1_tracker = millis();
  }

  if ((millis() - trig1_tracker) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (aLoaded != trig1_state) {
        trig1_state = aLoaded;
 
    }

    

  }

  int bLoaded = digitalRead(trigger2); //Final input may not be very clean so need to include some debounce handling as well

  // If the switch changed, due to noise or pressing:
  if (bLoaded != trig2_prev) {
    // reset the debouncing timer
    trig2_tracker = millis();
  }

  if ((millis() - trig2_tracker) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (bLoaded != trig2_state) {
        trig2_state = bLoaded;
 
    }


  }

  if(trig1_state == LOW){

    Serial.print("Line 1 active: ");
    Serial.println(daily_counter);
    daily_counter++;
  }

  if(trig2_state == LOW){

    Serial.print("Line 2 active: ");
    Serial.println(daily_counter);
    daily_counter++;
  }

  */
  noInterrupts();
  int pos_loop = pos;
  Serial.println(pos_loop);
  interrupts();

  daily_counter++;

  delay(3000);
  
  fetch_daily();

  fetch_total();


}
    
void display_ref(void){

  //Write out our data store in the array to each of the digits
  
  for(pos;pos < 4;pos++){
    PORTC = seg_reset; //Clear any number before writing the digit

    PORTL = seg_reset;

    PORTH = seg_reset;
    
    PORTH = row_sel[pos]; //Prepare for next row
    
    PORTC = numbers[display_data[0][pos]]; //Print out each digit for the daily counter
    
    PORTL = numbers[display_data[1][pos]]; //Print out each digit for total counter

  }

  pos = 0; //Reset the cycle ready for the next loop

}


void process_data(int rowSel, long int counter){
  
  //Take data from the daily counter and break down into indivial numbers for each display
  //The row select is use to determine if we are process for the daily count or the total
  //count.

  
  int digit_5 =((counter/10000) % 10);  

  display_data[rowSel][4] = digit_5; //If the counter is 10,000 or great then assign a number to the 5th digit
  
  int digit_4 = ((counter/1000) % 10);

  display_data[rowSel][3] = digit_4;

  int digit_3 = ((counter/100) % 10);

  display_data[rowSel][2] = digit_3;

  int digit_2 = ((counter/10) % 10);

  display_data[rowSel][1] = digit_2;

  int digit_1 = (counter%10);
  
  display_data[rowSel][0] = digit_1;      

}

void fetch_daily(){


  if(daily_counter > 99999){

    daily_counter = 0; //Reset upon overflow
  }
  process_data(0, daily_counter);

  //Print statements themporary for debugging only
  Serial.println("TTH, TH, H, T, U");
  Serial.print(display_data[0][4]);
  Serial.print(",");
  Serial.print(display_data[0][3]);
  Serial.print(",");
  Serial.print(display_data[0][2]);
  Serial.print(",");
  Serial.print(display_data[0][1]);
  Serial.print(",");
  Serial.println(display_data[0][0]);

  daily_counter_prev = daily_counter;

}


void fetch_total(){

  if(total_counter == 0){

    total_counter == daily_counter;
    
  }

  else if(total_counter > 99999){

    total_counter = 0;
    
  }

  else{
    
    total_counter = total_counter + (daily_counter - daily_counter_prev);
    
  }

  process_data(1, total_counter);

  Serial.println("TTH, TH, H, T, U");
  Serial.print(display_data[0][4]);
  Serial.print(",");
  Serial.print(display_data[0][3]);
  Serial.print(",");
  Serial.print(display_data[0][2]);
  Serial.print(",");
  Serial.print(display_data[0][1]);
  Serial.print(",");
  Serial.println(display_data[0][0]);
} 

Grateful for any replies

Cheers

Ryzer

Posting a schematic not a frizzy picture would help us who do not do word problem help you. Define what display correctly is and what you are actually getting. Try writing some test code and light only one segment at a time and be sure that works first.

The scan went a bit bad, hopefully it should be clear enough. I have now since been able to get it working more or less but there is a small amount of ghosting going on along with 3 digits appearing brighter than the rest on the first row. from what I read else where suggest that this could be hardware related. I had to change the remove the for loop in the display ISR which wasnt working for some reason. I found that when using an if state it works.

/*
 * First draft for configuring 7 segment displays as part of counter project
 *
 * The Hardware consist of two banks of 5 seven segment displays, each row is controlled seperately by its
 * own matrice. The type used for this project are common anode. A prototyping board is used to arrange the 
 * connections from the Arduino into 3 jst connnects. The anode connections are brought out in the first 
 * header. The other two provide the individual segment connections for each row respectively.
 * connector provides the the annodes for all the displays. The other two provide the individual segment
 * connections for each row respectively. currently this just checks for input and increments the counter.
 * Once first stage testing has been done a reeal time clock will need to be factored in so that the daily
 * count resets. Finally got work as intended however there are issues refreshing the display fast enough
 * so may need to rethink and impment a timer instead.
 *
 * The mapping is as follows
 *
 * Connector 1 [Common Anodes]:
 *  
 * D16 | PH1 | 6
 * D6  | PH3 | 7
 * D7  | PH4 | 8
 * D8  | PH5 | 9
 * D9  | PH6 | 10
 *  
 *  
 * 
 * |ROW1_D1|ROW1_D2|ROW1_D3|ROW1_D4|ROW1_D5|
 * -----------------------------------------
 * |ROW2_D1|ROW2_D2|ROW2_D3|ROW2_D4|ROW2_D5|
 * 
 * Connector 2 [Row 1 segment connections]:
 * 
 * Pin | Port|Segment
 * D31 | PC6 | a
 * D32 | PC5 | b
 * D33 | PC4 | c
 * D34 | PC3 | d
 * D35 | PC2 | e
 * D36 | PC1 | f
 * D37 | PC0 | g
 * 
 * 
 * 
 * |D31 - PC6|D32 - PC5|D33 - PC4|D34 - PC3|D35 - PC2|D36 -PC1|D37 - PC0|
 * ----------------------------------------------------------------------
 * 
 * Connector 3 [Row 2 segment connections]:
 *
 *Pin | Port|Segment
 * D43 | PL6 | a
 * D44 | PL5 | b
 * D45 | PL4 | c
 * D46 | PL3 | d
 * D47 | PL2 | e
 * D48 | PL1 | f
 * D49 | PL0 | g
 * 
 * 
 * 
 */

#include <TimerOne.h>
 
 /* Variables to handle the display data */

//Format as a,b,c,d,e,f,g, dot

//number, in the format 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9
volatile byte numbers[10]={0x7E,0x30,0x6D,0x79,0x33,0x5B,0x5F,0x70,0x7F,0x73};

volatile byte row_sel[5]={0x02,0x08,0x10,0x20,0x40}; //Cycle through each column
volatile byte seg_reset = 0x00; //clear all outputs before going to the display

//volatile byte filter;
//volatile byte output;

volatile int pos;

int day_unit = 0;
int day_ten = 0;
int day_hun = 0;
int day_thou = 0;
int day_ten_thou = 0;

int tot_unit = 0;
int tot_ten = 0;
int tot_hun = 0;
int tot_thou = 0;
int tot_ten_thou = 0;

//Store the digit data into five columns to match the number of displays that we have.
volatile int display_data[2][5]={{day_unit, day_ten, day_hun, day_thou, day_ten_thou},  //Hold the data for the daily counter
                                 {tot_unit, tot_ten, tot_hun, tot_thou, tot_ten_thou}}; //Hold the data for the total counter

long int daily_counter;
long int daily_counter_prev;
long int total_counter;

 
/* Variables to deal with our input sources */

const int trigger1 = 18;
const int trigger2 = 19;
const int reset_but = 2; //place holder for RTC impelemention later

//int trig1_prev = HIGH;
//int trig2_prev = HIGH;

//unsigned long trig1_tracker; 
//unsigned long trig2_tracker; 

//unsigned long debounceDelay = 100;
  
//bool trig1_state;
//bool trig2_state; 


void setup() {
  // put your setup code here, to run once:

  //DDRE |= 0b00111011; //Matrix the Annode pin to control a whole column effectively
  DDRH |= 0x7A; //Config annode pins shared by each row of displays 
  DDRC |= 0x7F; //configure segement pins for daily counter, decimal point NC so output for this is not needed
  DDRL |= 0X7F; //configure segement pins for total counter

  Timer1.initialize(2000); //Refresh a digit every 0.02 seconds, for some reason for loops do not apppear to function in an interrupt
  Timer1.attachInterrupt(display_ref); 

  //attachInterrupt(digitalPinToInterrupt(trigger1),tray_handler1, LOW);
  //attachInterrupt(digitalPinToInterrupt(trigger2),tray_handler2, LOW);
  //pinMode(trigger1, INPUT);
  //pinMode(trigger2, INPUT);
  //pinMode(reset_but, INPUT);

  Serial.begin(19200);
  Serial.println("initalising");
}

void loop() {

  /*
  
  int aLoaded = digitalRead(trigger1); //Final input may not be very clean so need to include some debounce handling as well

  // If the switch changed, due to noise or pressing:
  if (aLoaded != trig1_prev) {
    // reset the debouncing timer
    trig1_tracker = millis();
  }

  if ((millis() - trig1_tracker) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (aLoaded != trig1_state) {
        trig1_state = aLoaded;
 
    }

    

  }

  int bLoaded = digitalRead(trigger2); //Final input may not be very clean so need to include some debounce handling as well

  // If the switch changed, due to noise or pressing:
  if (bLoaded != trig2_prev) {
    // reset the debouncing timer
    trig2_tracker = millis();
  }

  if ((millis() - trig2_tracker) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (bLoaded != trig2_state) {
        trig2_state = bLoaded;
 
    }


  }

  if(trig1_state == LOW){

    Serial.print("Line 1 active: ");
    Serial.println(daily_counter);
    daily_counter++;
  }

  if(trig2_state == LOW){

    Serial.print("Line 2 active: ");
    Serial.println(daily_counter);
    daily_counter++;
  }

  */
  noInterrupts();
  int pos_loop = pos;
  Serial.println(pos_loop);
  interrupts();

  daily_counter++;

  delay(3000);
  
  fetch_daily();

  fetch_total();


}
    
void display_ref(void){

  //Write out our data store in the array to each of the digits
    
  PORTC = seg_reset; //Clear any number before writing the digit

  PORTL = seg_reset;

  PORTH = seg_reset;
    
  PORTH = row_sel[pos]; //Prepare for next row
    
  PORTC = numbers[display_data[0][pos]]; //Print out each digit for the daily counter
    
  PORTL = numbers[display_data[1][pos]]; //Print out each digit for total counter

  pos++;
  
  if(pos > 4){

      pos = 0; //Reset the cycle ready for the next loop

  }

}

void fetch_daily(){


  //TODO - Add mechnanism that resets the counter when the day has changed
  
  if(daily_counter > 99999){

    daily_counter = 0; //Reset upon overflow
  }
  process_data(0, daily_counter);

  Serial.print("daily ");
  Serial.println(daily_counter);
  
  //Print statements themporary for debugging only
  Serial.println("TTH, TH, H, T, U");
  Serial.print(display_data[0][4]);
  Serial.print(",");
  Serial.print(display_data[0][3]);
  Serial.print(",");
  Serial.print(display_data[0][2]);
  Serial.print(",");
  Serial.print(display_data[0][1]);
  Serial.print(",");
  Serial.println(display_data[0][0]);

  daily_counter_prev = daily_counter;

}


void fetch_total(){

  //TODO - find why it seems to result in 0
  
  total_counter = total_counter + (daily_counter - daily_counter_prev);
  
  if(total_counter > 99999){

    total_counter = 0;
    
  }

  Serial.print("Total ");
  Serial.println(total_counter);

  process_data(1, total_counter);

  Serial.println("TTH, TH, H, T, U");
  Serial.print(display_data[1][4]);
  Serial.print(",");
  Serial.print(display_data[1][3]);
  Serial.print(",");
  Serial.print(display_data[1][2]);
  Serial.print(",");
  Serial.print(display_data[1][1]);
  Serial.print(",");
  Serial.println(display_data[1][0]);
} 

void process_data(int rowSel, long int counter){
  
  //Take data from the daily counter and break down into indivial numbers for each display
  //The row select is use to determine if we are process for the daily count or the total
  //count.

  
  int digit_5 =((counter/10000) % 10);  

  display_data[rowSel][4] = digit_5; //If the counter is 10,000 or great then assign a number to the 5th digit
  
  int digit_4 = ((counter/1000) % 10);

  display_data[rowSel][3] = digit_4;

  int digit_3 = ((counter/100) % 10);

  display_data[rowSel][2] = digit_3;

  int digit_2 = ((counter/10) % 10);

  display_data[rowSel][1] = digit_2;

  int digit_1 = (counter%10);
  
  display_data[rowSel][0] = digit_1;      

}


Your AVG 252G spend about 0.5 ms to turn off and about 1 ms to turn on. You could use a P-channel MOSFET, it should work just fine with an arduino. Also simpler to wire.

Hi @ryzer

Can you explain why you designed your circuit as you did, and choose these components? The circuit seems over-complex, your code is certainly more complex than it needs to be, and the problems you face are commonly encountered when 7-seg driver circuits are designed by beginners.

I would recommend using an ht16k33 module. One of these could drive all 10 of your displays with absolutely no additional components. Your code would be much simpler also, and "ghosting" and uneven digit brightness would be eliminated.

Because this module is designed for common cathode displays, and you have common anode, some slightly tricky lines of code would be needed, but the forum can help you with those.

s-l400 (7)

This is not nice:

  noInterrupts();
  int pos_loop = pos;
  Serial.println(pos_loop); // put this statement after interrupts()
  interrupts();

Also you could optimise here as marked:

  PORTH = seg_reset;
    
  PORTH = row_sel[pos]; //Prepare for next row // This should be moved after the PORTC/PORTL update to minimise ghosting
    
  PORTC = numbers[display_data[0][pos]]; //Print out each digit for the daily counter
    
  PORTL = numbers[display_data[1][pos]]; //Print out each digit for total counter

EDIT

Because of the relatively long switching times of the display anodes because of the AVG 252G devices (as pointed out in post #4) you should increase the timer period to the maximum without causing noticeable flicker ( maybe 4ms). This is to minimise switching losses. Since you seem to like transistor arrays, you could also use a high side driver such as the MIC2981 (UDN2981) etc. instead.

Hi,

The primary reason of the layout is to be compatible with an already made up cluster of SA40-19SGWA 7 displays that I will use once I get things working more smoothly with the current displays ONLY acting as placeholders. The display connections are almost identical to my schematic, the only difference being that all the anode connections on the display are brought out individually on an 10 pin ide header. Components used are just what I had immediately available in my trays of parts.

Thanks for the suggestion, I did think about getting two MAX7219's to drive each row but unfortunately it looks like they only operate up to 5V. Ideally the driver will need to support a supply voltage of 12V.

Thanks

Ryzer

Hi @6v6gt ,

This sections was purely for diagnostic purposes. I just wanted to check that the position of the active segment was changing. It can probably be removed now. The problem I was having that when trying run the whole display, the increment function did not appear to be working as it seemed like it was stuck on 0 so for now it just goes through a single display each time the ISR is called.

noInterrupts();
  int pos_loop = pos;
  Serial.println(pos_loop); // put this statement after interrupts()
  interrupts();

Interesting that you mention as when I was in the process of gradually dialling down the time between interrupts I did start to think that it was become more of apparent but at the time I just put it down to some other issue. I could try with some UDN2981a, the only difference with them being that I would have to set the pins low to activate the segments as far as I am aware.

OK.
(1) if you suspend interrupts to get a clean read of a variable, which could be updated in an ISR while you are reading it, then do it quickly. Adding things like Serial.print() in the protected block is asking for trouble since such functions may also rely on interrupts. Good that it is only a temporary measure.
(2) I don't believe there would be a change of logic here. The UDN2981 (or the MIC2981 which is more likely to be available) would drive the display anodes and a high (say 5v) input would give a high output.

EDIT
UDN2981 can still be got here (and maybe other places too) : UDN 2981: 8-Kanal-Hochspannungsquellentreiber, -500 mA, DIL-18 bei reichelt elektronik

Then you are guilty of wasting the forum member's time thinking about something that is not the true problem. You could not have mentioned this in your first post!?!

That's a good point. I have now removed the print statement and the variable copy as I no longer believe that I need it. Following your earlier advice I initial tried bumping up the time between interrupts but there was a slight bit of ghosting. Now that I have changed over to the UDN2981 as you also suggest that ghosting has now been eliminated :slight_smile:

The only thing that I now need to overcome is those brighter displays. I have had those resistor blocks for ages so they could probably be replaced with new resistors which should cure that.

Thanks again

Ryzer

I doubt that will help. Resistors do not wear out.

LEDs do wear out. Try swapping some of the displays. Are some brighter, no matter where they are on the breadboard? Or does that make no difference, and the displays at the some positions on the breadboard are always brighter? If the latter, the problem could be timing, because those LEDs are lit for longer during each multiplex cycle.

It's always helpful to include a link to the data sheet for components you plan to use, especially unusual ones.

If this were my project, I would drive each display with a tpic6b595 shift register + resistor pack. This would achieve maximum brightness because no multiplexing would be required. The shift registers could be chained so that only 3 Arduino pins are required to drive them. This would significantly reduce the wiring complexity between the displays and the Arduino.

If I wanted to reduce the component count at the expense of some reduction in brightness, I would use 2 tpic6c595, one each for the common cathodes on each row of displays, plus an extra tpic6c595 to drive 5 PNP transistors for the common anodes.

That is a fair point, I will remember that for next time.

In Regards to post 12


Looks like its the former. after swapping the top 3 around. None of them are brand new however 5/8 came out of seal packets in my storage boxes so you would have thought that there would be 5 bright displays would be bright and the rest dimmer rather than the other way around.

Currently using the mega so that is not to much of a problem, should have probably mention that a bit early on. I may switch to an UNO but haven't fully decided as of yet in which case I would probably employ shift registers such as above. The eventual aim is to create a circuit that would fit on a footprint no bigger than the mega prototyping board.

Another possibility is that the sealed/"new" displays are in fact older than the others, or were manufactured with older tech, meaning different/less advanced chemistry in the led segments, not as bright.

would it be safe to assume that the numbers printed on top are dates of manufacture given they are in the format 2011-05 for example? Also I just looked again at the labels and found that the brighter three are definitely the SA52-RWA's originally referenced https://www.kingbrightusa.com/images/catalog/SPEC/SA52-11SRWA.pdf although they appear to be older they are stated as super brights while the rest are actually similarly labelled SA52-11EWA https://www.kingbrightusa.com/images/catalog/SPEC/SA52-11SRWA.pdf which appears to have no mention of being super bright. :man_facepalming:

You posted the same link twice there!

The superbright version says typical brightness of 34000ucd @ 10mA. The "high efficiency" ones seem to be much lower at only 6400ucd @ 10mA.


This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.