1

I have a PCF8591 analog to digital converter. I have it reading from AIN0 (thanks to @joan), but I cant find a reference for getting it to read from multiple channels. How would I get it to read input from channel 0-3 all at the same time?

pi@raspberrypi ~/Desktop/PiControl $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

My code:

import time
#board pins
#pin 3=SDA
#pin 5=SCL


from smbus import SMBus

bus = SMBus(1)

bus.write_byte(0x48,0) # i2cget -y 1
last_reading =-1

while(0 == 0): # do forever
        reading = bus.read_byte(0x48) # read A/D
        print('analog reading: '+str(reading))
        time.sleep(3)#sec

Updated code:

#!/usr/bin/env python
import time
#board pins
#pin 3=SDA
#pin 5=SCL

from smbus import SMBus

bus = SMBus(1)
temp_pin=0
light_pin=1


def read_ain(i):    
    global bus
    bus.write_byte(0x48, i)
    bus.read_byte(0x48)#first 2 are last state, and last state repeated.
    bus.read_byte(0x48)
    return bus.read_byte(0x48)

while(True):
    print read_ain(0)
    print read_ain(1)
    print "---"
    #print get_temp()
    #print get_light_level()
    time.sleep(3)#sec

returns:

220
220
---
....
3

You control the device by sending it two bytes. The first is the command code. The second is the byte to write to the digital to analogue converter.

The command byte is structured as follows.

7 6 5 4 3 2 1 0
0 X X X 0 X X X
  | | |   | | |
  A B B   C D D

A 0 D/A inactive
  1 D/A active

B 00 single ended inputs
  01 differential inputs
  10 single ended and differential
  11 two differential inputs

C 0 no auto inc
  1 auto inc

D 00 select channel 0
  01 select channel 1
  10 select channel 2
  11 select channel 3

Assuming you don't want to write to the DAC and you want normal inputs set A and B to 0.

To auto increment through the ADC inputs set C to 1 and D to 0.

To specify the ADC input set C to 0 and D to the desired input (0-3).

So instead of writing 0 to the device either write 4 just the once at the start of the program to auto increment through the ADC inputs.

bus.write_byte(0x48, 4)

while True:
   reading = bus.read_byte(0x48) # read next A/D
   print('analog reading: ' + str(reading))
   time.sleep(3)

or write 0-3 prior to the read to specify the ADC input to be read.

i = 0
while True:
   bus.write_byte(0x48, i)
   i = i + 1
   if (i > 3):
      i = 0
   reading = bus.read_byte(0x48) # read next A/D
   print('analog reading: ' + str(reading))
   time.sleep(3)

EDITED TO ADD EXAMPLE CODE

#!/usr/bin/env python

import smbus
import time
import curses

# 2014-08-26 PCF8591-x.py

# Connect Pi 3V3 - VCC, Ground - Ground, SDA - SDA, SCL - SCL.

# ./PCF8591-x.py

bus = smbus.SMBus(1)

stdscr = curses.initscr()
curses.noecho()
curses.cbreak()

aout = 0

stdscr.addstr(10, 0, "Brightness")
stdscr.addstr(12, 0, "Temperature")
stdscr.addstr(14, 0, "AOUT->AIN2")
stdscr.addstr(16, 0, "Resistor")

stdscr.nodelay(1)

try:

   while True:

      for a in range(0,4):
         aout = aout + 1
         bus.write_byte_data(0x48,0x40 | ((a+1) & 0x03), aout)
         v = bus.read_byte(0x48)
         hashes = v / 4
         spaces = 64 - hashes
         stdscr.addstr(10+a*2, 12, str(v) + ' ')
         stdscr.addstr(10+a*2, 16, '#' * hashes + ' ' * spaces )

      stdscr.refresh()
      time.sleep(0.04)

      c = stdscr.getch()

      if c != curses.ERR:
         break

except:
   pass

curses.nocbreak()
curses.echo()
curses.endwin()
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.