PCF8591 ADC and DAC (YL-40)
The NXP PCF8591 on the YL-40 module: four 8-bit analog inputs and one analog output on I2C.
Aliases: YL-40, PCF8591 module, AD/DA converter. It is the analog board of the Freenove and SunFounder kits, and the way a Raspberry Pi, which has no analog inputs, reads a sensor.
Pins
| Pin | What it does |
|---|---|
AOUT |
The DAC's output, while it is enabled. |
AIN0 to AIN3 |
The four analog inputs, 0 V to the supply. |
SCL, SDA |
The I2C bus; the module has its pull-ups. Address 0x48. |
GND, VCC |
Ground and the supply, 2.5 to 6 V. |
Properties
jumpers: on (as shipped) puts the board's own sensors on three inputs, the
light-dependent resistor on AIN0, the thermistor on AIN1 and the blue trimmer
on AIN3. Off, every input is yours.
While it runs
The three sliders are the light on the LDR, the temperature at the thermistor and
the trimmer's position. The LED beside AOUT lights with the DAC's voltage.
Reading it on an Arduino
With the Adafruit library, which Mokxi ships as Adafruit_PCF8591.h:
#include <Wire.h>
#include <Adafruit_PCF8591.h>
Adafruit_PCF8591 pcf = Adafruit_PCF8591();
void setup() {
Serial.begin(9600);
pcf.begin(); // 0x48
pcf.enableDAC(true);
}
void loop() {
Serial.println(pcf.analogRead(3)); // the trimmer, 0 to 255
pcf.analogWrite(200); // about 3.9 V on AOUT
delay(250);
}
With Wire.h alone: write the control byte (bit 6 the DAC enable, the low two bits
the channel), then read two bytes and keep the second.
What the model gets right
From the NXP datasheet:
The read is one conversion behind. Each read starts a conversion and sends the result of the one before; the first byte after power-on is 0x80. A sketch that switches channel and reads one byte gets the old channel's value, which is why every tutorial reads twice.
All four input modes. Four single-ended inputs; three differential (each
against AIN3); two single-ended and one differential; or two differential.
Differential results are two's complement, -128 to 127.
Auto-increment walks the channels after each conversion, wrapping at the mode's channel count.
The DAC puts VCC x value / 256 on AOUT while it is enabled and leaves the
pin high impedance when it is not.
The board's dividers. The LDR and the thermistor each sit under a 10 k pull-up, so more light and more heat both read lower; the trimmer is across the supply. Each drives its input as the divider it is, so a wire you add to the same input fights it as it would on the real board.
What it does not model
The converter's offset and gain errors (a few counts on a real chip), the
oscillator and its output, the external reference (the YL-40 ties it to the
supply, as here), and the load of the LED on AOUT. The DAC buffer's source
resistance is an assumed 50 ohm.
Common mistakes
Reading one byte after changing channel, and getting the previous channel.
Expecting the LDR to read higher in more light: on this board it reads lower.
Leaving the jumpers on and wiring your own sensor to AIN0, AIN1 or AIN3: the
board's sensor fights it. Take the jumper off.
See it in action
Analog board reads all three sensors and drives the DAC from the trimmer. Open it at /templates.