You are not logged in.
Pages: 1
Topic closed
Hi ,
I am unable to figure out what buffers to define to read multiple analog input channels of the PCF8591 A/D converter. I am able to read only the first channel successfully. The device address and the input channel addresses are correct. Please have a look at my code.
//assigning variables to outputs, these variables are WRITE-ONLY
//long output(0) adc_value;
long output(0) analog_in1;
long output(1) analog_in2;
//declaration of variables
long i2c_bufTx[3]; //buffer for transmitting data
long i2c_bufRx[3]; //buffer for receiving data
long i2c_bus_handle;
long i2c_chip_address;
long i2c_write_count;
long i2c_read_count;
long i2c_ret_fun;
//long output(2) freq;
//the init procedure is executed once when the REXLANG function block initializes
int init(void)
{
i2c_bus_handle = Open(I2CDEV_FNAME); // open I2C bus
/* Address: 1 1 0 1 A2 A1 A0 */
i2c_chip_address = 0x48; // 7-bit address of the I2C device
return 0;
}
//the main procedure is executed once in each sampling period
long main(void)
{
/* Configuration register:
=====================================================================================
| bit 7 | bit 6-5 | bit 4 | bit 3-2 | bit 1-0 |
-------------------------------------------------------------------------------------
| 1=start conversion | 00 = channel 1 | 1 = continuous | 00 = 12-bit | 00 = gain x1 |
| 0=no effect | 01 = channel 2 | 0 = one-shot | 01 = 14-bit | 01 = gain x2 |
| | | | 10 = 16-bit | 10 = gain x4 |
| | | | 11 = 18-bit | 11 = gain 8x |
=====================================================================================
*/
i2c_bufTx[0] = 0x00; // read channel 1 .I am able to read channel 1 successfully
i2c_bufTx[0] = 0x01; // read channel 2
i2c_write_count = 1;
i2c_read_count = 2;
//Sending data via I2C
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
analog_in1 = (i2c_bufRx[0]<<8) + i2c_bufRx[1];
analog_in2 = (i2c_bufRx[0]<<8) + i2c_bufRx[1];
return 0;
}
//the exit procedure is executed once when the task is correctly terminated
// (system shutdown, downloading new control algorithm, etc.)
long exit(void)
{
if(i2c_bus_handle>=0) Close(i2c_bus_handle); // close I2C bus
return 0;
Offline
Hi,
according to PFC8591 datasheet, the A/D converter can transmit more channels in one response - using auto-increment flag. It means that if you send control byte 0x04 and read 3 bytes, you will get previously converted byte (and probably throw it away) and 2 bytes (channel 0 and channel 1).
PFC8591 is 8bit ADC - it means that you don't have to combine two received bytes into one analog input:
//analog_in1 = (i2c_bufRx[0]<<8) + i2c_bufRx[1];
analog_in1 = i2c_bufRx[1];
I changed your code, mainly Configuration register table for your information and control byte command. See the code:
//assigning variables to outputs, these variables are WRITE-ONLY
//long output(0) adc_value;
long output(0) analog_in1;
long output(1) analog_in2;
//declaration of variables
long i2c_bufTx[3]; //buffer for transmitting data
long i2c_bufRx[3]; //buffer for receiving data
long i2c_bus_handle;
long i2c_chip_address;
long i2c_write_count;
long i2c_read_count;
long i2c_ret_fun;
//long output(2) freq;
//the init procedure is executed once when the REXLANG function block initializes
int init(void)
{
i2c_bus_handle = Open(I2CDEV_FNAME); // open I2C bus
/* Address: 1 1 0 1 A2 A1 A0 */
i2c_chip_address = 0x48; // 7-bit address of the I2C device
return 0;
}
//the main procedure is executed once in each sampling period
long main(void)
{
/* Configuration register:
===============================================================================================================
| bit 7 | bit 6 | bit 5-4 | bit 3 | bit 2 | bit 1-0 |
---------------------------------------------------------------------------------------------------------------
| 0 | 1 = Analog output enable | 00 = single ended inputs | 0 | 1 = auto-increment | 00 = channel 0 |
| | | 01 = 3 differential inputs | | | 01 = channel 1 |
| | | 10 = mixed inputs | | | 10 = channel 2 |
| | | 11 = 2 differential inputs | | | 11 = channel 3 |
===============================================================================================================
*/
i2c_bufTx[0] = 0x04; // read channel 0 with auto-increment flag (00000100b)
i2c_write_count = 1;
i2c_read_count = 3;
//Sending data via I2C
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//some old data in i2c_bufRx[0] from previous conversion
analog_in1 = i2c_bufRx[1];
analog_in2 = i2c_bufRx[2];
return 0;
}
//the exit procedure is executed once when the task is correctly terminated
// (system shutdown, downloading new control algorithm, etc.)
long exit(void)
{
if(i2c_bus_handle>=0) Close(i2c_bus_handle); // close I2C bus
return 0;
Unfortunately we don't have this AD converter in stock so we couldn't test it.
Hope it will help you.
Offline
It worked perfectly !.
Thanks a lot for taking the time to go through the device's datasheet and explain the solution so patiently.
Bless you ! Thanks !
Offline
Good to hear that it's working now!
Thank you for your reply and good luck!
Offline
Pages: 1
Topic closed