YL-40 module which is available on Aliexpress is a cheap evaluation board to test PCF8591. It has a LDR, a thermistor, and a potentiometer connected to PCF8591. Its schematic diagram is shown below.
Figure. Schematic circuit for YL-40 module.
(source: https://wiki.kewl.org/dokuwiki/_detail/interfaces:adda-sch.jpg)
An example program to read analog input channels and to write to analog output using Raspberry PI is shown in the following list, i2c_aio.cpp. The include file "ce_i2c.h" is also located in the same folder.
// File: i2c_aio.cpp // Description: analog input and analog output with PCF8591 // WebSite: http://cool-emerald.blogspot.com // MIT License (https://opensource.org/licenses/MIT) // Copyright (c) 2020 Yan Naing Aye #include "stdio.h" #include "cstdint" #include "string" #include "ce_i2c.h" using namespace std; typedef struct { uint8_t feature; uint8_t ao; uint8_t ai[4]; } IOAnalog; uint8_t ao_last; void PCF8591Out(uint8_t chipno, uint8_t value) { char d[] = { 0,0,0,0}; int i2caddr = 0x48 + (chipno & 0x07); // i2c address int i2cbus = 1; CE_I2C chip1(i2cbus, i2caddr); d[0] = 0x44; // first byte in i2c wr is the control reg // | reserved | AO Enable | mode sel 1 | mode sel 0 | // | reserved | auto increase | channel no 1 | channel no 0 | // | 0 | 1 | 0 0 | // | 0 | 1 | 0 0 | // auto increase needs AO enable to keep internal osc running // mode = 00 for 4 single ended ai // start reading from channel 0 and then auto increase // second byte to write to Ao d[1] = value; chip1.Write(d, 2); // send new data ao_last = value; chip1.Close(); string str = "Chip " + to_string(chipno) + ", Ao: " + to_string(value); printf("%s\n",str.c_str()); } IOAnalog PCF8591In(uint8_t chipno) { IOAnalog value; char d[] = { 0,0,0,0,0,0 }; int i2caddr = 0x48 + (chipno & 0x07); // i2c address int i2cbus = 1; CE_I2C chip1(i2cbus, i2caddr); d[0] = 0x44; // first byte in i2c wr is the control reg // | reserved | AO Enable | mode sel 1 | mode sel 0 | // | reserved | auto increase | channel no 1 | channel no 0 | // | 0 | 1 | 0 0 | // | 0 | 1 | 0 0 | // auto increase needs AO enable to keep internal osc running // mode = 00 for 4 single ended ai // start reading from channel 0 and then auto increase chip1.Write(d, 1); // set control reg to start at channel 0 chip1.Read(d, 5); // read 5 byte reg value chip1.Close(); // d[0] is the last read value before this read value.ai[0] = d[1]; value.ai[1] = d[2]; value.ai[2] = d[3]; value.ai[3] = d[4]; value.ao = ao_last; string str = "Chip " + to_string(chipno) + ", Values: " + to_string(value.ai[0]) + ", " + to_string(value.ai[1]) + ", " + to_string(value.ai[2]) + ", " + to_string(value.ai[3]); printf("%s\n",str.c_str()); return value; } int main() { uint8_t v = 0; float x=0,dx=0,steps=10.0; dx = 3.3 / steps; for(int i=0; i < steps ;i++) { // d = v / 3.3 * 256 = v * 77.576 (for 8 bits, 3.3 V full scale) x += dx; v = uint8_t (x * 256.0 / 3.3); printf("x = %f v = %d \n", x,v); PCF8591Out(0,v); usleep(1000000); PCF8591In(0); usleep(2000000); } return 0; }
No comments:
Post a Comment
Comments are moderated and don't be surprised if your comment does not appear promptly.