The Raspberry Pi doesn’t support any Analog to digital or digital to analog capabilities by default, so if you want to use analog sensors on Raspberry Pi, you will need some sort of external AD expansion board is required.
PCF8591 Information
A popular chip is the PCF8591, lets have a quick look at this chip
I used a Pioneer600 board which has one of these chips on it among other features
Parts
The Pioneer600 costs around $39 for many useful features
Name | Link |
Raspberry Pi 4 | Aliexpress product link |
Pioneer600 | Aliexpress product link |
DAC Example
C program based on BCM library
#include <bcm2835.h> #include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { char Buf[]={0, 0}; unsigned char value=0; if (!bcm2835_init()) return 1; bcm2835_i2c_begin(); // The I2C address of PCF8591 is 0x48. bcm2835_i2c_setSlaveAddress(0x48); bcm2835_i2c_set_baudrate(10000); printf("start..........\n"); while(1) { Buf[0] = 0x40; Buf[1] = value++; bcm2835_i2c_write(Buf, 2); printf("AOUT: %d\n", value); bcm2835_delay(20); } bcm2835_i2c_end(); bcm2835_close(); return 0; }
Save the file as “pcf8591.c”. Compile and run with:
gcc -Wall pcf8591.c -o pcf8591 -lbcm2835 sudo ./pcf8591
Python example using smbus
#!/usr/bin/python import smbus import time address = 0x48 cmd = 0x40 value = 0 bus = smbus.SMBus(1) while True: bus.write_byte_data(address,cmd,value) value += 1 if value == 256: value =0 print("AOUT:%3d" %value) time.sleep(0.01)
Save the file as “pcf8591.py” and execute it with:
sudo python pcf8591.py
C example using WiringPi
#include <wiringPi.h> #include <pcf8591.h> #include <stdio.h> #define Address 0x48 #define BASE 64 #define A0 BASE+0 #define A1 BASE+1 #define A2 BASE+2 #define A3 BASE+3 int main(void) { unsigned char value; wiringPiSetup(); pcf8591Setup(BASE,Address); while(1) { analogWrite(A0,value); printf("AOUT: %d\n",value++); delay(20); } }
Save the file as “pcf8591.c”. Compile and run with:
gcc -Wall pcf8591.c -o pcf8591 -lbcm2835 -lwiringPi sudo ./pcf8591
ADC Examples
C example using the BCM library
#include <bcm2835.h> #include <stdio.h> #include <unistd.h> int main(int argc, char **argv) { char Buf[]={0}; unsigned char i; if (!bcm2835_init())return 1; bcm2835_i2c_begin(); bcm2835_i2c_setSlaveAddress(0x48); bcm2835_i2c_set_baudrate(10000); printf("start..........\n"); while(1) { for(i = 0;i < 4;i++) { Buf[0] = i; bcm2835_i2c_write_read_rs(Buf,1,Buf,1); bcm2835_i2c_read (Buf,1); printf("AIN%d:%5.2f ",i,(double)Buf[0]*3.3/255); } printf("\n"); bcm2835_delay(100); } bcm2835_i2c_end(); bcm2835_close(); return 0; }
Save the file as “pcf8591.c”. Compile and run with:
gcc -Wall pcf8591.c -o pcf8591 -lbcm2835 sudo ./pcf8591
Python example
#!/usr/bin/python import smbus import time address = 0x48 A0 = 0x40 A1 = 0x41 A2 = 0x42 A3 = 0x43 bus = smbus.SMBus(1) while True: bus.write_byte(address,A0) value = bus.read_byte(address) print("AOUT:%1.3f " %(value*3.3/255)) time.sleep(0.1)
Save the file as “pcf8591.py” and execute it with:
sudo python pcf8591.py
C example using WiringPi
#include <wiringPi.h> #include <pcf8591.h> #include <stdio.h> #define Address 0x48 #define BASE 64 #define A0 BASE+0 #define A1 BASE+1 #define A2 BASE+2 #define A3 BASE+3 int main(void) { int value; wiringPiSetup(); pcf8591Setup(BASE,Address); while(1) { value = analogRead(A0); printf("Analoge: %dmv\n",value*3300/255); delay(1000); } }
Save the file as “pcf8591.c”. Compile and run with:
gcc -Wall pcf8591.c -o pcf8591 -lbcm2835 -lwiringPi sudo ./pcf8591