30 pin 4 digit display

i have a "delay(5)" for display and no delay for the clear...if i decrease it any further...the display is not on long enough and it gets even dimmer. if I increase it to say delay( 8 )...it becomes way too flickery.

Can you post all of the current code please, so we can see exactly the context of what you are doing where?

below is my full code...i posted some explanation in a few posts previous to this in regards to some of the functions
basically for each digit, (except 1 and 7), it has to switch the high and low twice...with a delay(5) of between switches for displaying. this is done in "show_num"

Function descriptions:
show_num(a,b,c,d) - shows digits specified in args
clearSegments() - resets all pins to low
swapGround() - switches the voltages

clearRegisters() - resets registered pins to low
setRegisterPin() - set a register pin to high or low
writeRegisters() - update display with updated register

/*
Arduino pins 2,3,4,5,6,7 - (handling pins 16-21 from display)
Arduino pins 8, 9, 10 - 74HC595 8 bit shift register (handling 5,6,9,10,12,13,14,15 pins from display)
Arduino pin 11   - Two center dots (pin 30 from display)
Arduino pin 12, 13 - ground 1 (pin 1) + ground 2 (pin 2)
*/

//How many of the shift registers - change this
#define number_of_74hc595s 1 

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

int const ledLength = 6;

int ledPins[ledLength] = {2,3,4,5,6,7};
int dotsPin =  11;
int SER_Pin = 8;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 10; //pin 11 on the 75HC595

int ground1 = 12;
int ground2 = 13;



void setup(){
        for (int x=0; x<ledLength; x++){
          pinMode(ledPins[x], OUTPUT);
        }
       // Serial.begin(9600);
        pinMode(dotsPin, OUTPUT);
        pinMode(SER_Pin, OUTPUT);
        pinMode(ground1, OUTPUT);
        pinMode(ground2, OUTPUT);
        pinMode(RCLK_Pin, OUTPUT);
        pinMode(SRCLK_Pin, OUTPUT);
        pinMode(dotsPin, OUTPUT);

          //reset all register pins
       clearRegisters();
         writeRegisters();

}               

void show_num(int a,int b,int c,int d){
  //turn on dots
      clearSegments();
       swapGround(ground1);
       digitalWrite(dotsPin, HIGH);
       delay(5);
       
    switch (a){
      
    case 1:
      clearSegments();
      swapGround(ground2);
      setRegisterPin(5, HIGH); //with g2, 
      setRegisterPin(6, HIGH);
      writeRegisters();
       delay(5);
      break;
  }
  switch (b){
   case 0:
    clearSegments();
    swapGround(ground1);
    //bottom right
    setRegisterPin(2, HIGH); //with g2
    //setRegisterPin(4, HIGH); //with g2
    setRegisterPin(3, HIGH); //with g2
    setRegisterPin(5, HIGH); //with g2
    writeRegisters();
     delay(5);
     
    clearSegments();
    swapGround(ground2);
    //bottom right
     setRegisterPin(2, HIGH); //with g2
    setRegisterPin(3, HIGH); //with g2
     setRegisterPin(4, HIGH); //with g2
    writeRegisters();
       delay(5);  
    case 1:
      clearSegments();
      swapGround(ground2);
      setRegisterPin(3, HIGH); //with g2, 
      setRegisterPin(4, HIGH);
      writeRegisters();
       delay(5);
      break;
    case 2:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(3, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(5, HIGH);
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
    case 3:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(3, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
    case 4:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
   case 5:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
       setRegisterPin(2, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
     case 6:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      setRegisterPin(5, HIGH); //with g2
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
       setRegisterPin(2, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
   case 7:
      clearSegments();
      swapGround(ground2);
      //bottom right
       setRegisterPin(2, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
       setRegisterPin(4, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
    case 8:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      setRegisterPin(5, HIGH); //with g2
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
       setRegisterPin(2, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
       setRegisterPin(4, HIGH); //with g2
      //setRegisterPin(5, HIGH); //with g2
      writeRegisters();
       delay(5);  
    case 9:
      clearSegments();
      swapGround(ground1);
      //bottom right
      setRegisterPin(2, HIGH); //with g2
      setRegisterPin(4, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
      writeRegisters();
       delay(5);
       
      clearSegments();
      swapGround(ground2);
      //bottom right
       setRegisterPin(2, HIGH); //with g2
      setRegisterPin(3, HIGH); //with g2
       setRegisterPin(4, HIGH); //with g2
      writeRegisters();
       delay(5);
      break;
  }
  switch (c){
    case 1:
      clearSegments();
      swapGround(ground2);
      digitalWrite(ledPins[2], HIGH);
      setRegisterPin(0, HIGH);
      writeRegisters();
       delay(5);
      break;
  }
  switch (d){
    case 1:
    clearSegments();
    swapGround(ground1);
    digitalWrite(ledPins[5], HIGH);
    digitalWrite(ledPins[2], HIGH);
    delay(5);
    break;
  }
}
int x_=0;
int start = millis();
void loop(){
 
  /*
 //loop numbers
   x_= int(millis()/1000)%10;
   show_num(0,x_,1,1);
*/

show_num(1,7,1,1);
 
}

//set all register pins to LOW
void clearRegisters(){
  for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers[i] = LOW;
  }
} 
void clearSegments(){
//turn off normal pin leds
for (int x=0; x<ledLength; x++){
      digitalWrite(ledPins[x], LOW);
}
      digitalWrite(dotsPin, LOW);
      clearRegisters();
      writeRegisters();
      
}

void swapGround(int gr){

      if (gr==ground1){
        //  Serial.println("switched to ground 1");
         digitalWrite(ground1, LOW);
         digitalWrite(ground2, HIGH);
      }
      else if (gr==ground2){
         //Serial.println("switched to ground 2");
         digitalWrite(ground2, LOW);
         digitalWrite(ground1, HIGH);
      }
}
//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

  digitalWrite(RCLK_Pin, LOW);

  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    int val = registers[i];

    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);

  }
  digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
  registers[index] = value;
}

What is the purpose of this first delay?

void show_num(int a,int b,int c,int d){
  //turn on dots
  clearSegments();
  swapGround(ground1);
  digitalWrite(dotsPin, HIGH);
  delay(5);    // <---------------- this one

Also I suggest you change all that delay(5) to delay(delayTime) where delayTime is a constant. That will make it much easier to tweak the delays.

const byte delayTime = 5;

thats for the 2 dots, in the middle.. they will always be displayed. and true that about the constant, ive been meaning to do so.

It seems to me to be a bit convoluted. Why clear the registers each time? Just have a pattern per digit, and send that pattern out. I suggest you want an array per digit, (off/on/off/off/on etc.) and for a particular digit just output the array contents.

standard 4 display

I understand that, which will work for a standard 4 segment schematic like above..but if im not mistaken...

this 4 digit display

..this one's input/output isn't seperated logically per segment and you really need to be continually swapping the voltage for each number..thus a costant need to refresh the screen. im new to this, but please let me know if im incorrect in this

It's the same thing isn't it? Except the anodes and cathodes are around the other way.

All I am saying is your method of setting the voltages seems unnecessarily long.

You can not connect the two ground pins directly to the arduino pins or the shift register pins. This is because they carry the current for a whole bunch of segments. This is too much and so needs buffering with a transistor.
What value of resistors are you using for each segment? Do not say you are not using resistors please.

I didn't connect resistors because in the alarm clock I ripped it out of , it went straight from this display to microcontroller. The display is on its own board , so I assume the resistors are there under the display?

Otherwise would I connect the led display pins to resistor to power (arduino pins)? I'm new but I thought resistors were always in between ground and cathode of led no?

How would I buffer with the transistor?

Right now the display is working properly, it's just not as bright as I would
Like it...but maybe this is just the way it is due to delays?

in the alarm clock I ripped it out of , it went straight from this display to microcontroller.

Chuck it up, our leds-have-to-have-resistors god/godess, :slight_smile:

There must be a way to simplify your code: it is too complicated. If you think about it, you are essentially driving "two digits". So there must be ways to arrange the pins so that there is some consistency between those digits.

Please ignore dhenry he is the forums equivalent of a village idiot.

It is unlikely you have built in resistors, the original display could have had a constant current driver so not requiring resistors.
Using a transistor for a buffer is easy, see the first diagram in this link:-
http://www.thebox.myzen.co.uk/Workshop/Motors_1.html
It is likely that the poor brightness is due to lack of a proper driver trying to force too much current down a pin.
Try and simplify the code, have you read:-
http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

I just double checked and there is 3 39ohm resistors (I think?) on the 2 grounds (pin 1 and 2) and the 5th pin...

Are you sure? It is a bad idea having resistors on the ground. This is because it can take the current from several segments depending on what is displayed. Therefore the current / brightness changes depending on what is being displayed.

THANKS GUYSI got it to working pretty bright! dhenry, the "2 digits" remark got me thinking.

I rewrote the way it worked, so that you basicially call a function show_num(a,b,c,d) and then it will slowly build the segments to light up on pin 1 in an array and the same for one on pin 2..then at the end it displays each with a small delay in between! less delays, so more bright. video and code below

code available here: http://codeviewer.org/view/code:2dc5

@grumpy_mike,well im not entirely sure about the resistors because im just looking at the old alarmclock circuit board.. in theirs..they have ground to pin 1 and actually vcc to pin 2...and then 2 39ohm resistors, one between each ...the ground also has a diode on it...a little confusing for a newbie like me. below is an image

this is what im doing below..im still a bit confused on the transistor in terms of where it would go

[quote]code available here:[/quote]

the show_nm() seems to be very complicated.

I would do something like this:

void led_display(void) {
  static unsigned char current_num=0; //current number to be displayed. 0=left most, 1=right most
  turn_off_all_digits(); //by pulling the two ground pins high
  switch (current_num) {
    case 0: show_num0(); current_num=1; break; //display num0
    case 1: show_num1(); current_num=2; break; //display num1
    case 2: show_num2(); current_num=3; break; //display num2
    case 3: show_num3(); current_num=4; break; //display num3
    case 4: show_dot(); current_num=5; break; //display dot
    case 5: show_dotx2(); current_num=0; break; //display doublt dot
    default: current_num=0;
  }
}

show_numx() can be implemented separately, or if needed, can be implemented here.

I would also use a display buffer for the content, and a look_up table that maps the digits into segment information, for speed and flexibility.

Hello,

I happened to have a similar LCD lying around, so decided to give it a try. I am only using the third and fourth segment though, as I do not have a 74HC595, and limited pins on the Arduino Uno.

It seems to work fine, and I'm planning to use this to display sensor output (e.g. temperature) in the future.

I have some questions on the transistor part though:

  • Are the PNP transistors wired up correctly?
    In fact, in this case, the transistors seem overkill; I did some current measurements, and current out of LCD pins 1 and 2 never seemed to exceed 15mA. It seems to work fine without transistors as well. Any feedback appreciated.
  • Is it necessary to put an additional resistor between the Arduino pins (12 and 13) and the PNP transistor bases? According to Arduino Forum, I should. Again, in this case it seems overkill, as the currents I measured at the base were in the order of 1mA.

Attached a Fritzing schematic and the full code.

Any feedback would be greatly appreciated!

LCDv2.ino (2.88 KB)

Replying to my own (old) question.

  1. As the LCD pin current (15mA) seems to stay well below the maximal allowable pin current of an arduino pin (40mA), it seems safe to hook things up without transistors.

  2. It is good practice to put a resistor between an arduino pin and a PNP transistor base, to limit the amount of current sunk into the arduino pin (or, in case of NPN transistor, drawn from the arduino pin).

You also need to consider the total current draw, not just individual pins, however in your case you seem to be within the limits.