I'm trying to read data from an ADS1115 ADC attached to the I²C link of my Raspi 3B using pigpiod
, but get nothing. In order to pin down the error, I took a deep look at the config I write beforehand into the ADC's config register 0x01 to find out that the data, which are effectively stored in the register, are apparently not the ones I had sent to the device. This happens during the init of the device:
int Initialize (int handle)
{
int ret = 0;
uint16_t adc_config = 0;
int pigpiod_handle = handle;
cout << "Initializing display and dimmer ADC...";
i2c_handle = i2c_open (pigpiod_handle, 1, 0x48, 0);
if (i2c_handle < (unsigned int) 0) {
ret = errno;
cout << "failed! Error: " << strerror (errno) << endl;
}
else {
uint16_t reg = 0x0000;
SetADCConfigBitfield (&adc_config, 0x8000, 0x8000); // Conversion: single.
SetADCConfigBitfield (&adc_config, 0x5000, 0x7000); // Input: AIN1.
SetADCConfigBitfield (&adc_config, 0x0200, 0x0E00); // Gain: ± 4096 mV.
SetADCConfigBitfield (&adc_config, 0x0000, 0x0100); // Mode: continuous.
SetADCConfigBitfield (&adc_config, 0x0000, 0x00E0); // Data rate: 8 samples / second.
SetADCConfigBitfield (&adc_config, 0x0000, 0x0010); // Comparator mode: traditional.
SetADCConfigBitfield (&adc_config, 0x0000, 0x0008); // Comparator polarity: active low.
SetADCConfigBitfield (&adc_config, 0x0000, 0x0004); // Comparator latching: off.
SetADCConfigBitfield (&adc_config, 0x0003, 0x0003); // Comparator queue: off.
cout << "¤¤ " << std::bitset<16> (adc_config) << " ¤¤" << endl;
ret += i2c_write_byte_data (vfd::pigpiod_handle, vfd::i2c_handle, 0x01, adc_config >> 8);
ret += i2c_write_byte_data (vfd::pigpiod_handle, vfd::i2c_handle, 0x01, adc_config & 0xFF);
reg = i2c_read_byte_data (vfd::pigpiod_handle, vfd::i2c_handle, 0x01) << 8;
reg |= i2c_read_byte_data (vfd::pigpiod_handle, vfd::i2c_handle, 0x01);
cout << "±± " << std::bitset<16> (reg) << " ±±" << endl;
if (ret == 0) {
cout << "done. Handle: " << vfd::spi_handle << "." << endl;
}
else cout << "ADC initialization failed! Error: " << ret << "." << endl;
}
return ret;
}
void SetADCConfigBitfield (uint16_t *config, uint16_t value, uint16_t mask)
{
*config &= ~mask;
*config |= (value & mask);
}
I took SetADCConfigBitfield ()
and the various parameter values directly from the driver written by Elektor Labs (which I can't use because of incompatibilities). Here is the relevant part of my app's output:
Initializing display and dimmer ADC...
¤¤ 1101001000000011 ¤¤
±± 1000010110000101 ±±
done. Handle: 1.
As you can see, when I read the register immediately after writing, I get completely different data. What is the reason for this? Am I doing anything wrong?
UPDATE Here is the link to the datasheet. See pp. 28–29: ADS111x datasheet