This repository has been archived by the owner on Nov 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
spi_bitbang_test.py
108 lines (83 loc) · 2.82 KB
/
spi_bitbang_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python
#
# Bitbang'd SPI interface with an MCP3008 ADC device
# MCP3008 is 8-channel 10-bit analog to digital converter
# Connections are:
# CLK => 18
# DOUT => 23 (chip's data out, RPi's MISO)
# DIN => 24 (chip's data in, RPi's MOSI)
# CS => 25
import RPi.GPIO as GPIO
import time
import sys
CLK = 18
MISO = 23
MOSI = 24
CS = 25
def setupSpiPins(clkPin, misoPin, mosiPin, csPin):
''' Set all pins as an output except MISO (Master Input, Slave Output)'''
GPIO.setup(clkPin, GPIO.OUT)
GPIO.setup(misoPin, GPIO.IN)
GPIO.setup(mosiPin, GPIO.OUT)
GPIO.setup(csPin, GPIO.OUT)
def readAdc(channel, clkPin, misoPin, mosiPin, csPin):
if (channel < 0) or (channel > 7):
print "Invalid ADC Channel number, must be between [0,7]"
return -1
# Datasheet says chip select must be pulled high between conversions
GPIO.output(csPin, GPIO.HIGH)
# Start the read with both clock and chip select low
GPIO.output(csPin, GPIO.LOW)
GPIO.output(clkPin, GPIO.HIGH)
# read command is:
# start bit = 1
# single-ended comparison = 1 (vs. pseudo-differential)
# channel num bit 2
# channel num bit 1
# channel num bit 0 (LSB)
read_command = 0x18
read_command |= channel
sendBits(read_command, 5, clkPin, mosiPin)
adcValue = recvBits(12, clkPin, misoPin)
# Set chip select high to end the read
GPIO.output(csPin, GPIO.HIGH)
return adcValue
def sendBits(data, numBits, clkPin, mosiPin):
''' Sends 1 Byte or less of data'''
data <<= (8 - numBits)
for bit in range(numBits):
# Set RPi's output bit high or low depending on highest bit of data field
if data & 0x80:
GPIO.output(mosiPin, GPIO.HIGH)
else:
GPIO.output(mosiPin, GPIO.LOW)
# Advance data to the next bit
data <<= 1
# Pulse the clock pin HIGH then immediately low
GPIO.output(clkPin, GPIO.HIGH)
GPIO.output(clkPin, GPIO.LOW)
def recvBits(numBits, clkPin, misoPin):
'''Receives arbitrary number of bits'''
retVal = 0
for bit in range(numBits):
# Pulse clock pin
GPIO.output(clkPin, GPIO.HIGH)
GPIO.output(clkPin, GPIO.LOW)
# Read 1 data bit in
if GPIO.input(misoPin):
retVal |= 0x1
# Advance input to next bit
retVal <<= 1
# Divide by two to drop the NULL bit
return (retVal/2)
if __name__ == '__main__':
try:
GPIO.setmode(GPIO.BCM)
setupSpiPins(CLK, MISO, MOSI, CS)
while True:
val = readAdc(0, CLK, MISO, MOSI, CS)
print "ADC Result: ", str(val)
time.sleep(5)
except KeyboardInterrupt:
GPIO.cleanup()
sys.exit(0)