Go Down

Topic: Hi. Control 24V LED strip by Multiplexing. HELP Please!! (Read 1 time) previous topic - next topic

PaulRB

@Bigtimer, you do realise that while all this transistor stuff is interesting and educational, you won't need it when your tpic chips arrive?

Bigtimer

yeah i understand that. i'm working on that circuit now, trying to figure it out. do you have a circuit in mind that i could copy possibly?

i'm using  fritzing, never used it before


Grumpy_Mike

Quote
i'm using  fritzing, never used it before
Never use it again. The results are useless unless you know how to drive it correctly and most people, and all beginners don't know how.

Just carry on with the pencil & paper. That last diagram was better. What you failed to do was to have positive at the top and negitave at the bottom. To anyone trying to read it, it looks upside down.

As to a base resistor you need to make the base current about one tenth of the collector current to ensure it turns on fully. This is called getting the transistor to saturate.

The integrated circuit in the middle however, is not how you draw things like that. Yes use a rectangle, but don't lay it out as if it were a physical chip. Draw the connections at a location on the box that makes the wiring as simple as possible and then label the pin number and the name of the pin. The object is to minimise the number of wires that cross each other.

PaulRB

The circuit from the Instructables page is not too bad as a place to start:

Corrections to that:
  • 0.1uF ceramic bypass caps for each chip (between 5V and ground, physically close to the chip)
  • Don't chain the grounds as shown, connect each ground pin directly to ground
  • You won't need the series resistors as they are already built-in to your strips.
  • The connections between the series resistors and the tpic pins have been drawn badly. It looks as though 4 led/resistor pairs are connected together and connected to 4 tpic pins. But in practice each resistor/led pair should be connected to a separate tpic pin. In your case, each strip is connected to a separate tpic pin.
  • You don't have to use the Arduino pins used above, you can use any you like and use the shiftOut() function. The advantage to using the pins shown is that the Arduiino's hardware SPI function can be used. But that's not really important for a 4-digit display which only needs updating once per second. If the display had 400 digits or needed to be updated 400 times per second, then using the hardware SPI would be a significant advantage.
  • If you do not need to dim the display, you can connect the OE pins directly to ground, saving an Arduino pin.

Bigtimer

Ok guys, here we  go.

I have changed the Circuit slightly to do what I think I need. does this look like it would work?

i have missed out a few things that i am unsure of


Quote
0.1uF ceramic bypass caps for each chip (between 5V and ground, physically close to the chip)
not really sure where i need to put it

Quote
If you do not need to dim the display, you can connect the OE pins directly to ground, saving an Arduino pin.
this will be connected to ground on the next drawing. i don't need to dim it for the moment  

Grumpy_Mike

#35
Nov 19, 2018, 09:29 pm Last Edit: Nov 19, 2018, 09:33 pm by Grumpy_Mike
Quote
not really sure where i need to put it
You were told:-
Quote
between 5V and ground, physically close to the chip
What do you not understand about that?

Quote
i don't need to dim it for the moment  
When you do need to dim then all LEDs will dim at the same rate, you do not have individual control over the brightness of the LEDs.

Your Circuit:-

You need capacitors on both sides of the regulator. User a 47uF and 0.1 uF ceramic in parallel on each side.

You need to connect all the grounds on the shift register chips.

Paul__B

A Mega is gross overkill for this.  A Nano would be more practical.

Bigtimer

Yes i know the Mega is a little overkill but it's all i have on hand at the moment.

I've amended the circuit dose this look right?


Now I just need help with the Code that will run this bad boy.

i'm looking to make just simple timer. counting down in minutes and seconds. I had it working with a  multiplexed display. but now i've switched over to this shift register system i don't know how to change it  



PaulRB

Quote
had it working with a  multiplexed display. but now i've switched over to this shift register system i don't know how to change it  
I think you already have the ingredients. You have the timer sketch for the multiplexed display, and you have that sketch from post #24 that uses shiftOut().

Have a go at updating your timer sketch to use shiftOut() and post the sketch if you get stuck. The resulting sketch should be simpler than before because it does not need to multiplex the display.

With the multiplexed display, the sketch has to send out data for the display 100+ times per second, one digit at a time, so that the whole display gets updated 25+ times per second so the eye does not see flickering.

With a non-multiplexed display, the sketch simply needs to send the data for all 4 digits out, just once, and only when the data has changed. With 4 chained tpic chips, your sketch will need 4 X shiftOut() before it triggers the latch pin.

Grumpy_Mike

#40
Nov 19, 2018, 11:46 pm Last Edit: Nov 19, 2018, 11:47 pm by Grumpy_Mike
Yes a lot better. You have missed the 5V label off the Arduino. The other thing is that the symbol for your LED strip don't show there is a current limiting resistor in the strip.

I am not sure if there is a official symbol for an LED strip. I would propose something like this:-

Wawa

Now I just need help with the Code that will run this bad boy.
Gave you a hint in post#23.
Leo..

Bigtimer

Ok so i am finding this really difficult. And really am butchering things together as i have no idea really.

Is this the part of the code that displays the numbers?

Code: [Select]
void showdigit (int digit)

{
 
 switch (digit) {
 
 case 0:
 digit0 ();
 break;
 
 case 1:
 digit1 ();
 break;
 
 case 2:
 digit2 ();
 break;
 
 case 3:
 digit3 ();
 break;
 
 case 4:
 digit4 ();
 break;
 
 case 5:
 digit5 ();
 break;
 
 case 6:
 digit6 ();
 break;
 
 case 7:
 digit7 ();
 break;
 
 case 8:
 digit8 ();
 break;
 
 case 9:
 digit9 ();
 break;
 
 default:

 
 
 break;
 
 
 
 };

};


// showing 4 digits
//  not only shows 4 digit number, but also there is option to turn on
//only selected digits and decimal point.

void showdigits (int number, char digit_on, char  decimal_point)
{

 

digitalWrite(GND4, LOW);
  // e.g. we have "1234"
showdigit(number/1000);  // segments are set to display "1"
if (decimal_point&8) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&8) {
digitalWrite(GND1, HIGH); // first digit on,
digitalWrite(GND2, LOW); // other off
digitalWrite(GND3, LOW);
 }
 delay (1);


number = number%1000;  // remainder of 1234/1000 is 234
digitalWrite(GND1, LOW); // first digit is off
 showdigit(number/100); //// segments are set to display "2"
if (decimal_point&4) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&4) {
digitalWrite(GND2, HIGH); // second digit is on
  } delay (1);// and so on....
 
number =number%100;   
digitalWrite(GND2, LOW);
showdigit(number/10);
if (decimal_point&2) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&2) {
digitalWrite(GND3, HIGH);
 }
 delay (1);

number =number%10;
digitalWrite(GND3, LOW);
showdigit(number);
if (decimal_point&1) {digitalWrite(DP, HIGH);} else {digitalWrite(DP, LOW);};
 if (digit_on&1) {
digitalWrite(GND4, HIGH);
  }
  delay (1);

};


Code: [Select]
if (set_mode) {if (Sec==60) {Sec=00;}

 if (Min==100) {Min=0;} }

     
       else {
 
 if (Sec==-1) {Min--;Sec=59;}
 
 } 
 
 
//decimal point indication control

if (!set_mode) {
 
 
  if (!(Sec%2)) { showdigits (Min*100+Sec,0x0F,0x04); } //0X00

else  {showdigits (Min*100+Sec,0x0F,0x00); }; //0000

} else {
 
  if (set_mode==1) {
 
  showdigits (Min*100+Sec,0x0F,0x0C);   //XX00
                                } else {
                     
                     
                     
                     showdigits (Min*100+Sec,0x0F,0x03);      } //00XX

}
if (run) {  // to do while timer is running; e.g. control relay
//////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////
digitalWrite(LED, HIGH);


} else digitalWrite(LED, LOW);



if ((Min==0)&&(Sec==0)&&run) {
run=0;
TCCR1B=0x00; //stop timer


How on earth do i translate that into something a shift register can read so fare I have manage to do this .

Bigtimer

This is what ive made so fare. don't think it could ever work though.

Code: [Select]

};
void loop ()

{

for (int Sec=59; Sec>=0; Sec--)
 {
   digitalWrite(latchpin, LOW);
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the right display
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the left display
   digitalWrite(latchpin, HIGH);
   if (Sec<10)
   {
     digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[Sec]); // sends the digit down the serial path
     shiftOut(datapin, clockpin, LSBFIRST, 255); // sends a blank down the serial path to push the digit to the right
     digitalWrite(latchpin, HIGH);
   }
   else if (Sec>=10)
   {
     d=Sec%10; // find the remainder of dividing z by 10, this will be the right-hand digit
     c=int(d); // make it an integer, c is the right hand digit
     b=Sec/10; // divide z by 10 - the whole number value will be the left-hand digit
     e = int(b); // e is the left hand digit
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[c]);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[e]);
     digitalWrite(latchpin, HIGH);
   }
   delay(speed);
 }
 for (int Min=99; Min>=0; Min--)
 {
   digitalWrite(latchpin, LOW);
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the right display
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the left display
   digitalWrite(latchpin, HIGH);
   if (Min<10)
   {
     digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[Min]); // sends the digit down the serial path
     shiftOut(datapin, clockpin, LSBFIRST, 255); // sends a blank down the serial path to push the digit to the right
     digitalWrite(latchpin, HIGH);
   }
   else if (Min>=10)
   {
     z=Min%10; // find the remainder of dividing z by 10, this will be the right-hand digit
     q=int(z); // make it an integer, c is the right hand digit
     p=Min/10; // divide z by 10 - the whole number value will be the left-hand digit
     f = int(p); // e is the left hand digit
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[q]);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[f]);
     digitalWrite(latchpin, HIGH);
   }
   delay(speed);
 }
 


 //////////// button_start//////////

Bigtimer

I'm having a look at that code now leo.

how should i implement it?

Code: [Select]
byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void setup()
{
  Serial.begin(9600);
  Serial.println("Large Digit Driver Example");

  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);

  int x = 0;
  while(1)
  {
    if(x == 9)
      postNumber(x, true); //Show decimal
    else
      postNumber(x, false);

    digitalWrite(segmentLatch, LOW);
    digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
    delay(500);

    x++;
    x %= 10; //Reset x after 9

    Serial.println(x); //For debugging
  }
}

void loop()
{
  //showNumber(42); //Test pattern
}

//Takes a number and displays 2 numbers. Displays absolute value (no negatives)
void showNumber(float value)
{
  int number = abs(value); //Remove negative signs and any decimals

  //Serial.print("number: ");
  //Serial.println(number);

  for (byte x = 0 ; x < 2 ; x++)
  {
    int remainder = number % 10;

    postNumber(remainder, false);

    number /= 10;
  }

  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

//Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

  byte segments;

  switch (number)
  {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  //Clock these bits out to the drivers
  for (byte x = 0 ; x < 8 ; x++)
  {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}

Go Up