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.

ADS1256: INCONSISTENT DATA

Part Number: ADS1256

HELLO EVERYONE,

I'm trying to do my first data acquisition project where I use the STM32 Nucleo-L476GR with the ADC Converter ADS1256.

When reading the data, I am unable to correctly read the voltage values ​​in Single Ended mode on Channel A0. Firstly, I am trying to acquire data only on one channel to later extend it to other channels. The STM32 Nucleo-L476RG module only accepts a maximum of 16 bits of data size for SPI Communication. I've already tried varying between 8 and 16 bits, but without getting results.

I send the code attached to this.

Thank you if anyone can help.

ADS1256 STM code: /cfs-file/__key/communityserver-discussions-components-files/73/STM_2B00_ADS1256-code.txt

  • Hi Claudio Tasso,

    Can you please explain your problem in more detail: are you getting data out of the ADC, but it is wrong? Are you not getting any data, but you can communicate with the ADC? Is the communication not working, but you see signals from the ADC? Is the ADC doing nothing? It is not clear from your post what actual problem you are experiencing

    Typically, the best way to diagnose code issues with an ADC is to use a logic analyzer. This will tell you what you are sending to the ADC, as well as what the ADC is sending to the controller, and if the timing requirements are being met. You can then compare these results to your code to make sure that the ADC and controller are actually doing what you want them to do.

    Please send logic analyzer data so we can see what is going on

    -Bryan

  • Hi Bryan,

    Firstly thanks for the help.

    Yes, I can communicate between the STM32 and the ADS1256. I can see the commands sent in the logic analyzer.

    I am also receiving data after sending the RDATA command, but this data is not correct. I don't know if I don't know how to receive the data using a uint8_t rawData[3] vector and then convert it to 24 bits. I don't know if the ADC1256 is sending the wrong data or if there is some command that I am sending incorrectly.

    Am I sending the correct sequence of commands to initialize the device?

    Am I sending the correct sequence of commands to read data from the device?

    I send some screenshots of the logic analyzer.


    Thanks,

    The values below are with nothing connected to pins A0 - GND, where it should be something close to 0.

  • Hi Claudio Tasso,

    Thanks for sending the LA plots

    First you will need to set your logic analyzer to capture data on DOUT on the falling edge. As noted in the datasheet, data is shifted onto DOUT on the rising edge, so you should capture on the falling edge. This is easy to change with the Saleae LA. Please resend the LA plots with the correct capture edge

    Second, please also note that the ADS1256 has a binary two's complement coding scheme. This is shown in Table 16. So the data you are showing in the last image appears to be very small, negative numbers. This is possible with no input as this indicates a small, negative offset. Also, when you perform these measurements, you should not leave your inputs floating. Instead, connect them together so this acts as a true short i.e. both inputs are at the same potential.

    Can you also send a schematic of your board?

    -Bryan

  • Bryan,

    I followed the instructions as per your guidance. I closed the short between A0 and GND and configured DOUT (MISO) as falling edge.

    You can see the first command RESET (0xFE)

    After I sent:

    SDATAC: 0x0F

    ADCON

                  WREG: 0x50 | ADCON: 0x02 = 0x52

                  PGA1 - 0x00

    DRATE

                  WREG: 0x50 | REG_DRATE: 0x03 = 0x53

                  DRATE_1000SPS: 0xE0

    SELFCAL: 0xF0

    ### Inside Infinite Loop While ###

    MUX

                  WREG: 0x50 | REG_MUX: 0x01 = 0x51

                  DRATE_1000SPS: 0x08

    SYNC: 0xFC

    WAKEUP: 0x00

    RDATA: 0x01

    THEN..... RECEIVE DATA

    FIRST BYTE

    SECOND BYTE

    THIRD BYTE

    To handle 2's complement, I created the code below:

    COMMENT: STM32 DATA SIZE IS SET TO 8 BITS

    //RDATA

    dataToSend[0] = ADS125X_RDATA; //0x01

    dataToSend[1] = 0x00;

    //HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_RESET); //low

    HAL_SPI_Transmit(&hspi1, dataToSend, 1, HAL_MAX_DELAY);

    HAL_Delay(0.00683);

    //Read ADC Data

    HAL_SPI_Receive(&hspi1, &rawData[0], 1, 0.1);

    HAL_SPI_Receive(&hspi1, &rawData[1], 1, 0.1);

    HAL_SPI_Receive(&hspi1, &rawData[2], 1, 0.1);

    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_SET); //high

    raw[0] = rawData[0];

    raw[1] = rawData[1];

    raw[2] = rawData[2];

    uint32_t valorADC = (rawData[0] << 16) | rawData[1] << 8 | rawData[2]; // MSB

    if (valorADC & 0x800000)

    {

    valorADC &= 0x7FFFFF;

    }

    /*

    must be signed integer for 2's complement to work ### SECOND OPTION) ###

    int32_t adsCode = (spiRx[0] << 16) | (spiRx[1] << 8) | (spiRx[2]);

    if(adsCode & 0x800000) adsCode |= 0xff000000; // fix 2's complement

    // do all calculations in float. don't change the order of factors --> (adsCode/0x7fffff) will always return 0

    return ( (float)adsCode * (2.0f * ads->vref) ) / ( ads->pga * 8388607.0f ); // 0x7fffff = 8388607.0f

    */

    voltagemBinario = valorADC;

    voltagem = (valorADC) * ((2 * 5.0) /(16777216));

    ##############################################################################

    The model of the board:

    Thank you again and sorry for any mistake!

  • Hi Claudio Tasso,

    Your LA is still triggering on the rising edge, see the first image below from your latest post. See how the arrow is pointing up on the rising edge of SCLK?

    You need to change this in the SPI settings window that I show in the second image. Note that the Saleae refers to this as the "trailing edge". Your microcontroller also needs to follow this same protocol

    Please make sure these issues are corrected or you will not be able to read correct data on either the Saleae or your MCU

    -Bryan

  • Hi Bryan,

       First of all, I'm sorry for the delay in responding, as I was looking for information based on your instructions and discovered several mistakes I was making.

       First, the STM32's SPI communication clock was very high... 40 mHz and in a search I found that it has to be below 1.92 Mhz.

       The STM clock operating mode was also incorrect, where Edge 2 was configured as explained below:

       => 1 Edge means the first clock transition is the first data capture edge (value 0) AND 2 Edge means the second clock transition is the first data capture edge (value 1)

       Another mistake in the acquisition by Logic Analyzer. CPOL = 0 / CPHA = 1 and Falling Edge mode were configured.

       There were a lot of mistakes I was making....

       The received data is still not coherent... Closed short between A0 - GND and I still can't read anything around "0". 

       it could be something related to the reception/sending of data by the ADS1256 or also in the conversion/processing of data from the 2's complement format.

        Below on the last image, I send a sample of the data in Binary.

        I would appreciate it if you could give more information/ tips on what could be wrong.

       The information you provided me ended up giving me the correct direction on where to proceed. Learning things alone is very difficult, but I believe I can do it!

    Thank you again!

    Claudio

    STM32 - Nucelo-L476RG: SPI clock configuration.

    SPI Parameters on Nucleo-L476RG

    Configuration on Logic Analyzer Saleae:

    Command Sequency as per main.c Code:

    RESET: 0xFE

    SDATAC: 0x0F

    ADCON: 0x52 / 0x00

    DRATE: 0x52 / 0xA1

    SELFCAL: 0xF0

    MUX: 0x51 / 0x08

    SYN: 0xFC

    WAKEUP: 0x00

    x

    RDATA: 0x01

    FIRST 03 BYTES RECEIVED

    Bynary Sample

    main.c Code: /cfs-file/__key/communityserver-discussions-components-files/73/Main-code.txt

  • Hi Claudio Tasso,

    I strongly encourage you to read the ADC datasheet. Both of the issues below are covered in this document, along with many others you have already faced. It is imperative that you understand how the device behaves before you actually use it, otherwise you will continue to have issues and our support will be limited. I will try to help you with at least a few issues I noticed from your last post

    You are missing at least one byte with your WREG. You said that your WREG to DRATE is 0x52 / 0xA1. The first byte indicates that you are performing a WREG command starting at register 2. The second byte is to tell the ADC how many registers you are writing. Since you wrote A1, this is a nonsense input according to Table 24, so nothing happens. Then, you never send the actual data you want written to the ADC, and instead you end the frame by pulling CS high.

    If you look at your data read back, you can see that the 24 bits of data you are clocking out takes a very long time compared to the DRDY signal. In fact, there are 7 DRDY pulses from the beginning of the first byte to the end of the third byte, see the image below. All of these DRDY pulses are indicating that new data is ready to be clocked out, so your three data bytes are from different data captures. You will need to sample much slower or capture data much faster i.e. within 1 DRDY period.

    Also, can you please stop posting your code in your replies? It is making the thread very long and difficult to follow. As mentioned previously, the best way to debug ADC code is to use the logic analyzer. FYI I condensed your code into text files and attached them to your posts

    -Bryan

  • Bryan,

    Thank you very much for all the information provided. Many of them opened my mind to improve my knowledge. I apologize for any inconvenience caused and I will study the ADS 1256 datasheet further.

  • Hi Claudio Tasso,

    Understood, glad we could help

    -Bryan