
Raspberry Pi PCF8591 AD-DA Sensor Python Interface
In this demo we'll be using Python Tkinter to build a user interface to control-read a PCF8591T sensor module. The PCF8591T features four-8-bit analog to digital converters and a single 8-bit digital to analog converter.
This will operate through the I2C interface on the Raspberry Pi.
Tkinter will be used to program general the user interface pictured
above. This features four buttons (labeled AIN0-AIN4) that when pressed
will read corresponding AD channel.
In addition one can enter a values from 0-255 in the box and
when AOUT is pressed the value is written to the DA channel where the
output voltage can be measured with a volt meter.
In this case I connected the AOUT channel to AIN2 so the output value can be read back. The fact that the AD and DA process uses only 8-bits introduced an error of one or two LSB. The power supply connection for VCC was only 4.75 volts and the most of the apparent error was on the high end.
In addition I used a level converter between the Raspberry Pi's I2C operating at 3-volts with the PCF8255 operating at 5-volts. The converter should not have contributed to the conversion-read back errors.
One oddity is when reading one of the AD channels one must perform what I call a dummy read. Then read it again to get a value. The first read begins the conversion - the next get the first value. As long as one keeps reading the same channel, this only needs to be done once; change channels the process must be repeated.
The device has a sequential read mode for the four AD channels. See the spec sheet for more on that.
To write to the DA channel a single command must be written as follows:
bus.write_byte_data(address, 0x40, value)
Address of the device address, 0x40 is for function register to select DA, and value from 0-255 for the output voltage. The DA register like the AD registers are all 8-bit.
Some of the Tkinter design was adopted from Programming The Raspberry Pi
by Monk, Simon. The book covered almost nothing on hardware and that
wasn't the only problem I encountered. The book was written for Python 3
and above, but the smbus I used to access the I2C works in Python 2.7
not 3.
In addition using Tkinter with Python 2.7 the "T" must be upper case, with Python 3 lower case. That was a headache to find.
But the design works well and should be the basis for use with other I2C devices such as an Arduino. My next project is the use a similar interface to an Arduino to read Arduino's 10-bit AD converters.
Have fun.
Screenshots
Screenshot sdd4.png features Fluxbox, the Rox pinboard for icons, Rox-Filer, and this demo.
Screenshot sdd2.png features Openbox, the Rox pinboard for icons, Rox-Filer, Idle, and this demo.
# must use Python 2.7 import smbus import time from Tkinter import * #import Tkinter must start with capital 'T' # for RPI version 1, use "bus = smbus.SMBus(0)" bus = smbus.SMBus(1) # This is the address we setup in the PCF8591 address = 0x48 # 0x00 - 0x03 is AIN0 - AIN3 # bus.write_byte(address,0x00) class App: def __init__(self, master): frame = Frame(master) frame.pack() Label(frame, text="Analog Value = ").grid(row=0, columnspan=2) self.result_var = DoubleVar() # location to display data in result_var Label(frame, textvariable=self.result_var).grid(row=0, column=2) button0 = Button(frame, text="AIN0", command=self.read_AIN0) button0.grid(row=1, column=0) button1 = Button(frame, text="AIN1", command=self.read_AIN1) button1.grid(row=1, column=1) button2 = Button(frame, text="AIN2", command=self.read_AIN2) button2.grid(row=1, column=2) button3 = Button(frame, text="AIN3", command=self.read_AIN3) button3.grid(row=1, column=3) # get value for DA converter self.aout_var = DoubleVar() Entry(frame, textvariable=self.aout_var).grid(row=2, columnspan=4) button4 = Button(frame, text="AOUT", command=self.writeAOUT) button4.grid(row=3, columnspan=4) def read_AIN0(self): bus.write_byte(address,0x40) bus.read_byte(address) # dummy read to start conversion temp = bus.read_byte(address) self.result_var.set(temp) def read_AIN1(self): bus.write_byte(address,0x41) bus.read_byte(address) # dummy read to start conversion temp = bus.read_byte(address) self.result_var.set(temp) def read_AIN2(self): bus.write_byte(address,0x42) bus.read_byte(address) # dummy read to start conversion temp = bus.read_byte(address) self.result_var.set(temp) def read_AIN3(self): bus.write_byte(address,0x43) bus.read_byte(address) # dummy read to start conversion temp = bus.read_byte(address) self.result_var.set(temp) def writeAOUT(self): temp = self.aout_var.get() # 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) root = Tk() root.wm_title("PCF8591T Demo") app = App(root) root.geometry("300x120+0+0") root.mainloop()
Downloads:
PCF8591 spec sheet. (PDF file)
PCF8591 module. (picture)
Arduino Projects
- Testing the Keyes IR Sensor Module with Arduino
- How to Connect Easy Driver Micro-Stepper Controller to Arduino
- Connect Arduino to LCD Display with 74164 Shift Register
- Arduino with LCD Display and DS18B20 Temperature Sensor
- Below has differing code from the above. Works the same.
- Arduino with LCD Display and DHT11 Temperature-Humidity Sensor
- In Depth Look at AC Power Control with Arduino
- Four part series:
- Experimenting with the PCA9555 32-Bit GPIO Expander with Arduino
- PCA9555 32-Bit GPIO Expander with Arduino and a 4X4 Keypad
- PCA9555 32-Bit GPIO Expander with Arduino Using Interrupts
- PCA9555 32-Bit GPIO Expander with Arduino and LCD Display
- YouTube Video Interfacing PCA9555 to Arduino
Raspberry Pi
- Build Your Own Raspberry Pi Arduino System
- Setting up Openbox for Raspberry Pi
- Raspberry Pi Linux Permissions-Program Installations
- Connecting Ds1307 RTC to Raspberry Pi
- Raspberry Pi Window Manager Control with Xinitrc
- Setup Fstab, Symbolic Links for Raspberry Pi
- Change Background Wallpaper on Raspberry Pi with FEH
- Setup JWM Window Manager for Raspberry Pi
Videos:
Raspberry Pi, Arduino, and Learning Linux
Raspberry PI Arduino Advanced Interface
Tkinter with Raspberry Pi and PCF8591 AD-DA Sensor
- Added February 17, 2014:
- Connecting Raspberry Pi to Arduino with I2C Interface
- Use Python Tkinter with Raspberry Pi and PCF8591 AD-DA Sensor
- Additional Program not in the Repositories
- Add Zmixer ALSA Sound Control to Raspberry Pi
- Adding Lightweight Beaver Text Editor to Raspberry Pi
- Add Viewnior Lightweight Image Viewer for Raspberry Pi
- Connect Raspberry Pi to Arduino
- Connecting Raspberry Pi to Arduino with I2C Interface
- Connect Serial LCD to Raspberry Pi
- Serial Read from Arduino to Raspberry Pi
- Arduino Raspberry Pi Interface with LCD Display
- arduino_ds18b20X2.ino
Linux Videos
Live Linux Distro for Using Printer Port with Electronics
Using the powerful Rox-Filer system in Linux
Use FEH under Linux for a Wallpaper Setter
How to create Symbolic links in Linux