Connecting the Raspberry PI to a shift input board uses less GPIO pins and giving you eight inputs. To connect this you need to enable the SPI (Serial Peripheral Interface) chip interface. The chip reads eight parallel inputs and converts it to a serial data stream. It is possible to chain more than one chip to increase the amount of inputs or use the another chip for outputs (74HC595) or analogue inputs (MCP3008).
When CE is high the chip will not output values. When PL is low inputs D0 to D7 are read, then when PL is high D0 to D7 and the serial value is sent to Q7 (Pin 9). Q7 (Pin 7) sends the inverse of Q7 (Pin 9). CP is a clock pulse required for the operations to work. DS is linked to the output of another chip and is used to send that chips data when the CE is high.
A tac switches are connected to D0 to D8 inputs with 10KΩ pull down resistor to keep the values to low when switch is not connected. Any input connections (D0 to D8) not being used must be connected to GND or the value could change randomly. The other connections are to the Raspberry PI.
The CE is pulled high as there is only one chip in this system.
The SPI interface sequence and timing is taken care of buy the Raspberry PI SPI interface. The code required is as below.
The 74HC165 does not really support the SPI interface properly because PL must be cycled to read the parallel inputs this is done by reading (or writing) to the other channel. Read channel 1 then 0 and the data will be read when on channel 0 but the chip has connected to channel 1. The chip works well when used with the 74HC595 chip in series.
while True:
resp = spiRead(1)
resp = spiRead(0)
print ("Input Responce = {}".format(resp))
The program load the SPI and time modules. The spiRead function opens the channel and read from address zero waits half a second then returns the value. The main loop reads from channel 1 then channel 0 to make the chip read the inputs, then value and printed to the screen.
Install and enable the SPI interface
- First make sure the system is up to date
sudo apt-get update
sudo apt-get upgrade
sudo reboot - To install the development software that includes spi_dev type the following command. Note:Raspberry PI needs internet connection for this to work.
sudo apt-get install python-dev python3-dev
The command will indicate the package size before installing. Then install the spidev for Pyhon with the below commands.
cd ~
git clone https://github.com/doceme/py-spidev.git
cd py-spidev
make
sudo make install - Enable the SPI interface
- sudo raspi-config select Advanced the enable SPI and set to load by default.
- Reboot the Raspberry PI
- sudo reboot
- To check that the interface is enabled type lsmod and check that spi_bcm2835 is listed.
74HC165 connections
Pin
|
Signal
|
Description
|
1
|
PL
|
Asynchronous
parallel load input (active LOW)
|
2
|
CP
|
Clock
input
|
3
|
D4
|
Parallel
input 5
|
4
|
D5
|
Parallel
input 6
|
5
|
D6
|
Parallel
input 7
|
6
|
D7
|
Parallel
input 8
|
7
|
Q7
|
Complementary
output from the last stage
|
8
|
GND
|
Ground
|
9
|
Q7
|
Serial
output from the last read
|
10
|
DS
|
Serial
data input
|
11
|
D0
|
Parallel
input 1
|
12
|
D1
|
Parallel
input 2
|
13
|
D2
|
Parallel
input 3
|
14
|
D3
|
Parallel
input 4
|
15
|
CE
|
Clock
enable input (active LOW)
|
16
|
VCC
|
Positive
supply voltage
|
How the SPI interface data is read
When CE is high the chip will not output values. When PL is low inputs D0 to D7 are read, then when PL is high D0 to D7 and the serial value is sent to Q7 (Pin 9). Q7 (Pin 7) sends the inverse of Q7 (Pin 9). CP is a clock pulse required for the operations to work. DS is linked to the output of another chip and is used to send that chips data when the CE is high.
Wiring Connections
A tac switches are connected to D0 to D8 inputs with 10KΩ pull down resistor to keep the values to low when switch is not connected. Any input connections (D0 to D8) not being used must be connected to GND or the value could change randomly. The other connections are to the Raspberry PI.
The CE is pulled high as there is only one chip in this system.
Pin
|
Signal
|
Description
|
GPIO
|
RPI Pin
|
1
|
PL
|
Parallel
load inputs
|
CS1
|
26
|
2
|
CP
|
Clock
input
|
SCLK
|
23
|
8
|
GND
|
Ground
|
GND
|
6
|
9
|
Q7
|
Serial
output from the last read
|
MISO
|
21
|
15
|
CE
|
Clock
enable
|
GND
|
6
|
16
|
VCC
|
Positive
supply voltage
|
3.3 Volts
|
1
|
The 74HC165 does not really support the SPI interface properly because PL must be cycled to read the parallel inputs this is done by reading (or writing) to the other channel. Read channel 1 then 0 and the data will be read when on channel 0 but the chip has connected to channel 1. The chip works well when used with the 74HC595 chip in series.
import spidev
import time
spi = spidev.SpiDev()
import time
spi = spidev.SpiDev()
def spiRead(channel):
spi.open(0,channel)
spiValue = spi.xfer2([0])
time.sleep(0.5)
spi.close()
return spiValue
spiValue = spi.xfer2([0])
time.sleep(0.5)
spi.close()
return spiValue
while True:
resp = spiRead(1)
resp = spiRead(0)
print ("Input Responce = {}".format(resp))
The program load the SPI and time modules. The spiRead function opens the channel and read from address zero waits half a second then returns the value. The main loop reads from channel 1 then channel 0 to make the chip read the inputs, then value and printed to the screen.
Hi Rob...
ReplyDeleteThis has really helped. Do you perhaps have the java code using the SPI library? i cannot get it to work using java. The spi only have two methods and the return value is either 1 or -1.
Thanks
Brian
Hi Brian,
DeleteSorry I have not tried JAVA on the PI yet!
But I did find a site that may help you http://pi4j.com/
Good luck with your projects
Robert
Ok, I i can just ask you a question... What data do i need to send to the 74hc165. The java library (SPI) expects a byte array and im not sure what size i need to make this and what data i need to pass in. I was assuming you dont 'pass' data into this shift register but only read the response.
ReplyDelete-> int wiringPiSPIDataRW (int channel, unsigned char *data, int len);
Appreciated
Brian
Brian
DeleteOk so first I will say I don't know much about the java libary and I think you are talking about PI4J interface. I have had a quick look and I think the link below will help it is used on the MCP3008 which I have also used in Python.
https://github.com/Pi4J/pi4j/blob/master/pi4j-example/src/main/java/SpiExample.java
Note: for the 74HC165 you have to read both channel 0 and then 1 to get it to output this is because it does not fully support the SPI interface. I am not sure is required as a byte array sorry.
The problem could be that the SPI implementation in JAVA will not support this chip properly.
I hope this helps
Robert
Hi Rob, thanks for the good tutorial!
ReplyDeleteI have a question.
I am going to using Raspberry pi 3 to create a wire checking tool. My plan is connect Raspi -> send serial data to 74HC595 -> a bust of wire (100 channels) -> get data from 74HC165 -> get serial data back to Raspi and check to know what wire is broken.
Please give me the suggestion about the library, Wiring Connections (especially for Raspi 3, multi 74HC,...), ... I want to use python for my app.
Thanks a lot!
Best regards,
Huy.