74hc165 incorrect data after tri-stating

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
Robospud
 
Posts: 11
Joined: Tue Oct 22, 2013 2:55 pm

74hc165 incorrect data after tri-stating

Post by Robospud »

I am having a rather peculiar issue with my circuit. I am using a 74hc165 shift register with 8 dip switches to set an address in my code for an rf module.
On it's own both the code and 74hc165 circuit work fine. If I connect my arduino to the 165s data out I receive the correct values for all switches.

However I need to tri-state the chip as the nrf905 module I'm using also uses the SPI bus and without tri-stating the chip I cannot send or receive data which makes the circuit useless because I need to send data. I am attempting to use a 74hc125 chip to tri-state the output.

The connections between the 2 chips are as follows:

74hc165 74hc125
15 (CE) 13 (4C)
9 (Q7) 12 (4A)

74hc125 Arduino
11 (4Y) 12(MISO)

Like I said earlier if I connect arduino pin 12 to the data out (Q7) the values are all correct.
When I connect the the arduino to the buffer out I get the correct data values for switches 1-7 but switch 8 sets the data as 255 it doesn't matter if it's on it's own or not it will always give 255.

I'm sorry if it's horrendously obvious but I have been failing to spot a problem for many hours, any help would be greatly appreciated.

Code: Select all

#include <SPI.h>

const byte SHIFTON = 4; //CE pin for 74hc165
const byte LATCH = 9;


void setup ()
{

  SPI.begin ();
  Serial.begin (9600);
  pinMode (SHIFTON, OUTPUT); 
  digitalWrite (SHIFTON, LOW); //enable the shift register
  pinMode (LATCH, OUTPUT);
  digitalWrite (LATCH, HIGH);
  byte RXADDRB4;

  findRXADDRESS();
  byte RXADDRESS[] = {192, 168, 1, RXADDRB4}; //This devices address

  //turn shift register off
  digitalWrite (SHIFTON, HIGH);
}

void findRXADDRESS()
{
    for (int i=8; i < 0; i--) {
    digitalWrite (LATCH, LOW);
    digitalWrite (LATCH, HIGH);  
    delay(5);
    }
  RXADDRB4 = SPI.transfer (0);
}

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: 74hc165 incorrect data after tri-stating

Post by adafruit_support_mike »

It looks like you're calling SPI.transfer() eight times for the same byte of input from the '165.

The first problem is that SPI.transfer() pulls 8 bits at a time. The second problem is that a '165 isn't an SPI device. The function you want is shiftIn():

http://arduino.cc/en/Reference/ShiftIn

That was written specifically for devices like the '165.

Robospud
 
Posts: 11
Joined: Tue Oct 22, 2013 2:55 pm

Re: 74hc165 incorrect data after tri-stating

Post by Robospud »

Thankyou for pointing out the read 8 times that was me failing to understand the example code slightly and as it worked I thought it was fine. I have changed the code to remove that loop.

Code: Select all

void findRXADDRESS()
{
    digitalWrite (LATCH, LOW);
    digitalWrite (LATCH, HIGH);
    RXADDRB4 = SPI.transfer (0); 
}
That piece of code is edited but was found in an example of how to use the 74hc165 on the spi bus. As I stated before it works without the tri-state buffer to isolate it but when that chip is connected I get 255 when the final bit is set high.

From the ShiftIn page:
Note: this is a software implementation; Arduino also provides an SPI library that uses the hardware implementation, which is faster but only works on specific pins.
Is there any point of using the ShiftIn if it works over spi already do I gain anything other than being able to remap the pins for usage (I'd rather not use more pins than necessary as the nrf905 already uses a large number of pins).

Robospud
 
Posts: 11
Joined: Tue Oct 22, 2013 2:55 pm

Re: 74hc165 incorrect data after tri-stating

Post by Robospud »

I have solved my issue myself. I had a short due to missing insulation part way down the chip enable wire. this led to 5v being applied as that was the final output of the shift register if the final bit was high. This in turn set the tri-state buffer so it read as all high which set the value at 255.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: 74hc165 incorrect data after tri-stating

Post by adafruit_support_mike »

Looks like you beat me to the solution while I was writing a reply.

In the spirit of better late than never, here's what I had:

In this case, the main advantage of using hardware SPI over shiftIn() is pin count, but the difference is only one pin.

The actual data transfer between a 74HC165 and a microcontroller takes three pins: LATCH, CLK, and DATA. Hardware SPI gives you CLK and DATA, but costs you an ENABLE pin to make the '165 share the pins with a real SPI device. You actually use more pins with hardware SPI, but gain the option of sharing two of them with other devices.

For one byte, the speed difference between hardware and software SPI is negligible.. hardware SPI can load a byte in 1 microsecond (assuming a 16MHz system clock) and software SPI will do it in 3-4 microseconds. The difference in overall memory footprint will also be small since the SPI library has a larger footprint than the code for shiftIn().

On the flipside, trying to make a 74HC165 share the SPI pins with a real SPI device costs you another chip and a pin to control it. The basic design tradeoff is that using another pin will let you eliminate a chip (and some problems associated with it), while using the chip will save you a pin.

WRT the problems you're having with the tristate buffer, I'd check everything *except* the data path between the 74HC165 and the buffer. A buffer doesn't have memory, and it won't see the 8th bit from a 74HC165 until the other 7 have already been transmitted. Having the last bit effect the ones that come before it would violate the basic design of the '165

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”