Teensy Shift Register issue AGAIN

Status
Not open for further replies.

BenDanville

Active member
Hi everyone, I'm hoping someone out their can offer some advice!

I'm working on building myself a sim and shiftregister seemed good for adding lots of switches to one teensy.

I am attempting to use the SN74HC165N serial-in shift registers and am using the arduino SN74HC165N example, I can use 1-4 shift registers and everything works well, but if I change to 5 or 6 then suddenly the previous 1-2 registers stop working.
Is it because a long is 32 bits and the 6x shift registers are 48bits? Not really sure what else it could be and how to get around the issue :/

shiftboard.jpg

/*
* SN74HC165N_shift_reg
*
* Program to shift in the bit values from a SN74HC165N 8-bit
* parallel-in/serial-out shift register.
*
* This sketch demonstrates reading in 16 digital states from a
* pair of daisy-chained SN74HC165N shift registers while using
* only 4 digital pins on the Arduino.
*
* You can daisy-chain these chips by connecting the serial-out
* (Q7 pin) on one shift register to the serial-in (Ds pin) of
* the other.
*
* Of course you can daisy chain as many as you like while still
* using only 4 Arduino pins (though you would have to process
* them 4 at a time into separate unsigned long variables).
*
*/

/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS 5

/* Width of data (how many ext lines).
*/
#define DATA_WIDTH NUMBER_OF_SHIFT_CHIPS * 8

/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC 5

/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC 1

/* You will need to change the "int" to "long" If the
* NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned long

int ploadPin = 33; // SH/LD Connects to Parallel load pin the 165
int clockEnablePin = 38; // Connects to Clock Enable pin the 165
int dataPin = 37; // Connects to the Q7 pin the 165
int clockPin = 34; // CLK Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
* serial Data from the shift register chips and representing
* the state of those pins in an unsigned integer (or long).
*/
BYTES_VAL_T read_shift_regs()
{
long bitVal;
BYTES_VAL_T bytesVal = 0;

/* Trigger a parallel Load to latch the state of the data lines,
*/
digitalWrite(clockEnablePin, HIGH);
digitalWrite(ploadPin, LOW);
delayMicroseconds(PULSE_WIDTH_USEC);
digitalWrite(ploadPin, HIGH);
digitalWrite(clockEnablePin, LOW);

/* Loop to read each bit value from the serial out line
* of the SN74HC165N.
*/
for(int i = 0; i < DATA_WIDTH; i++)
{
bitVal = digitalRead(dataPin);

/* Set the corresponding bit in bytesVal.
*/
bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

/* Pulse the Clock (rising edge shifts the next bit).
*/
digitalWrite(clockPin, HIGH);
delayMicroseconds(PULSE_WIDTH_USEC);
digitalWrite(clockPin, LOW);
}

return(bytesVal);
}

/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
Serial.print("Pin States:\r\n");

for(int i = 0; i < DATA_WIDTH; i++)
{
Serial.print(" Pin-");
Serial.print(i);
Serial.print(": ");

if((pinValues >> i) & 1)
Serial.print("HIGH");
else
Serial.print("LOW");

Serial.print("\r\n");
}

Serial.print("\r\n");
}

void setup()
{
Serial.begin(9600);

/* Initialize our digital pins...
*/
pinMode(ploadPin, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);

digitalWrite(clockPin, LOW);
digitalWrite(ploadPin, HIGH);

/* Read in and display the pin states at startup.
*/
pinValues = read_shift_regs();
display_pin_values();
oldPinValues = pinValues;
}

void loop()
{
/* Read the state of all zones.
*/
pinValues = read_shift_regs();

/* If there was a chage in state, display which ones changed.
*/
if(pinValues != oldPinValues)
{
Serial.print("*Pin value change detected*\r\n");
display_pin_values();
oldPinValues = pinValues;
}

delay(POLL_DELAY_MSEC);
}
 

Attachments

  • shift_register_4.zip
    1.6 KB · Views: 79
Indeed this code only works for DATA_WIDTH up to 32:
Code:
for(int i = 0; i < DATA_WIDTH; i++)
{
bitVal = digitalRead(dataPin);
/* Set the corresponding bit in bytesVal. */
bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

I started a solution - but too late to show it working . . . once 'i' goes over 31, you need to put those bits into a different BYTES_VAL_T - perhaps with an array of [2] up to 64 bits.

*Note: good use of the
Code:
 blocking - doing a Ctrl+T before pasting will result in uniformly formatted and more readable code.
 
you could use unsigned long long that would get you to 64 bits, or you could use a byte array, one byte for each 8-bit shift register, and re-write your loops to step through the byte array.
 
Status
Not open for further replies.
Back
Top