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
[codesyntax lang=”python”]
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)
[/codesyntax]
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