I am trying to have both an input shift register (74HC165) and an output shift register (74HC595) share the same SPI bus. In paticular, the arduino pro-micro hardware bus.
Input register code is based on >>THIS<< Nick Gammon article.
Output register toggles the eight outs ON/OFF at a 1Hz frequency. The code is based on >>THAT<< Nick's article.
I assigned Input and output latches to different pins. The input sectin of the sketch always work. Outputs section works only if the input part is deleted, so there must be some sort of conflict between them.
#include <SPI.h>
//PINOUT
const byte inRegPin = 5; //input registers latch pin
const byte outRegPin = 10; //output register latch pin
//outputs variables
unsigned long blinkTime;
bool flag;
byte outByte;
//inputs variables
byte inByte;
byte oldInByte; //previous state
byte mask;
byte iState;
void setup (){
pinMode (inRegPin, OUTPUT);
pinMode (outRegPin, OUTPUT);
digitalWrite (inRegPin, HIGH);
digitalWrite (outRegPin, HIGH);
SPI.begin (); //start SPI
Serial.begin(115200);
} // end of setup
void loop (){
//INPUTS: READ INPUT STATES AND SEND TO SERIAL
digitalWrite (inRegPin, LOW); // pulse the parallel load latch to send bytes serially
digitalWrite (inRegPin, HIGH);
inByte = SPI.transfer (0);
mask = 0b00000001;
for (int i = 1; i <= 8; i++)
{
if ((inByte & mask) != (oldInByte & mask))
{
Serial.print ("Switch ");
Serial.print (i);
Serial.print (" now ");
Serial.println ((inByte & mask) ? "closed" : "open");
} // end of bit has changed
mask <<= 1;
} // end of for each bit
oldInByte = inByte;
//OUTPUTS: TOGGLE OUTS ON/OFF AT 1HZ
digitalWrite (outRegPin, LOW);
if(millis()-blinkTime > 500) {
blinkTime = millis();
mask = 1;
flag = !flag;
if(flag == 1){
outByte = 0b10101010;
}
else{
outByte = 0b01010101;
}
SPI.transfer(outByte/*, sizeof(out)*/);
}
digitalWrite (outRegPin, HIGH);
} // end of loop
Could anyone help me figure out what is wrong?
Thanks in advance
Unfortunately you failed to provide schematics of your setup. From your description I guess that you have connected exactly one chip of each type. Is that assumption correct?
Did you connect the two types in parallel or serial?
Keep in mind that shift registers doesn't have a real chip select signal, so the shifting always happens even if you think it's for the other functionality (input versus output).
What does that mean? Are you using exactly the same hardware just delete the code section that reads the input?
The HC165 has a "CLK INH" or clock inhibit input. The HC595 doesn't have that. But if you wrote out and latched data in the 595, shifting in with a 165 and a common clock wouldn't matter, the output data is already latched, and you will shift out new data to the 595 before you latch it again anyway.
I think, if you are obeying the right sequences, you can share a clock between them without problems. Dying to see the schematic...
Yes, I've got it. You shift out data to the '595 every 500ms. But you latch whatever data has been sent to it each and every time loop() executes. If the '165 code is removed, then that's no problem because no other data gets shifted out. But if the '165 code is running, it shifts 8x 0 bits out every time loop() executes, and those zeros then get latched onto the '595.
Fix it like this:
#include <SPI.h>
//PINOUT
const byte inRegPin = 5; //input registers latch pin
const byte outRegPin = 10; //output register latch pin
//outputs variables
unsigned long blinkTime;
bool flag;
byte outByte;
//inputs variables
byte inByte;
byte oldInByte; //previous state
byte mask;
byte iState;
void setup (){
pinMode (inRegPin, OUTPUT);
pinMode (outRegPin, OUTPUT);
digitalWrite (inRegPin, HIGH);
digitalWrite (outRegPin, HIGH);
SPI.begin (); //start SPI
Serial.begin(115200);
} // end of setup
void loop (){
//INPUTS: READ INPUT STATES AND SEND TO SERIAL
digitalWrite (inRegPin, LOW); // pulse the parallel load latch to send bytes serially
digitalWrite (inRegPin, HIGH);
inByte = SPI.transfer (0);
mask = 0b00000001;
for (int i = 1; i <= 8; i++)
{
if ((inByte & mask) != (oldInByte & mask))
{
Serial.print ("Switch ");
Serial.print (i);
Serial.print (" now ");
Serial.println ((inByte & mask) ? "closed" : "open");
} // end of bit has changed
mask <<= 1;
} // end of for each bit
oldInByte = inByte;
//OUTPUTS: TOGGLE OUTS ON/OFF AT 1HZ
if(millis()-blinkTime > 500) {
blinkTime = millis();
mask = 1;
flag = !flag;
if(flag == 1){
outByte = 0b10101010;
}
else{
outByte = 0b01010101;
}
SPI.transfer(outByte/*, sizeof(out)*/);
digitalWrite (outRegPin, LOW);
digitalWrite (outRegPin, HIGH);
}
} // end of loop
Thanks guys for your replies. I have not schematics by hand, but I followed the wiring suggested by Nick Gammon. I forgot to mention that I kept clock in common between the two registers (sorry: my fault!)
About the code: Paul, you spotted it! Now everything works as it was inended. Thank you very much for takeing the time to read and understand the sketch, much appreciated