This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADC081C021: ADC reading issue

Part Number: ADC081C021

I have a problem with reading the ADC conversion result in normal mode i.e the address pointer register is set to 0(zero). When I try to read the result, only the first reading returns the conversion result, all the following reading are zeros. I read the ADC081C021 data sheet. It indicates after a read, it would start the conversion again. Thus I assume I can continue to read it. 

But if I close the file and open again for every reading, it would returns a none-zero result. Is that suppose to be the way to read the ADC in normal mode(single shot mode)

my linux env uses TI AM3357 and kernel 4.14.96 of linux (Linaro), with ADC081C021 for battery monitor. 

Here is the code that I try to read the ADC conversion results. 

char adcName[] = "/sys/bus/iio/devices/iio\:device0/in_voltage_raw";
output_fd = open(adcName, O_RDWR);
if (output_fd < 0) {
    LOG( LL_INFO, "failed to open ADC \n");
   pthread_exit(NULL);
}
for (int i = 0; i < 10; i++) 
{

/* read ADC */

LOG(LL_INFO, "WRITE ADDRESS POINTER REG \n");
addrPointerReg = CONVERSION_RESULT; // CONVERSION_RESULT is zero
write(output_fd, &addrPointerReg, sizeof(Address_Pointer_Reg));

int ret = read(output_fd, &conversionResultReg, sizeof(Conversion_Result_Register));
LOG(LL_INFO, "ADC output converResult = %d ret = %d \n",
                                                       conversionResultReg.conversionResult, ret);


conversionResultReg = {0}

}

close(output_fd);

Thanks

-Tom

  • Hello,

    Would you please provide a scope shot of the digital lines? This help with confirming that the code is expected to do is in fact what it is doing.

    Also, to make sure the reading commands are correct, I would suggest confirming with the below paragraph from the datasheet.

    Regards, Cynthia

  • Cynthia, 

    Thanks for the reply.

    I followed the Figure 30. (b) Typical Pointer Set Followed by Immediate Read of a 2-Byte ADC Register in data sheet which indicates the steps

    1. Frame 1 sends Address Byte from Master

    2. Frame 2 sends Pointer Byte from Master

    3. Frame 3 sends Address Byte from Master

    4. Frame 4 and 5 are Data Byte read from ADC.

    Based on what I interpreted that sequences I code as follow but the first write already fail. 

    char adcName[] = "/sys/bus/iio/devices/iio:device0/in_voltage_raw";
    fileDescriptor = open(adcName, O_RDWR);
     if (fileDescriptor < 0) {
              LOG( LL_INFO, "failed to open ADC \n");
              pthread_exit(NULL);
     }

    memset(buf, 0, bufSize);
    buf[0] = ADC_ADDRESS; // Address byte by from master
    ret = write(fileDescriptor, buf, 1);
    if(ret <= 0)
    {
    LOG( LL_INFO, "-- 1 Fail to write to DAC ret = %d \n", ret);
    }


    memset(buf, 0, bufSize);
    addrPointerReg = CONVERSION_RESULT;
    buf[0] = addrPointerReg; // pointer byte from master
    write(fileDescriptor, buf, 1);

    memset(buf, 0, bufSize);
    buf[0] = ADC_ADDRESS; // Address byte from master
    write(fileDescriptor, buf, 1);

    memset(buf, 0, bufSize);
    ret = read(fileDescriptor, buf, 2); // read ADC 2 bytes

    Can you confirm the above sequence that write and read to device matched with the data sheet?

    I will ask the HW help to capture the digital lines later. They are all stay at home now.

    Thanks

    -Tom



  • I turned out I can use cat /sys/bus/iio/devices/iio:device0/in_voltage_raw to read the data without those sequence as my needs is just single shot mode. 

    I just direct the out of cat in C code to a file and read it back. 

    Thanks for the help.

    -Tom