B4R Code Snippet 74HC595 Shift Register for multiple output

The attached implements a code module for use of a shift register for getting multiple outputs while using only 3 pins of the arduino/esp.
See this thread for more information https://www.b4x.com/android/forum/threads/esp8266-spi-bus.71230/
The wiring for the application is like in this link https://learn.adafruit.com/adafruit-arduino-lesson-4-eight-leds/arduino-code

Update - Added a method for multiple write (to multiple chained registers).
I also wrote the shiftOut function by B4R code instead of the inline C so it can be modified if necessary.
The new file is added to the existing.
The wiring for the next register is simple - the same as the first (clock and latch pins connected in parallel), data pin in the next register is connected to Q7s (or Q7') of the previous register.
 

Attachments

  • 74hc595.zip
    1.7 KB · Views: 388
  • 74hc595_M.zip
    2 KB · Views: 379
Last edited:

derez

Expert
Licensed User
With this simple code I drive a 8x8 led matrix:
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
'    Private d1 As D1Pins  ' for ESP8266
    Private b(2) As Byte

    Private V() As Byte = Array As Byte(0x16,0x16,0x16,0x1F,0x70,0x88,0x88,0xF8)
'    Private V() As Byte = Array As Byte(0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10)

    Private G() As Byte = Array As Byte(0x7F,0xBF,0xDF,0xEf,0xF7,0xFB,0xFD,0xFE)

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")

'    ShiftReg.Initialize(d1.D5,d1.D6,d1.D2,True) ' for wemos
    ShiftReg.Initialize(5,6,4,True) ' for uno

    AddLooper("Draw")
End Sub

Sub Draw
    For i = 0 To 7
        b(1) = V(i)
        b(0) = G(i)
        ShiftReg.MultiWrite(b)
        Delay(1)
    Next
End Sub

upload_2016-10-1_11-11-21.png


The matrix is a RGB but this code drives just one color. With two more registers it is simple to drive the other two colors and also mix them. Maybe next...
 

derez

Expert
Licensed User
It was quick:
upload_2016-10-1_15-11-37.png


B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
'    Private d1 As D1Pins  ' for ESP8266
    Private b(4) As Byte

    Private Vcc() As Byte = Array As Byte (0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01)

            ' define light = 1
    Private Green() As Byte = Array As Byte(0x15,0x15,0x15,0x1F,0x70,0x88,0x88,0xF8)
    Private Red()   As Byte = Array As Byte(0x0B,0x0B,0x0B,0x00,0x00,0x70,0x70,0x00)
    Private Blue()  As Byte = Array As Byte(0xE0,0xE0,0xE0,0xE0,0x8F,0x07,0x07,0x07)
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")

'    ShiftReg.Initialize(d1.D5,d1.D6,d1.D2,True) ' for wemos
    ShiftReg.Initialize(5,6,4,True) ' for uno
   
    For i = 0 To 7    ' convert to light on 0 
        Green(i) = Bit.Not(Green(i))
        Red(i) = Bit.Not(Red(i))
        Blue(i) = Bit.Not(Blue(i))
    Next
   
    AddLooper("Draw")
End Sub

Sub Draw
    For i = 0 To 7
        b(3) =  Vcc(i)
        b(2) = Blue(i)
        b(1) = 0xFF 'Red(i)
        b(0) = 0xFF 'Green(i)
        ShiftReg.MultiWrite(b)
    Next
    For i = 0 To 7
        b(3) =  Vcc(i)
        b(2) = 0xFF 'Blue(i)
        b(1) = 0xFF 'Red(i)
        b(0) = Green(i)
        ShiftReg.MultiWrite(b)
    Next
    For i = 0 To 7
        b(3) =  Vcc(i)
        b(2) = 0xFF 'Blue(i)
        b(1) = Red(i)
        b(0) = 0xFF 'Green(i)
        ShiftReg.MultiWrite(b)
    Next       
End Sub
 
Last edited:

derez

Expert
Licensed User
With monochrome matrix it should be similar to post #3 with arrays going from 0 to 15 and also the loop up to 15.
The Shift registers should be connected two in a row - two for the V array and the other two for the ground of each led.
 

derez

Expert
Licensed User
In my code the 74hc595 are independent ICs.
You have arduino code in the link, does it work ?
 

tango

Member
Licensed User
hi derez.
did you work about P10 Led Panel with 74ch595 shiftregister.can you write wrapper DMD library to b4r or b4j. İf you help me , i will be glad for you.
Thanks friend.
 

derez

Expert
Licensed User
hi derez.
did you work about P10 Led Panel with 74ch595 shiftregister.can you write wrapper DMD library to b4r or b4j. İf you help me , i will be glad for you.
Thanks friend.
Sorry I don't know how to do it.
 

metheoneandonly

Member
Licensed User
In my code the 74hc595 are independent ICs.
You have arduino code in the link, does it work ?

I've tried it, but it didn't work as expected. Maybe is there something more than just change of arrays to 15 and also loop up to 15. Just to be sure, I've also tried to change connections between pins, meaning "maybe it's wrong connected", but with no success. But one thing just arrived: does it mind if i use Arduino Due, or some other controller? I mean, it compiles happily for Due, but Due is still 32-bit board regarding to most other boards most people still use, so maybe is there a problem? Should I get some 8-bit board and try with it?
 

derez

Expert
Licensed User
I've tried it, but it didn't work as expected. Maybe is there something more than just change of arrays to 15 and also loop up to 15. Just to be sure, I've also tried to change connections between pins, meaning "maybe it's wrong connected", but with no success. But one thing just arrived: does it mind if i use Arduino Due, or some other controller? I mean, it compiles happily for Due, but Due is still 32-bit board regarding to most other boards most people still use, so maybe is there a problem? Should I get some 8-bit board and try with it?
I don't think that it should make a difference.
Have you tried the code example in the link you sent - it will answer the question !The device you have cannot work with my code !
 

metheoneandonly

Member
Licensed User
I don't think that it should make a difference.
Have you tried the code example in the link you sent - it will answer the question !The device you have cannot work with my code !

I've just tried it, but it doesn't work. BUT, it work with the following code, I don't know where I found it, it was a long time ago:


#define COL_PIXEL 16
#define ROW_PIXEL 16

int latchPin=8; //LT
int clockPin=12;//SK
int dataPin=11; //R1

unsigned int COL_xPixel;
unsigned int ROW_num;
unsigned char Col_num_l;
unsigned char Col_num_h;


unsigned long ROW_code[16]={0x0080,0x0040,0x0020,0x0010,0x0008,0x0004,0x0002,0x0001,0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100};

//Data code: Horizontal modulus ,Bytes reverse order
unsigned char Bmp1[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;Matrix
------------------------------------------------------------------------------*/
0x3, 0xc3, 0xf, 0xc, 0xcf, 0x3, 0x30, 0xc, 0x33, 0x3, 0x30, 0x3f, 0x3,
0xc3, 0x3f, 0xc, 0x3, 0x33, 0x30, 0xc, 0x3, 0x33, 0x30, 0xcc, 0x3, 0xc3,
0xff, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x3, 0x0,
0x33, 0x3, 0x0, 0x0, 0xf,0xc0, 0xc3, 0xc0, 0x3, 0x0, 0x3, 0x33, 0x3, 0x0,
0x3, 0xc, 0x3, 0x0, 0x3, 0x33, 0x3, 0xc0, 0xcf, 0xc0 };



unsigned char Bmp2[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;LED 16 16
------------------------------------------------------------------------------*/
0x3, 0xfc, 0xcf, 0xf, 0x3, 0xc, 0xc0, 0x30, 0x3, 0xc, 0xc0, 0xc0, 0x3, 0xfc, 0xcf, 0xc0, 0x3, 0xc, 0xc0, 0xc0,
0xc3, 0xc, 0xc0, 0x30, 0xff, 0xfc, 0xcf, 0xf, 0x0, 0x0, 0x0, 0x0, 0xc, 0xf, 0x30, 0x3c, 0xcf, 0x0, 0x3c,
0x3, 0xcc, 0x0, 0x30, 0x3, 0xcc, 0xf, 0x30, 0x3f, 0xcc, 0x30, 0x30, 0xc3, 0xcc, 0x30, 0x30, 0xc3, 0x3f, 0xf, 0xfc, 0x3c, 0x0, 0x0, 0x0, 0x0 };

unsigned char Bmp3[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;SMILE
------------------------------------------------------------------------------*/
0xc0, 0xff, 0xff, 0x3, 0xf0, 0xff, 0xff, 0xf, 0x3c, 0x0, 0x0, 0x30, 0xcf, 0x3, 0xc0, 0xf3, 0xcf, 0x3,
0xc0, 0xf3, 0xcf, 0x3, 0xc0, 0xf3, 0xcf, 0x3, 0xc0, 0xf3, 0xcf, 0x3, 0xc0, 0xf3, 0xcf, 0x3, 0xc0, 0xf3,
0xcf, 0x3, 0xc0, 0xf3, 0xf, 0xff, 0xff, 0xf0, 0xf, 0xfc, 0x3f, 0xf0, 0xf, 0x0, 0x0, 0xf0, 0xc, 0x0, 0x0,
0x3c, 0xf0, 0xff, 0xff, 0xf, 0xc0, 0xff, 0xff, 0x3 };

unsigned char Bmp4[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;LED Smile
------------------------------------------------------------------------------*/
0x3, 0xfc, 0xcf, 0xf, 0x3, 0xc, 0xc0, 0x30, 0x3, 0xc, 0xc0, 0xc0, 0x3, 0xfc, 0xcf, 0xc0, 0x3, 0xc,
0xc0, 0xc0, 0xc3, 0xc, 0xc0, 0x30, 0xff, 0xfc, 0xcf, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xc0, 0x0, 0xc0, 0x3, 0x30, 0x3, 0x30, 0xc, 0xc, 0xc, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xfc, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0 };

unsigned char Bmp5[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;car
------------------------------------------------------------------------------*/
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0xc0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0xc, 0x3,
0xc0, 0x0, 0x33, 0x3, 0xf0, 0xff, 0xff, 0xf, 0xfc, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0x3f, 0xff, 0xf, 0xfc,
0xf, 0xfc, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0x0, 0x0, 0x3c, 0x3c, 0x0, 0x0, 0x3c,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0

};

unsigned char Bmp6[]=
{
/*------------------------------------------------------------------------------
; Width X height (pixels): 16X16
;love
------------------------------------------------------------------------------*/
0x0, 0x0, 0x0, 0x0, 0xc0, 0x3, 0xc0, 0x3, 0x30, 0xc, 0x30, 0xc, 0xc, 0x30, 0xc, 0x30, 0x3, 0xc0, 0x3,
0xc0, 0x3, 0x0, 0x0, 0xc0, 0x3, 0x0, 0x0, 0xc0, 0x3, 0x0, 0x0, 0xc0, 0xc, 0x0, 0x0, 0x30, 0x30, 0x0,
0x0, 0xc, 0xc0, 0x0, 0x0, 0x3, 0x0, 0x3, 0xc0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x30, 0xc, 0x0, 0x0,
0xc0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0


};


void shiftOut(unsigned char dataOut)
{
boolean pinState;
digitalWrite(dataPin,LOW);
digitalWrite(clockPin,LOW);

for(int i=0;i<=7;i++)
{
digitalWrite(clockPin,LOW);
// if(dataOut & (0x80>>i)){
if(dataOut & (0x01<<i)){
pinState=HIGH;
}
else{
pinState=LOW;
}

digitalWrite(dataPin,pinState);

digitalWrite(clockPin,HIGH);
digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, LOW);
}

//Combine 2 bits/pixel to 1 bits/pixel
unsigned char Combine_2BitsTo1Bit(unsigned char num,unsigned char *BMP)
{
unsigned char Col_num_tem_1;
unsigned char Col_num_tem_2;
unsigned int Col_num_tem = 0;
unsigned char i=0;
unsigned char Col_num_1bit = 0x00;
Col_num_tem_1 = *(BMP+num);
Col_num_tem_2 = *(BMP+num+1);
Col_num_tem = Col_num_tem_1;
Col_num_tem |= (Col_num_tem_2 << 8);
for(i=0;i<8;i++)
{
if(Col_num_tem&(0x0003<<i*2)) Col_num_1bit |= (0x01<<i);
}
return ~Col_num_1bit;
}

//display one picture
void display_martix(unsigned char *BMP)
{
//Display count
unsigned int dis_cnt=256;
unsigned int i;
unsigned int num_x;
for(i=0;i<dis_cnt*16;i++)
{
for(num_x=0;num_x<(COL_PIXEL/16);num_x++)
// for(num_x=0;num_x<4;num_x++)
{

ROW_num = ROW_code[COL_xPixel];

shiftOut(ROW_num>>8);
shiftOut(ROW_num);
// Single color,1 bits/pixel
// Col_num_l=~Bmp1[2*num_x + (COL_PIXEL/8)*COL_xPixel];
//Col_num_h=~Bmp1[2*num_x + (COL_PIXEL/8)*COL_xPixel+1];
//Single color,2 bits/pixel
Col_num_l = Combine_2BitsTo1Bit(4*num_x+(COL_PIXEL/8)*COL_xPixel*2,BMP);
Col_num_h = Combine_2BitsTo1Bit(4*num_x+(COL_PIXEL/8)*COL_xPixel*2+2,BMP);
//Col_num_l = Combine_2BitsTo1Bit(4*num_x+(8)*COL_xPixel*2,BMP);
//Col_num_h = Combine_2BitsTo1Bit((4*num_x+COL_PIXEL/8)*COL_xPixel*2+2,BMP);
shiftOut(Col_num_l);
shiftOut(Col_num_h);
}

if(COL_xPixel==15) COL_xPixel=0; else COL_xPixel++;
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);

}
}

void setup()
{
pinMode(latchPin,OUTPUT);
pinMode(clockPin,OUTPUT);
pinMode(dataPin,OUTPUT);
}




void loop()
{

display_martix(Bmp1);

display_martix(Bmp2);

display_martix(Bmp3);

display_martix(Bmp4);

display_martix(Bmp5);

display_martix(Bmp6);



}
 
Top