In this article we look at another sensor – this time its the PCF8591 and we will connect it to our Beaglebone and we will have a python example
First lets take a look at the sensor in question
The PCF8591 is a single-chip, single-supply low-power 8-bit CMOS data acquisition device with four analog inputs, one analog output and a serial I2C-bus interface. Three address pins A0, A1 and A2 are used for programming the hardware address, allowing the use of up to eight devices connected to the I2C-bus without additional hardware. Address, control and data to and from the device are transferred serially via the two-line bidirectional I2C-bus.The functions of the device include analog input multiplexing, on-chip track and hold function, 8-bit analog-to-digital conversion and an 8-bit digital-to-analog conversion. The maximum conversion rate is given by the maximum speed of the I2C-bus.2.
Features and benefits
Single power supply
Operating supply voltage 2.5 V to 6.0 V
Low standby current
Serial input and output via I2C-bus
I2C address selection by 3 hardware address pins
Max sampling rate given by I2C-bus speed
4 analog inputs configurable as single ended or differential inputs
Auto-incremented channel selection
Analog voltage range from VSS to VDD
On-chip track and hold circuit
8-bit successive approximation A/D conversion
Multiplying DAC with one analog output.
Here is a sample module which also has 3 optional analog input devices
P4 connected to P4 shunt, selects the thermistor
P5 connected to P5 shunt, selects the photosensitive resistor
P6 connected to P6 shunt, selects 0-5V pot
Parts Required
Schematic/Connection
Beaglebone | Module |
3.3v – P9.3 | Vcc |
Gnd – P9.1 | Gnd |
SDA – P9.20 | SDA |
SCL – P9.19 | SCL |
Code Example
Save this as pcf8591.py
import smbus
import time
bus = smbus.SMBus(2)
#check your PCF8591 address by type in 'sudo i2cdetect -y -1' in terminal.
def setup(Addr):
global address
address = Addr
def read(chn): #channel
try:
if chn == 0:
bus.write_byte(address,0x40)
if chn == 1:
bus.write_byte(address,0x41)
if chn == 2:
bus.write_byte(address,0x42)
if chn == 3:
bus.write_byte(address,0x43)
bus.read_byte(address) # dummy read to start conversion
except Exception as e:
print ("Address: %s" % address)
print (e)
return bus.read_byte(address)
def write(val):
try:
temp = val # move string value to temp
temp = int(temp) # change string to integer
# print temp to see on terminal else comment out
bus.write_byte_data(address, 0x40, temp)
except Exception as e:
print ("Error: Device address: 0x%2X" % address)
print (e)
if __name__ == "__main__":
setup(0x48)
while True:
print ('AIN0 = ', read(0))
print ('AIN1 = ', read(1))
tmp = read(0)
tmp = tmp*(255-125)/255+125 # LED won't light up below 125, so convert '0-255' to '125-255'
write(tmp)
time.sleep(0.3)
Output
Run this example and you should see the following. You can see me tying the AIN0 and AIN1 to gnd at points in the output
(‘AIN0 = ‘, 0)
(‘AIN1 = ‘, 56)
(‘AIN0 = ‘, 0)
(‘AIN1 = ‘, 62)
(‘AIN0 = ‘, 0)
(‘AIN1 = ‘, 58)
(‘AIN0 = ‘, 66)
(‘AIN1 = ‘, 128)
(‘AIN0 = ‘, 155)
(‘AIN1 = ‘, 190)
(‘AIN0 = ‘, 204)
(‘AIN1 = ‘, 216)
(‘AIN0 = ‘, 226)
(‘AIN1 = ‘, 232)
(‘AIN0 = ‘, 243)
(‘AIN1 = ‘, 244)
(‘AIN0 = ‘, 247)
(‘AIN1 = ‘, 0)
(‘AIN0 = ‘, 216)
(‘AIN1 = ‘, 0)
Links