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.

AFE4300: Source code is needed

Part Number: AFE4300

Hi,

I have designed PCB and attached to an Arduino using C. I could not find a complete source code to help me. I am reading 0 after setup AFE4300 using this code. Please check and advice.

Thank you

void AFE4300_writeRegister(uint8_t regAddress, uint16_t data)
{
uint8_t firstByte = (uint8_t)(data >> 8);
uint8_t secondByte = (uint8_t)data & 0xFF;
regAddress=regAddress & 0x1F; //Last 5 bits specify address
SPI.transfer(regAddress);
delayMicroseconds(10);
SPI.transfer(firstByte);
delayMicroseconds(10);
SPI.transfer(secondByte);
delayMicroseconds(10);
}

int16_t AFE4300_readRegister(uint8_t regAddress)
{
int16_t spiReceive = 0;
uint8_t spiDataBuf[2] = {0,0};

SPI.transfer(0x20 | regAddress);
SPI.transfer(regAddress);
//2 = two bytes to read
delayMicroseconds(50);
spiDataBuf[0]=SPI.transfer(0x0);
delayMicroseconds(50);
spiDataBuf[1]=SPI.transfer(0x0);

//Combine the two received bytes into a signed int
spiReceive = (spiDataBuf[0] << 8);
spiReceive |= spiDataBuf[1];

//Note that every time read, it must be rewritten except ADC dataout register
if(regAddress != ADC_DATA_RESULT) {
AFE4300_writeRegister(regAddress, spiReceive);
}

return spiReceive;
}
void AFE4300V2::init() //const
{
writeRegister(ADC_CONTROL_REGISTER, 0x5140);//d 0x4950);
delayMicroseconds(800);
writeRegister(MISC1_REGISTER, 0x0000);
delayMicroseconds(800);
writeRegister(MISC2_REGISTER, 0xFFFF);
delayMicroseconds(800);
writeRegister(DEVICE_CONTROL_1, 0x0004); //?? 0x96 ~ 0110 0000
delayMicroseconds(800);
writeRegister(ISW_MATRIX, 0x0000);
delayMicroseconds(800);
writeRegister(VSW_MATRIX, 0x0000);
delayMicroseconds(800);
writeRegister(IQ_MODE_ENABLE, 0x0000);
delayMicroseconds(800);
writeRegister(WEIGHT_SCALE_CONTROL, 0x0000);
delayMicroseconds(800);
writeRegister(BCM_DAC_FREQ, 0x0040);// 0x00FA);
delayMicroseconds(800);
writeRegister(DEVICE_CONTROL_2, 0x0000);
delayMicroseconds(800);
writeRegister(ADC_CONTROL_REGISTER_2, 0x0011);
delayMicroseconds(800);
writeRegister(MISC3_REGISTER, 0x00C0);
delayMicroseconds(800);
}


void AFE4300V2::initWeightScale() const
{
writeRegister(ADC_CONTROL_REGISTER, 0x4120);// 0x4150); // ?? Differential measurement mode, 32 SPS
delayMicroseconds(100);
writeRegister(DEVICE_CONTROL_1, 0x0005);// 0x4001); //Power up weigh scale signal chain
delayMicroseconds(100);
writeRegister(ADC_CONTROL_REGISTER_2, 0x0000); //ADC selects output of weigh scale
delayMicroseconds(100);
writeRegister(WEIGHT_SCALE_CONTROL, 0x003F); //Gain = 1 DAC Offset = -1
delayMicroseconds(100);
writeRegister(BCM_DAC_FREQ, 0x0040); //?? Frequency = default
delayMicroseconds(100);
//writeRegister(DEVICE_CONTROL_2, 0x1000); //Power up weigh scale signal chain
// delayMicroseconds(100);
writeRegister(IQ_MODE_ENABLE, 0x0000); //Disable IQ mode
delayMicroseconds(100);
writeRegister(ISW_MATRIX, 0x0000); //Channels IOUTP1 and IOUTN0
delayMicroseconds(100);
writeRegister(VSW_MATRIX, 0x0000); //Channels VSENSEP1 and VSENSEN0
delayMicroseconds(100);
}


/**
* @brief Initializes the BCM Module
*/

void AFE4300V2::initBCM()
{
writeRegister(ADC_CONTROL_REGISTER,0x4120); //Differential measurement mode, 32 SPS
delayMicroseconds(100);
writeRegister(DEVICE_CONTROL_1,0x0006); //Power up BCM signal chain
delayMicroseconds(100);
writeRegister(ISW_MATRIX,0x0804); //Channels IOUTP1 and IOUTN0
delayMicroseconds(100);
writeRegister(VSW_MATRIX,0x0804); //Channels VSENSEP1 and VSENSEN0
delayMicroseconds(100);
writeRegister(ADC_CONTROL_REGISTER_2,0x0063); //ADC selects output of BCM-I output
delayMicroseconds(100);
writeRegister(WEIGHT_SCALE_CONTROL,0x0000); //Gain = 1 DAC Offset = 0
delayMicroseconds(100);
writeRegister(BCM_DAC_FREQ,0x0032);
delayMicroseconds(100);
writeRegister(MISC3_REGISTER,0x0030);
delayMicroseconds(100);

}
void setup()
{
Bio.resetAFE4300();//Pull RESET pin low for 50 Usec and pull high
Bio.init();
Bio.initWeightScale();
////START BCM
Bio.initBCM();
PWMsetup();//1 Mhz CLOCK
}
void loop()
{
reg_val=readRegister(ADC_DATA_RESULT);
Serial.println(reg_val, HEX);
delay(100);
}

  • Hi Faezeh,

    In you readRegister routine you have "SPI.transfer(regAddress);" and this is not needed. Can you please try after removing this.
    Also I would suggest to read the known register first to make sure that read routine is working fine ( Please remember to write back the read value).
    Regarding the register configuration, you can take help of AFE4300EVM's GUI to get the register settings for the required configuration.

    Regards,
    Prabin.
  • Hi Probin,
    Thanks for your advice. My Write & Read routines are working. I got 0x01C3 (451) when reading Register 0x01 and 0x00 in Register 0x09. I followed Help file and saved Registers then tested but always get 0x00 when reading ADC.

    void AFE4300_writeRegister(uint8_t regAddress, uint16_t data)
    {
    uint8_t firstByte = (uint8_t)(data >> 8);
    uint8_t secondByte = (uint8_t)data & 0xFF;
    digitalWrite(PIN_CS, LOW);
    delayMicroseconds(1);
    SPI.transfer(regAddress);
    delayMicroseconds(10);
    SPI.transfer(firstByte);
    delayMicroseconds(10);
    SPI.transfer(secondByte);
    delayMicroseconds(10);
    digitalWrite(PIN_CS, HIGH);
    delayMicroseconds(1);
    }

    uint16_t AFE4300_readRegister(uint8_t regAddress)
    {
    uint16_t spiReceive = 0;
    uint8_t spiDataBuf[2] = {0,0};
    digitalWrite(PIN_CS, HIGH);// SPI CS High
    delayMicroseconds(1);
    digitalWrite(PIN_CS, LOW);
    delayMicroseconds(1);
    SPI.transfer(0x20 | regAddress);
    //2 = two bytes to read
    spiDataBuf[0]= SPI.transfer(0x00);
    delayMicroseconds(10);
    spiDataBuf[1]= SPI.transfer(0x00);
    delayMicroseconds(10);

    //Combine the two received bytes into a signed int
    spiReceive = (spiDataBuf[0] << 8);
    spiReceive |= spiDataBuf[1];
    digitalWrite(PIN_CS, HIGH);
    delayMicroseconds(1);
    AFE4300_writeRegister(regAddress, spiReceive);
    return spiReceive;
    }
    in the main program....
    AFE4300_init();
    AFE4300_reset();
    AFE4300_initDRDYInterrupt();
    AFE4300_enableInterrupt();
    delay(100);
    //Register test
    AFE_Data=AFE4300_readRegister(0x01);//ADC_CONTROL_REGISTER1;
    delayMicroseconds(10);
    Serial.print("ADC_CONTROL 1 ");
    Serial.println(AFE_Data);// Register 0x01 returned 0x01C3 (451)
    AFE_Data=AFE4300_readRegister(0x09); //DEVICE_CONTROL1
    delayMicroseconds(10);
    Serial.print("Device Control 1 ");
    Serial.println(AFE_Data);//// Register 0x09 returned 0x0000 (0)
    delay(1000);

    //FROM AFE4300 Device GUI Program Registers
    AFE4300_writeRegister(0x00,0x0000);
    AFE4300_writeRegister(0x01,0x4140);
    AFE4300_writeRegister(0x02,0x0000);
    AFE4300_writeRegister(0x03,0xFFFF);
    AFE4300_writeRegister(0x09,0x6006);
    AFE4300_writeRegister(0x0A,0x0004);
    AFE4300_writeRegister(0x0B,0x0800);
    AFE4300_writeRegister(0x0C,0x0000);
    AFE4300_writeRegister(0x0D,0x0000);
    AFE4300_writeRegister(0x0E,0x0040);
    AFE4300_writeRegister(0x0F,0x0000);
    AFE4300_writeRegister(0x10,0x0063);
    AFE4300_writeRegister(0x1A,0x0030);
    for (i=0; i<100; i++)
    {
    AFE_Data = AFE4300_readRegister(0x00);
    Serial.println(AFE_Data);//// Always Register 0x00 returned 0x0000 (0)
    delay(20);
    }
  • Hi Faezeh,

    Can you please probe the RDY pin and confirm that there is a pulse train of frequency same as data rate set by you.
    If you don't see the pulse train, then please check the clock signal given to the AFE.

    Regards,
    Prabin
  • Dear Probin,
    RDY pin is okay and Ref voltage is 1.7. I played with Registers and found setting is very important. I have 100 ohm between RP0 (P29) and RN0 (P31 and 1K between RP1(P28) and RN1 (P30). I need to read Weighing scale on INP1,INM1 and Body Impedance by two pairs of electrodes.
    Could you please help for correct registers setting.
    AFE4300 Device GUI is confusing me.
  • Hi Faezeh,


    CAn you please try the following register setting for Weight scale with the inputs given to INP1 and INM1

    AFE4300_writeRegister(0x01,0x4120);
    AFE4300_writeRegister(0x02,0x0000);
    AFE4300_writeRegister(0x03,0xFFFF);
    AFE4300_writeRegister(0x09,0x6005);
    AFE4300_writeRegister(0x0A,0x0000);
    AFE4300_writeRegister(0x0B,0x0000);
    AFE4300_writeRegister(0x0C,0x0000);
    AFE4300_writeRegister(0x0D,0x0000);
    AFE4300_writeRegister(0x0E,0x0000);
    AFE4300_writeRegister(0x0F,0x0000);
    AFE4300_writeRegister(0x10,0x0000);
    AFE4300_writeRegister(0x1A,0x0030);

    Regards,
    Prabin
  • Hi Probin,

    I tested your Register setting and I got 0 in the load cell input force. LVDO is 1.7 V and in Register 0x10, ADCREF connected to VLDO but I am wondering why VREF is zero!!!?

    I reduced SPI to 500khz, 800 microSec after Write Regiters but no hope. 

    Please give me separate piece of code to configure continues reading only Weighing Scale (INP1 and INM1) and one for BCM measurement.

    How to find if AFE4300 is damaged?

     Thank you

  • Hi Faezeh,

    When weight scale signal chain is enabled, voltage at VREF will be 0 whereas it will be 1.7V at VLDO.
    Also, do you get all the samples of the ADC output as absolute 0 or it is few ADC codes?
    If it is few ADC code then there is some problem with the input being applied.
    However if it is absolute 0 then something is wrong with the AFE's configuration of AFE is damaged.

    Regards,
    Prabin.
  • Hi Prabin,

    Problem was due to oscillator. I provided 1024 Hz clock by MCU and I have data but inconstant output. Few questions:

    1) Table 1 shows ADC data is twos complement binary. Do I have to read register 0x00 unsigned 16 bit and then convert to signed integer or directly read signed 16 bit ?

    2) Figure 11. shows in Single-Shot Mode, DRY Falling during read process and in continuous mode is always High and falling after read process so better to check in Single shot DRY=LOW and in Continuous DRY=High to insure correct data otherwise ignore it.

    3) IOUTx pins should connect to VSENSEx pin directly of by 1UF capacitor? Like:

    VSENSEM_R0 ------/\/\/\/\------VSENSEP_R0 (VSW_Matrix=0x0101)
                                 |              |
                              RN0        RP0 (ISW_Matrix=0x0101)

    My inconstant readings:

    RESET_AFE();
    delay(100);
    spiWrite(MISC1_REGISTER, 0x0000);
    spiWrite(MISC2_REGISTER, 0xFFFF);
    spiWrite(DEVICE_CONTROL_1, 0x0006);
    spiWrite(ISW_MATRIX, 0x0101);
    spiWrite(VSW_MATRIX, 0x0101);
    spiWrite(IQ_MODE_ENABLE, 0x0000);//Disable IQ mode
    spiWrite(WEIGHT_SCALE_CONTROL, 0x0000);
    spiWrite(BCM_DAC_FREQ, 0x0032); //0x0040
    spiWrite(DEVICE_CONTROL_2, 0x0000);
    spiWrite(ADC_CONTROL_REGISTER_2, 0x0063); //ADC selects output of BCM-I output
    spiWrite(MISC3_REGISTER, 0x0030);
    spiWrite(BCM_DAC_FREQ, 50);//set_frequency from 1 to 255 khz in BCM
    uint16_t Result;
    delay(300);//wait 300 msec
    while(1)
    {
    spiWrite(ADC_CONTROL_REGISTER,0xC1C0);//128 SPS (default) Single SHot
    while(readADCFlag == 0x00);//wait untile Interrupt occoured by Falling DRDY pin
    unint16_t Result = spiRead(0x20 | 0x00);
    int16_t ADC_Data=0;
    spiWrite(ADC_CONTROL_REGISTER,0x41C0);//128 SPS (default) Single SHot ADC COV MODE=0 OFF
    if (Result >=32768)
    ADC_Data = Result - 65536;
    Serial.println(ADC_Data);
    delay(100);//wait 100 msec
    }
    output:
    -512

    0

    -512

    0

    -256

    -256

    -256

    0

    Thank you

  • Hi Faezeh,

    ADC gives the signed output in two's complementary binary format. You have to convert the ADC output into positive and negative decimal numbers yourself based on the information presented in Table 1.
    RDYZ pin is used to indicate the end of ADC conversion and the availability of the data. In continuous conversion mode you can read the data after the falling edge of RDYZ, whereas in single shot mode you can read after the rising edge of RDYZ.
    You can connect the sense pins without any capacitors.

    Regards,
    Prabin