back to index

PCF8591-read


Why
How
      chip
      code
Usage
      options
      output
            examples
Compiling
Files
TODO

Why

The PCF8591 is a fairly inexpensive I2C ADC/DAC chip, with four 8-bit ADC inputs and one 8-bit DAC output.

It often comes on breakout boards. The boards, like eg. this one, sometimes come with example devices, here eg. a trimpot, a thermistor, and a photoresistor, on the inputs, and a red LED on the output. The LED doesn't light up below about half of the output range.

Python library is available.

For reading from shell scripts, especially on underpowered boards like Raspberry Pi 1, python is less suitable due to the overheads at process startup. Insane amount of files has to be read and interpreted. A frequently executed task will bring a significant load on the machine.


How

A simple C code was derived from the sw_chip_PCF8591 one.

As the sensor doesn't do conventional registers, and only bare reads and writes are used (so eg. i2cdump will show just all zeroes and confuse the register settings), the barest of interfacing will do. File and IOCTL access to /dev/i2c-something was therefore chosen.

chip

The chip operates in a simple way. Send a one-byte configuration, optionally with another byte (or bytes) to be written to the DAC output. Read raw bytes from the ADC, from a fixed channel or from autoincrementing sequence of individual inputs.

code

The code first opens the I2C device (or fails when device doesn't exist or is inaccessible). IOCTL I2C_SLAVE is executed on the resulting file handle, with the chip's address as parameter.

The config byte is sent (code fails here if the chip is not on the given address), optionally followed with DAC value.

Then several reads are issued. First byte is an old value from previous read.


Usage

options

If executed without options, it queries first BH1750 sensor on the /dev/i2c-1 bus. This is a default configuration on raspberry pi boards.

PCF8591 sensor read
Usage: pcf8591 [-v] [-x] [-O] [-o <DACval>] [-c <chan>] [-a <addr>] [-d <dev>]
ADC:
  -c <num>  display ADC channel (0..3), all if not specified
  -m <num>  set the input mux (0..3) (bits 4,5 of config; default 0, four separate inputs)
  -x        hex output
  -j        json format
DAC:
  -O        force DAC output (do not unset when DAC value not specified)
  -o <num>  set DAC value (0..255)
I2C:
  -a <num>  address, 0..7, default=0; adds to base address 0x48
  -d <dev>  specify I2C device, default /dev/i2c-1
general:
  -v        verbose mode
  -h,--help this help

output

If all is okay, result code is 0. Otherwise, if something crashes, result is 1.

If not verbose or help, only the measured value of the selected channel, or all four separated by space, is spat to stdout.

examples

read all four channels (0..3)

./pcf8591
236 255 155 97
 
read only channel 2
./pcf8591 -c 2
155
 
read all inputs, output in hexadecimal
./pcf8591 -x
ec ff e7 61
 
read all inputs, output in JSON /pcf8591 -j
 
read all inputs, output 0x9F (or, 159) to DAC
./pcf8591 -o 0x9f
255 223 97 237
 
read all inputs, keep DAC output enabled unchanged
./pcf8591 -O
255 223 97 237


Compiling

The code doesn't need any special compilation. A simple call will do:

or, for statically linked version,


Files


TODO


If you have any comments or questions about the topic, please let me know here:
Your name:
Your email:
Spambait
Leave this empty!
Only spambots enter stuff here.
Feedback: