How toggle the output of shift register individually with buttons?

I want to toggle 08 leds connected on output of 74HC595 through 08 button on arduino.

0~6 (7 button) working fine
But when #7 (8th button) is high led ON if I keep it high and try to toggle other 7 button all goes wrong leds randomly toggling.

If i will press #7 (8th button) again and all 07 button and leds working fine.

Where I am wrong.

My sketch and library attached.

#include <Shifter.h>
#define SER_Pin 2   //Data pin SER_IN 
#define RCLK_Pin 3  //Latch Pin L_CLOCK 
#define SRCLK_Pin 4 //Clock Pin CLOCK
#define NUM_REGISTERS 1 //how many registers are in the chain

//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);


const uint32_t debounceTime = 20;  // 5 mSec, enough for most switches

const uint8_t switchPin0     = A0;  // with n.o. momentary pb switch to ground
const uint8_t switchPin1     = A1;  // with n.o. momentary pb switch to ground
const uint8_t switchPin2     = A2;  // with n.o. momentary pb switch to ground
const uint8_t switchPin3     = A3;  // with n.o. momentary pb switch to ground
const uint8_t switchPin4     = A4;  // with n.o. momentary pb switch to ground
const uint8_t switchPin5     = A5;  // with n.o. momentary pb switch to ground
const uint8_t switchPin6     = 7;  // with n.o. momentary pb switch to ground
const uint8_t switchPin7     = 6;  // with n.o. momentary pb switch to ground

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;


bool lastState0   = switchOff;
bool newState0    = switchOff;
bool toggleState0 = false;

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

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

bool lastState3   = switchOff;
bool newState3    = switchOff;
bool toggleState3 = false;

bool lastState4   = switchOff;
bool newState4    = switchOff;
bool toggleState4 = false;

bool lastState5   = switchOff;
bool newState5    = switchOff;
bool toggleState5 = false;

bool lastState6   = switchOff;
bool newState6    = switchOff;
bool toggleState6 = false;

bool lastState7   = switchOff;
bool newState7    = switchOff;
bool toggleState7 = false;

void setup() {
  pinMode ( switchPin0, INPUT_PULLUP );
  pinMode ( switchPin1, INPUT_PULLUP );
  pinMode ( switchPin2, INPUT_PULLUP );
  pinMode ( switchPin3, INPUT_PULLUP );
  pinMode ( switchPin4, INPUT_PULLUP );
  pinMode ( switchPin5, INPUT_PULLUP );
  pinMode ( switchPin6, INPUT_PULLUP );
  pinMode ( switchPin7, INPUT_PULLUP );

  shifter.clear(); //set all pins on the shift register chain to LOW
  shifter.write(); //send changes to the chain and display them
}

void loop() {

  newState0 = digitalRead( switchPin0 );
  newState1 = digitalRead( switchPin1 );
  newState2 = digitalRead( switchPin2 );
  newState3 = digitalRead( switchPin3 );
  newState4 = digitalRead( switchPin4 );
  newState5 = digitalRead( switchPin5 );
  newState6 = digitalRead( switchPin6 );
  newState7 = digitalRead( switchPin7 );

  ////////////////////////*********0**********///////////////////////////
  if ( lastState0 != newState0 ) // state changed
  {
    delay( debounceTime );
    lastState0 = newState0;
    // push on, push off
    if ( newState0 == switchOn && toggleState0 == false )
    {
      toggleState0 = true;
      shifter.setPin(0, HIGH);
      shifter.write();
    }
    else if ( newState0 == switchOn && toggleState0 == true )
    {
      toggleState0 = false;
      shifter.setPin(0, LOW);
      shifter.write();
    }

  }
  ////////////////////////////////////1//////////////////////////////////////////

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

    // push on, push off
    if ( newState1 == switchOn && toggleState1 == false )
    {
      toggleState1 = true;
      shifter.setPin(1, HIGH);
      shifter.write();
    }
    else if ( newState1 == switchOn && toggleState1 == true )
    {
      toggleState1 = false;
      shifter.setPin(1, LOW);
      shifter.write();
    }
  }
  ////////////////////////*********2**********///////////////////////////
  if ( lastState2 != newState2 ) // state changed
  {
    delay( debounceTime );
    lastState2 = newState2;

    // push on, push off
    if ( newState2 == switchOn && toggleState2 == false )
    {
      toggleState2 = true;
      shifter.setPin(2, HIGH);
      shifter.write();
    }
    else if ( newState2 == switchOn && toggleState2 == true )
    {
      toggleState2 = false;
      shifter.setPin(2, LOW);
      shifter.write();
    }
  }
  ////////////////////////*********3**********///////////////////////////
  if ( lastState3 != newState3 ) // state changed
  {
    delay( debounceTime );
    lastState3 = newState3;

    // push on, push off
    if ( newState3 == switchOn && toggleState3 == false )
    {
      toggleState3 = true;
      shifter.setPin(3, HIGH);
      shifter.write();
    }
    else if ( newState3 == switchOn && toggleState3 == true )
    {
      toggleState3 = false;
      shifter.setPin(3, LOW);
      shifter.write();
    }
  }
  ////////////////////////*********4**********///////////////////////////
  if ( lastState4 != newState4 ) // state changed
  {
    delay( debounceTime );
    lastState4 = newState4;

    // push on, push off
    if ( newState4 == switchOn && toggleState4 == false )
    {
      toggleState4 = true;
      shifter.setPin(4, HIGH);
      shifter.write();
    }
    else if ( newState4 == switchOn && toggleState4 == true )
    {
      toggleState4 = false;
      shifter.setPin(4, LOW);
      shifter.write();
    }
  }
  ////////////////////////*********5**********///////////////////////////
  if ( lastState5 != newState5 ) // state changed
  {
    delay( debounceTime );
    lastState5 = newState5;

    // push on, push off
    if ( newState5 == switchOn && toggleState5 == false )
    {
      toggleState5 = true;
      shifter.setPin(5, HIGH);
      shifter.write();
    }
    else if ( newState5 == switchOn && toggleState5 == true )
    {
      toggleState5 = false;
      shifter.setPin(5, LOW);
      shifter.write();
    }
  }
  ////////////////////////*********6**********///////////////////////////
  if ( lastState6 != newState6 ) // state changed
  {
    delay( debounceTime );
    lastState6 = newState6;

    // push on, push off
    if ( newState6 == switchOn && toggleState6 == false )
    {
      toggleState6 = true;
      shifter.setPin(6, HIGH);
      shifter.write();
    }
    else if ( newState6 == switchOn && toggleState6 == true )
    {
      toggleState6 = false;
      shifter.setPin(6, LOW);
      shifter.write();
    }
  }
  ////////////////////////*********7**********///////////////////////////
  if ( lastState7 != newState7 ) // state changed
  {
    delay( debounceTime );
    lastState7 = newState7;

    // push on, push off
    if ( newState7 == switchOn && toggleState7 == false )
    {
      toggleState7 = true;
      shifter.setPin(7, HIGH);
      shifter.write();
    }
    else if ( newState7 == switchOn && toggleState7 == true )
    {
      toggleState7 = false;
      shifter.setPin(7, LOW);
      shifter.write();
    }
  }
  ////////////////////////////////////////////////////////////////////////////
}

Shift-Register-8-Bit-74HC595-master.zip (4.2 KB)

I want to toggle 08 leds

8 is not a valid octal digit.

AWOL:
8 is not a valid octal digit.

But in sketch I use 0~7 . 8th for just explain.

Shorten your code...
Read about structs and arrays.
The logic will jump out at you far more easily.

TBH, I didn’t look at your problem, as there is so much duplication and redundancy that it just confuses the question.

It seems like you only push bits out IF the input bit changes, it in fact, yoU need to push all output bits on every cycle of the shift register.

thanks for your time.

Actually I want to toggle the leds individual pin on shift register output. and 08 buttons are connected with arduino pins. 0 to 6 pins are working normal but when I make pin7 high all pin stop toggling and start random display.

Yes I can short the code but I want to make simple to understand because later on I want to add RS485 as a serial communication over long distance. Without shift register my existing system is working and now I want to add shift register.

So mainly issue is how toggle the output of shift register individually with buttons?

This should compile - I don't have your library...
From your example, I'm assuming you simply have to set/clear the corresponding bit in the shifter.setPin() function.
This is basically the same operations as your code - just squished.
No more or less capable of being modified to serial / 485 - just easier to maintain.
(The indenting didn't carry properly from Notepad++)

Let us know!
-- just noted: You could move the shifter.write() call to the last line of loop()
-- operationally it doesn't change anything, but makes the code flow more logical...
-- you may want to batch the changes together some time in the future, which this would allow easily.

*** IGNORE THIS CODE - USE THE SNIPPET FURTHER DOWN IN THIS THREAD ***

#include <Shifter.h>

#define SER_Pin 2   //Data pin SER_IN 
#define RCLK_Pin 3  //Latch Pin L_CLOCK 
#define SRCLK_Pin 4 //Clock Pin CLOCK

#define NUM_REGISTERS 1 //how many 8-bit registers are in the output chain
// (in this example, the output is mapped directly to the number of inputs/8

//initalize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
const uint32_t debounceTime = 20;  // 5 mSec, enough for most switches

// switch inputs with n.o. momentary closure to 'switchOn'
const uint8_t switchPin[] = { A0, A1, A2, A3, A4, A5, 7, 6 };

struct {
 bool prevState = switchOff;
 bool currState = switchOff;
 bool toggle = false;
} switchStruct;
//  create the array of switches
switchStruct mySwitch[8];

uint8_t SRbytes[NUM_REGISTERS];

// -----------------------------------
void setup() {
 for (byte index = 0; index < sizeof(switchPin); index++) {
 pinMode ( switchPin[index], INPUT_PULLUP );
 }
  shifter.clear(); //set all pins on the shift register chain to LOW
  shifter.write(); //send changes to the chain and display them
}

// -----------------------------------
void loop() {

 for (byte index = 0; index < sizeof(switchPin); index++) {
 mySwitch.currState[index] = digitalRead( switchPin[index] );

 if ( mySwitch[index].currState != mySwitch[index].prevState ) // state has changed
 {
 // push on, push off
 if ( mySwitch[index].currState == switchOn)
 {
 mySwitch[index].toggle = !mySwitch[index].toggle;
 shifter.setPin(index, mySwitch[index].toggle);
 shifter.write();
 }
 mySwitch[index].prevState = mySwitch[index].currState; // update prevState
 delay( debounceTime );
 }
 }
}

getting error:

sketch_nov10a:44: error: 'mySwitch' was not declared in this scope

mySwitch.currState[index] = digitalRead( switchPin[index] );

^

exit status 1
'switchStruct' does not name a type

Library is attached in my #1.

mySwitch[index].currState

AWOL:

mySwitch[index].currState

Still errorsketch_nov10c:27: error: 'switchStruct' does not name a type

switchStruct mySwitch[8];

^

C:\Users\G0C6D~1.FAR\AppData\Local\Temp\arduino_modified_sketch_4390\sketch_nov10c.ino: In function 'void loop()':

sketch_nov10c:42: error: 'mySwitch' was not declared in this scope

mySwitch[index].currState = digitalRead( switchPin[index] );

^

sketch_nov10c:42: error: 'index' was not declared in this scope

mySwitch[index].currState = digitalRead( switchPin[index] );

^

exit status 1
'switchStruct' does not name a type

Guess what?
We can't see your code.

AWOL:
Guess what?
We can't see your code.

#include <Shifter.h>

#define SER_Pin 2   //Data pin SER_IN 
#define RCLK_Pin 3  //Latch Pin L_CLOCK 
#define SRCLK_Pin 4 //Clock Pin CLOCK

#define NUM_REGISTERS 1 //how many 8-bit registers are in the output chain
// (in this example, the output is mapped directly to the number of inputs/8

//initalize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
const uint32_t debounceTime = 20;  // 5 mSec, enough for most switches

// switch inputs with n.o. momentary closure to 'switchOn'
const uint8_t switchPin[] = { A0, A1, A2, A3, A4, A5, 7, 6 };

struct {
 bool prevState = switchOff;
 bool currState = switchOff;
 bool toggle = false;
} switchStruct;
//  create the array of switches
switchStruct mySwitch[8];

uint8_t SRbytes[NUM_REGISTERS];

// -----------------------------------
void setup() {
 for (byte index = 0; index < sizeof(switchPin); index++) {
 pinMode ( switchPin[index], INPUT_PULLUP );
 }
  shifter.clear(); //set all pins on the shift register chain to LOW
  shifter.write(); //send changes to the chain and display them
}

// -----------------------------------
void loop() {

 for (byte index = 0; index < sizeof(switchPin); index++) {
  mySwitch[index].currState = digitalRead( switchPin[index] );
 if ( mySwitch[index].currState != mySwitch[index].prevState ) // state has changed
 {
 // push on, push off
 if ( mySwitch[index].currState == switchOn)
 {
 mySwitch[index].toggle = !mySwitch[index].toggle;
 shifter.setPin(index, mySwitch[index].toggle);
 shifter.write();
 }
 mySwitch[index].prevState = mySwitch[index].currState; // update prevState
 delay( debounceTime );
 }
 }
}

I just checked - there was an invisible 'non-printing' character hidden in the source I posted earlier.. hence the odd error. So I fixed that - it compiles now when shifter is commented out.
The rest is up to you. (Apologies for the red-herring)

#include <Shifter.h>

#define SER_Pin 2   //Data pin SER_IN 
#define RCLK_Pin 3  //Latch Pin L_CLOCK 
#define SRCLK_Pin 4 //Clock Pin CLOCK

#define NUM_REGISTERS 1 //how many 8-bit registers are in the output chain
// (in this example, the output is mapped directly to the number of inputs/8

//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
const uint32_t debounceTime = 20;  // 5 mSec, enough for most switches

// switch inputs with n.o. momentary closure to 'switchOn'
const uint8_t switchPin[]		= { A0, A1, A2, A3, A4, A5, 7, 6 };

struct switchStruct {
  bool	prevState = switchOff;
  bool	currState = switchOff;
  bool	toggle = false;
} ;
//  create the array of switches
switchStruct mySwitch[8];

void setup() {
  for (byte index = 0; index <= sizeof(switchPin); index++) {
    pinMode ( switchPin[index], INPUT_PULLUP );
  }

  shifter.clear(); //set all pins on the shift register chain to LOW
  shifter.write(); //send changes to the chain and display them
}

void loop() {

  for (byte index = 0; index <= sizeof(switchPin); index++) {
    mySwitch[index].currState = digitalRead( switchPin[index] );

    if ( mySwitch[index].currState != mySwitch[index].prevState ) // state has changed
    {
      // push on, push off
      if ( mySwitch[index].currState == switchOn)
      {
        mySwitch[index].toggle = !mySwitch[index].toggle;
        shifter.setPin(index, mySwitch[index].toggle);
        shifter.write();
      }
      mySwitch[index].prevState = mySwitch[index].currState; // update prevState
      delay( debounceTime );
    }
  }
}

That's excellent and working good same as working without array. :slight_smile:

Now the biggest challenge for me and the reason why i was not use the array :

With toggle the led I also want to send the command like "A" (when state ON) and send "B" when OFF and so on. (I achieve this without array and my sketch is attached)

Just ignore the RS485 in sketch I am using this as a serial communication over long distance protocol like modebus but actually serial communication which will eco back to this slave.

Thanks again for your time.

75HC595_with_08_individual_toggle_output.ino (25 KB)

Using an array makes no difference to your communications- the way you’ve explained it.

As you discussed so far, the only lines that need to change for local or remote operation are -

shifter.setPin(index, mySwitch[index].toggle);
shifter.write();

Using serial A B etc is a new twist... where did that come from?
Input handling would go here...

mySwitch[index].currState = digitalRead( switchPin[index] );

I think before anyone can help you get further along, you need to sketch out a conceptual block diagram of what your whole ‘expected’ system is going to look like.

I build a home automation which has Arduino mega + Ethernet shield with SD card and local button (panel) connected with Arduino mega.

.XML file save on SD card and we can toggle the relay over WIFI and button. All of this setup is synchronize browser with Ajax which update the page automatically.

Additionally I also want to control the same relay over long distance or you can say 02 way / 03 way switch with real time led indicator.

I use RS485 to communicate over long distance and protocol is simple.

  1. When push the button1 as ON serial. Write 'A' will send to the master.
  2. Master which is Arduino mega receive the command 'A' and relay 01 will ON. And after execution it will Eco back to the slave serial. Write 'A'.
  3. So on Slave which is my remote panel Arduino Nano will only light up Led1 when received 'A'

Same think with other button2,3.... and C,D,E,F....

each time during sending the command Tx/RX control pin will be high than delay (1) and become low as receiver mode.

Like half duplex communication.

My challenge is how define in array A,B,C,D,E,F....... and also control the Tx/RX control pin.

Its complicated for me or may be I am trying to do this in wrong way.

Below is array of functions code. It can solve the serial write and Tx/RX control pin switching because function is called in array . I need your help to add this with your sketch or if there is better way to call the function in array of toggle button.

void doAction0 (){Serial.println (0);}
void doAction1 (){Serial.println (1);}
void doAction2 (){Serial.println (2);}
void doAction3 (){Serial.println (3);}
void doAction4 (){Serial.println (4);}
void doAction5 (){Serial.println (5);}
void doAction6 (){Serial.println (6);}
void doAction7 (){Serial.println (7);}
void doAction8 (){Serial.println (8);}

typedef void (*GeneralFunction) ();
// array of function pointers
GeneralFunction doActionsArray [] =
{
  doAction0,
  doAction1,
  doAction2,
  doAction3,
  doAction4,
  doAction5,
  doAction6,
  doAction7,
  doAction8,
};

void setup ()
{
  Serial.begin (115200);
}  // end of setup

void loop () {
  Serial.println ();

  int action = 0;   // 0 is an example
  for (int i = 0; i <=  action;  action++) {
    doActionsArray [action] ();
    delay(1000);
  }
}

void doAction0 (){Serial.println (0);}I'm seeing a pattern here.
And it doesn't involve arrays.

AWOL:

void doAction0 (){Serial.println (0);}

I'm seeing a pattern here.
And it doesn't involve arrays.

Here is my complet sketch. Its 08 toggle button. I want to call "void Call1()" when button state ON and "void test1()" when button state off.

Currently I am getting void Call1() void Call2()....... only.

void Call1() {Serial.println("Function Call1 has been called ");}
void Call2() {Serial.println("Function Call2 has been called");}
void Call3() {Serial.println("Function Call3 has been called");}
void Call4() {Serial.println("Function Call4 has been called");}
void Call5() {Serial.println("Function Call5 has been called");}
void Call6() {Serial.println("Function Call6 has been called");}
void Call7() {Serial.println("Function Call7 has been called");}
void Call8() {Serial.println("Function Call8 has been called");}

void test1() {Serial.println("Function test1 has been tested ");}
void test2() {Serial.println("Function test2 has been tested");}
void test3() {Serial.println("Function test3 has been tested");}
void test4() {Serial.println("Function test4 has been tested");}
void test5() {Serial.println("Function test5 has been tested");}
void test6() {Serial.println("Function test6 has been tested");}
void test7() {Serial.println("Function test7 has been tested");}
void test8() {Serial.println("Function test8 has been called");}


void (*myPointer[])(void) = {
  Call1,
  Call2,
  Call3,
  Call4,
  Call5,
  Call6,
  Call7,
  Call8
};

void (*mytest[])(void) = {
 test1,
 test2,
 test3,
 test4,
 test5,
 test6,
 test7,
 test8
};

#include <Shifter.h>

#define SER_Pin 2   //Data pin SER_IN 
#define RCLK_Pin 3  //Latch Pin L_CLOCK 
#define SRCLK_Pin 4 //Clock Pin CLOCK

#define NUM_REGISTERS 1 //how many 8-bit registers are in the output chain
// (in this example, the output is mapped directly to the number of inputs/8

//initaize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);

const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
const uint32_t debounceTime = 20;  // 5 mSec, enough for most switches

// switch inputs with n.o. momentary closure to 'switchOn'
const uint8_t switchPin[]    = { A0, A1, A2, A3, A4, A5, 7, 6 };

struct switchStruct {
  bool  prevState = switchOff;
  bool  currState = switchOff;
  bool  toggle = false;
} ;
//  create the array of switches
switchStruct mySwitch[8];

void setup() {
  for (byte index = 0; index <= sizeof(switchPin); index++) {
    pinMode ( switchPin[index], INPUT_PULLUP );
    Serial.begin(115200);
  }

  shifter.clear(); //set all pins on the shift register chain to LOW
  shifter.write(); //send changes to the chain and display them
}

void loop() {

  for (byte index = 0; index <= sizeof(switchPin); index++) {
    mySwitch[index].currState = digitalRead( switchPin[index] );

    if ( mySwitch[index].currState != mySwitch[index].prevState ) // state has changed
    {
      // push on, push off
      if ( mySwitch[index].currState == switchOn)
      { 
        mySwitch[index].toggle = !mySwitch[index].toggle;
        shifter.setPin(index, mySwitch[index].toggle);
        shifter.write();   
       myPointer[index]();
      }  
      mySwitch[index].prevState = mySwitch[index].currState; // update prevState
      delay( debounceTime );
    }
  }
}
void Call1() {Serial.println("Function Call1 has been called ");}
void Call2() {Serial.println("Function Call2 has been called");}
void Call3() {Serial.println("Function Call3 has been called");}
void Call4() {Serial.println("Function Call4 has been called");}
void Call5() {Serial.println("Function Call5 has been called");}
void Call6() {Serial.println("Function Call6 has been called");}
void Call7() {Serial.println("Function Call7 has been called");}
void Call8() {Serial.println("Function Call8 has been called");}

Can you see a pattern here?
One that doesn't waste quite so much RAM?

AWOL:

void Call1() {Serial.println("Function Call1 has been called ");}

void Call2() {Serial.println("Function Call2 has been called");}
void Call3() {Serial.println("Function Call3 has been called");}
void Call4() {Serial.println("Function Call4 has been called");}
void Call5() {Serial.println("Function Call5 has been called");}
void Call6() {Serial.println("Function Call6 has been called");}
void Call7() {Serial.println("Function Call7 has been called");}
void Call8() {Serial.println("Function Call8 has been called");}


Can you see a pattern here?
One that doesn't waste quite so much RAM?

I didn't get it. what does it mean. See the full sketch