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.

ADS131B04-Q1: Compatibility between ADS131M04 and ADS131B04-Q1

Part Number: ADS131B04-Q1
Other Parts Discussed in Thread: ADS131M04, , ADC-ENERGY-METROLOGY-LIB-SW

A signal mixed with "extremely small" frequencies is sampled by ADS131M04, passed through a digital filter (IIR), and demodulated. This was the intended result.
If you replace it with ADS131B04-Q1, you will get different results even though the same circuit and the same register settings are used.
First, it does not become a sine wave and is disturbed.
Then, after a few seconds, the amplitude is almost gone.
Is the global chop function different?
Is it incompatible?

  • Hello Iwakiri-san,

    Thank you for your post.

    Can you please provide more details about the input signal, source, signal chain and registers settings?

    The register maps are very close, but we should check all the settings to be sure.

    Regards,

    Ryan

  • Tank you, Ryan-san.

    MCU is MSP432P4111.

    Source code is based on ADC-ENERGY-METROLOGY-LIB-SW.

    Register setting header file is from sbac278.ADS131B04-Q1 Example C Code.

    Constants that cannot be compiled are commented out.

    There is no other difference.

    bool adcStartup(void)
    {
    /* (OPTIONAL) Provide additional delay time for power supply settling */
    #ifndef __ICCARM__ // CCS Project
    usleep(DELAY_5US);
    #else // IAR Project
    SysCtlDelay(DELAY_5US);
    #endif
    
    // Configure Inputs
    // Port P2
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(ADS_DRDY0_PORT, ADS_DRDY0_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
    MAP_GPIO_setAsInputPin(ADS_DRDY0_PORT, ADS_DRDY0_PIN);
    
    // Configure Outputs
    // Port P2
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(ADS_RESET_SYNC_PORT, ADS_RESET_SYNC_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
    MAP_GPIO_setDriveStrengthLow(ADS_RESET_SYNC_PORT, ADS_RESET_SYNC_PIN);
    MAP_GPIO_setAsOutputPin(ADS_RESET_SYNC_PORT, ADS_RESET_SYNC_PIN);
    MAP_GPIO_setOutputHighOnPin(ADS_RESET_SYNC_PORT, ADS_RESET_SYNC_PIN);
    #ifdef nCS_PIN_ENABLED
    MAP_GPIO_setDriveStrengthLow(ADS_CS0_PORT, ADS_CS0_PIN);
    MAP_GPIO_setAsOutputPin(ADS_CS0_PORT, ADS_CS0_PIN);
    #ifdef SINGLE_SPI_MULTIPLE_ADC
    MAP_GPIO_setDriveStrengthLow(ADS_CS1_PORT, ADS_CS1_PIN);
    MAP_GPIO_setAsOutputPin(ADS_CS1_PORT, ADS_CS1_PIN);
    MAP_GPIO_setDriveStrengthLow(ADS_CS2_PORT, ADS_CS2_PIN);
    MAP_GPIO_setAsOutputPin(ADS_CS2_PORT, ADS_CS2_PIN);
    #endif
    #endif
    
    // IIRフィルタ初期化
    init_arm_iir();
    memset(&Z, 0, sizeof(Z));
    memset(&F, 0, sizeof(F));
    memset(&H, 0, sizeof(H));
    Freq = 0;
    
    /* (OPTIONAL) Toggle nRESET pin to ensure default register settings. */
    /* NOTE: This also ensures that the device registers are unlocked. */
    toggleRESET();
    
    /* (REQUIRED) Initialize internal 'registerMap' array with device default settings */
    restoreRegisterDefaults();
    
    for (size_t adc_index = 0; adc_index < NUM_ADS131M0X; adc_index++)
    {
    /* (OPTIONAL) Validate first response word when beginning SPI communication: (0xFF20 | CHANCNT) */
    uint16_t response = sendCommand(OPCODE_NULL, adc_index);
    
    /* Disable ADC channels to send short frames for configuring ADC */
    if (!writeSingleRegister(CLOCK_ADDRESS, (CLOCK_DEFAULT & ~(CLOCK_CLK_SEL_MASK | CLOCK_CH3_EN_MASK | CLOCK_CH2_EN_MASK | CLOCK_CH1_EN_MASK | CLOCK_CH0_EN_MASK | CLOCK_OSR_MASK)) | CLOCK_OSR_PWR, true, adc_index)) return false;
    #ifdef CRC_CCITT
    if (!writeSingleRegister(MODE_ADDRESS, MODE_CRC_TYPE_16BIT_CCITT | MODE_WLENGTH_24BIT /*| MODE_DRDY_SEL_MOST_LAGGING*/ | MODE_DRDY_HiZ_LOGIC_HIGH /*| MODE_DRDY_FMT_LOGIC_LOW*/, true, adc_index)) return false;
    #else
    if (!writeSingleRegister(MODE_ADDRESS, MODE_CRC_TYPE_16BIT_ANSI | MODE_WLENGTH_24BIT | MODE_DRDY_SEL_MOST_LAGGING | MODE_DRDY_HiZ_LOGIC_HIGH | MODE_DRDY_FMT_LOGIC_LOW, true, adc_index)) return false;
    #endif
    
    if (!writeSingleRegister(GAIN_ADDRESS, (GAIN_ADC_CHANNEL3) << (ADC_CHANNEL3 << 2) | (GAIN_ADC_CHANNEL2) << (ADC_CHANNEL2 << 2) | (GAIN_ADC_CHANNEL1) << (ADC_CHANNEL1 << 2) | (GAIN_ADC_CHANNEL0) << (ADC_CHANNEL0 << 2), true, adc_index)) return false;
    
    if (!writeSingleRegister(CH0_CFG_ADDRESS + ADC_CHANNEL3 * (CH1_CFG_ADDRESS - CH0_CFG_ADDRESS), CH0_CFG_MUX0_AIN0P_AIN0N /*| SET_PHASE_REGISTER_VALUE(PHASE_ADC_CHANNEL3)*/, true, adc_index)) return false;
    if (!writeSingleRegister(CH0_CFG_ADDRESS + ADC_CHANNEL2 * (CH1_CFG_ADDRESS - CH0_CFG_ADDRESS), CH0_CFG_MUX0_AIN0P_AIN0N /*| SET_PHASE_REGISTER_VALUE(PHASE_ADC_CHANNEL2)*/, true, adc_index)) return false;
    if (!writeSingleRegister(CH0_CFG_ADDRESS + ADC_CHANNEL1 * (CH1_CFG_ADDRESS - CH0_CFG_ADDRESS), CH0_CFG_MUX0_AIN0P_AIN0N /*| SET_PHASE_REGISTER_VALUE(PHASE_ADC_CHANNEL1)*/, true, adc_index)) return false;
    if (!writeSingleRegister(CH0_CFG_ADDRESS + ADC_CHANNEL0 * (CH1_CFG_ADDRESS - CH0_CFG_ADDRESS), CH0_CFG_MUX0_AIN0P_AIN0N /*| SET_PHASE_REGISTER_VALUE(PHASE_ADC_CHANNEL0)*/, true, adc_index)) return false;
    
    #ifdef CURRENT_DETECTION_ENABLED
    if (!writeSingleRegister(CH0_OCAL_MSB_ADDRESS + ADC_CHANNEL0 * (CH1_OCAL_MSB_ADDRESS - CH0_OCAL_MSB_ADDRESS), (20640 & 0xFFFFFF00) >> 8, true, adc_index)) return false;
    if (!writeSingleRegister(CH0_OCAL_LSB_ADDRESS + ADC_CHANNEL0 * (CH1_OCAL_LSB_ADDRESS - CH0_OCAL_LSB_ADDRESS), (20640 & 0x000000FF) << 8, true, adc_index)) return false;
    if (!writeSingleRegister(CH0_OCAL_MSB_ADDRESS + ADC_CHANNEL1 * (CH1_OCAL_MSB_ADDRESS - CH0_OCAL_MSB_ADDRESS), (4109 & 0xFFFFFF00) >> 8, true, adc_index)) return false;
    if (!writeSingleRegister(CH0_OCAL_LSB_ADDRESS + ADC_CHANNEL1 * (CH1_OCAL_LSB_ADDRESS - CH0_OCAL_LSB_ADDRESS), (4109 & 0x000000FF) << 8, true, adc_index)) return false;
    #endif
    
    #if (SAMPLE_RATE == 2000)
    #elif (SAMPLE_RATE == 2930) || (SAMPLE_RATE == 4000) || (SAMPLE_RATE == 3906)
    if (!writeSingleRegister(CLOCK_ADDRESS, CLOCK_CH3_EN_ENABLED | CLOCK_CH2_EN_ENABLED | CLOCK_CH1_EN_ENABLED | CLOCK_CH0_EN_ENABLED | CLOCK_OSR_PWR, true, adc_index)) return false;
    #else // SAMPLE_RATES = 5859, 6000, 6400, 7812 or 8000
    if (!writeSingleRegister(CLOCK_ADDRESS, CLOCK_CLK_SEL_EXTERNAL | CLOCK_CH3_EN_ENABLED | CLOCK_CH2_EN_ENABLED | CLOCK_CH1_EN_ENABLED | CLOCK_CH0_EN_ENABLED | CLOCK_OSR_PWR, true, adc_index)) return false;
    #endif
    
    #ifdef CURRENT_DETECTION_ENABLED
    if (!writeSingleRegister(THRSHLD_MSB_ADDRESS, (CURRENT_DETECTION_THRESHOLD_VALUE & 0x00FFFF00) >> 8, true, adc_index)) return false;
    // Not all devices have DC filter
    if (!writeSingleRegister(THRSHLD_LSB_ADDRESS, (CURRENT_DETECTION_THRESHOLD_VALUE & 0x000000FF) << 8 | DC_BLOCK_COEFFICIENT, true, adc_index)) return false;
    #endif
    
    if (!writeSingleRegister(CFG_ADDRESS, CFG_GC_EN /*| CFG_CD_ALLCH_ANY_CHANNEL | CFG_CD_NUM_1 | CFG_CD_LEN_128 | CFG_CD_EN_DISABLED*/, true, adc_index)) return false;
    }
    
    return true;
    
    }

  • Hi Iwakiri-san,

    I understand that you began with our Energy Metrology software library and also imported our ADS131B04-Q1 example code header file. Some of the register names and macro definitions may be different. Please double-check that the register names, addresses, and macro definitions match correctly.

    Regards,

    Ryan