08 Individual relay drive by (TPIC6B595)

I want to drive 08 relays individually with TPIC6B595 in home automation project. Like 08 relay control with 08 buttons.
Is it possible to drive TPIC6B595 pin with 08 buttons individual without disturbing other relay status ?

I try basic sketch which can toggle individual pin one by one and also specific pattern. But not sure how drive individual and specific pin only without disturbing other relay status.

counter = 5; registerWrite(counter, HIGH);
counter = 5; registerWrite(counter, LOW);

//////////////////////--------------------------------------------////////////////////

  if (buttonstate1 == LOW && Led1 == 0)
  {
    leds ^= B00000001;
    bitSet(leds, 1);
    updateShiftRegister();
   delay(1000);
   // Led1 = !Led1;     // for Push on only 
  }

An output can be changed without modifying the other outputs.

Each time you update the register, you must update all 8 outputs because that is how shift registers work. To change 1 output without disturbing the other 7, your code must remember the state of the other 7 pins and combine them with the updated pin before updating the register. There are several ways to do this. One way that is quite easy is to have a global byte variable which remembers the state of all 8 pins. When you want to change any pin, your code must update that global variable and then send the updated variable to the shift register.

I am not good in coding but I get the result with below code. Can anyone explain that.
because when I use same function in state change example is stop working.

const int latchPin = 10;
const int clockPin = 9;
const int dataPin = 12;
const int OE        = 11;

int Btn1 = A0;  //button 1 connected to pin 1
int Btn2 = 5;  //button 2 connected to pin 2
int Btn3 = 6;  //button 3 connected to pin 3
int Btn4 = 7;  //button 4 connected to pin 4
int Btn5 = A4;  //button 5 connected to pin 5
int Btn6 = A3;  //button 6 connected to pin 6
int Btn7 = A2;  //button 7 connected to pin 7
int Btn8 = A1;  //button 8 connected to pin 8


int buttonstate1 = 0;    //state button 1
int buttonstate2 = 0;    //state button 2
int buttonstate3 = 0;    //state button 3
int buttonstate4 = 0;    //state button 4
int buttonstate5 = 0;    //state button 5
int buttonstate6 = 0;    //state button 6
int buttonstate7 = 0;    //state button 7
int buttonstate8 = 0;    //state button 8

int Led1 = 0;  //Light1 on/off
int Led2 = 0;  //Light2 on/off
int Led3 = 0;  //Light3 on/off
int Led4 = 0;  //Light4 on/off
int Led5 = 0;  //Light5 on/off
int Led6 = 0;  //Light6 on/off
int Led7 = 0;  //Light7 on/off
int Led8 = 0;  //Light8 on/off

byte leds = 0;

void setup()
{
  pinMode(OE, OUTPUT);
  digitalWrite(OE, LOW);
  pinMode(Btn1, INPUT_PULLUP);
  pinMode(Btn2, INPUT_PULLUP);
  pinMode(Btn3, INPUT_PULLUP);
  pinMode(Btn4, INPUT_PULLUP);
  pinMode(Btn5, INPUT_PULLUP);
  pinMode(Btn6, INPUT_PULLUP);
  pinMode(Btn7, INPUT_PULLUP);
  pinMode(Btn8, INPUT_PULLUP);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

}

void loop()
{
  buttonstate1 = digitalRead(Btn1);
  buttonstate2 = digitalRead(Btn2);
  buttonstate3 = digitalRead(Btn3);
  buttonstate4 = digitalRead(Btn4);
  buttonstate5 = digitalRead(Btn5);
  buttonstate6 = digitalRead(Btn6);
  buttonstate7 = digitalRead(Btn7);
  buttonstate8 = digitalRead(Btn8);

  if (buttonstate1 == LOW && Led1 == 0)
  {
    leds ^= B00000001;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate2 == LOW && Led2 == 0)
  {
    leds ^= B00000010;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate3 == LOW && Led3 == 0)
  {
    leds ^= B00000100;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate4 == LOW && Led4 == 0)
  {
    leds ^= B00001000;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate5 == LOW && Led5 == 0)
  {
    leds ^= B00010000;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate6 == LOW && Led6 == 0)
  {
    leds ^= B00100000;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate7 == LOW && Led7 == 0)
  {
    leds ^= B01000000;
    updateShiftRegister();
     delay(200);
  }

  if (buttonstate8 == LOW && Led8 == 0)
  {
    leds ^= B10000000;
    updateShiftRegister();
     delay(200);
  }
}

void updateShiftRegister()
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, leds);
  digitalWrite(latchPin, HIGH);
}

That code is very long and repetitive and many parts do nothing. I suspect it works only if you press the buttons very briefly (<200ms). If you press them for longer than that, the led might flash briefly and stay off, or will flash rapidly until you release the button.

The explanation for why it works, I think, is mostly because you are using the "^=" operator, which means "bitwise exclusive-or and assignment". This operation is being used here to 'toggle' one bit of the variable "leds" which is then sent to the shift register, very similar to my previous suggestion.

For help with that code, post it.

This sketch toggle both relay at once from both buttons.

const int latchPin = 10;
const int clockPin = 9;
const int dataPin = 12;
const int OE        = 11;
byte leds = 0;

const uint32_t debounceTime = 50;  // 5 mSec, enough for most switches
const uint8_t switchPin1     = A0;  // with n.o. momentary pb switch to ground
const uint8_t switchPin2     = 5;  // with n.o. momentary pb switch to ground

#define ledPin1      13

const bool switchOn  = true;     // with capasitive touch
const bool switchOff = false;

bool lastState1   = switchOff;
bool newState1    = switchOff;
bool toggleState1 = false;

bool lastState2   = switchOff;
bool newState2    = switchOff;
bool toggleState2 = false;

void setup()
{

  Serial.begin(9600);
  pinMode(OE, OUTPUT);
  digitalWrite(OE, LOW);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode ( switchPin1, INPUT_PULLUP );
  pinMode ( switchPin2, INPUT_PULLUP );
  pinMode(ledPin1, OUTPUT);
  digitalWrite(ledPin1, LOW);
}

void loop()
{

  newState1 = digitalRead( switchPin1 );
  newState2 = digitalRead( switchPin2 );


  if ( lastState1 != newState1 ) // state changed
  {
    delay( debounceTime );
    lastState1 = newState1;

    // push on, push off
    if ( newState1 == switchOn && toggleState1 == false )
    {
      toggleState1 = true;

      leds ^= B00000001;
      updateShiftRegister();
    }
    else if ( newState1 == switchOn && toggleState1 == true )
    {
      toggleState1 = false;
      leds ^= B00000001;
      updateShiftRegister();
    }

  }



  if ( lastState2 != newState2 ) // state changed
  {
    delay( debounceTime );
    lastState2 = newState2;

    // push on, push off
    if ( newState2 == switchOn && toggleState2 == false )
    {
      toggleState2 = true;
      
      leds ^= B00000010;
      updateShiftRegister();
    }
    else if ( newState2 == switchOn && toggleState2 == true )
    {
      toggleState2 = false;
      
      leds ^= B00000010;
      updateShiftRegister();
    }
  }
}


void updateShiftRegister()
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, leds);
  digitalWrite(latchPin, HIGH);
}





That is strange. I can't see a reason why it would do that. Try this change:

void updateShiftRegister()
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, leds);
  digitalWrite(latchPin, HIGH);
  Serial.print("leds=");
  Serial.println(leds, BIN);
}

What do you see on serial monitor?

----------------------Serial output-----------------

leds=1 // After power on without press any button
leds=11 // After power on without press any button

leds=10 // 1st press on button 01
leds=0 // 1st press on button 01

leds=10 // 2nd press on button 01
leds=11 // 2nd press on button 01

Its working only with that sketch which i did not understand.

---------------------------- Serial output with post # 4 code--------------

leds=1 // 01 ON with button 01
leds=0 // 01 OFF with button 01
leds=10 // 02 ON ---------------
leds=0 // 02 OFF---------------
leds=100 // 03 ON
leds=0 // 03 OFF
leds=1000 // follow the same sequence
leds=0
leds=100000
leds=0
leds=10000
leds=0
leds=1000000
leds=0
leds=10000000
leds=0
leds=1 // 01 ON with button 01
leds=11 // 01+ 02 ON with 02 button while 01 keep on
leds=111 // follow the same sequence and 1== ON and 0 == OFF with related button
leds=1111
leds=101111
leds=111111
leds=1111111
leds=11111111
leds=11111011
leds=11111010
leds=11101010

Finally solve by Pullup all other buttons pin. Now it's working with debouncing / state change sketch also.
0.1uF capacitor is already there near to the chip. how we can further improve to avoid the noise interference.

You should learn the Arduino "bit" macros:
https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitset/
For example, you have a byte variable that holds the staes of your relays named "relayStates" and you wanted to change the state of relay 4 from OFF to ON.
bitSet(relayStates,4);
To turn relay 7 OFF:
bitClear(relayStates,7);
Then send "relayStates" to the shift register.

1 Like

I don't understand what changes you made to fix the problem.