johnmitakz
Posts: 7
Joined: Wed Feb 03, 2016 8:53 am

I2C timeout between writing and reading from an ADC device

Wed Feb 03, 2016 9:08 am

Hi. I have an rpi2 with (several) ADC Pi Plus boards on top from abelectronics. I have read through their 'manual' at https://github.com/abelectronicsuk/ABEl ... E_ADCPi.py and ported it to Java using pi4j. After some tries I got it working, but apparently I have to use a timeout between the config write that switches ADC channel and reading new values. Weird, because in the original perl sample there is no waiting between reading the different channels https://github.com/abelectronicsuk/ABEl ... voltage.py If I run the sample (and remove the 0.5sec sleep) it almost instantly refreshes all the channels without any problem.

This is what I do (pseudo) :

Code: Select all

    write(1001 0000); //channel 1, continuous mode, PGA1, 12bit resolution
    read(); //Reading 4 bytes, loop until highest bit of 4th byte is '1', then use first 2 bytes as the 'value'
    write(1011 0000); //channel 2, continuous mode, PGA1, 12bit resolution
    read(); //Reading 4 bytes, loop until highest bit of 4th byte is '1'
=>last read would still return the value from channel 1 although we switched to channel 2

If I now do:

Code: Select all

   write(1001 0000); //channel 1, continuous mode, PGA1, 12bit resolution
    read(); //Reading 4 bytes, loop until highest bit of 4th byte is '1'
    write(1011 0000); //channel 2, continuous mode, PGA1, 12bit resolution

    wait(100msec)

    read(); //Reading 4 bytes, loop until highest bit of 4th byte is '1'
=>last read now returns value of channel2 = OK

Thing is that the arbitrary wait is a bit fishy and since the Perl sample doesn't need it, I'm trying to find out what I'm doing wrong. I'm accessing the bus via I2CFactory.getInstance(I2CBus.BUS_1). Device is accessed via bus.getDevice(<address>), I'm using I2CDevice.write() to write the byte config and I2CDevice.read(result, 0, 4) to read the 4 bytes result.

Something I have noticed is that in Perl (ABE_ADCPi.py L143 ) they use: self._bus.read_i2c_block_data(address, config, 4). If you inspect the code more closely, you'll see that they set the channel (= update the internal byte representing the config) at L127. However, the config is never written to the device. But, when they perform the above read instruction they pass along the config byte as well. So my guess is that the magic is in this function as it will probably first send the "config" byte (and then use some internal wait or status check?) before reading the result. But this function is Perl/I2C specific and has nothing todo with the ADC in question. So, am I missing something here in Java? Or ...

Return to “Java”