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.

AFE4404: Using the AFE4404 with an Arduino MEGA

Part Number: AFE4404

I tried to set up the AFE4404 with the source code I got from TI for their AFE4404EVM software. Since I am not using the same setup the evaluation modul does, I am now experiencing some issues and would like to ask if someone could help me.

I am using an Arduino MEGA to control the AFE4404 in combination with Osrams SFH 7060. I do not have much time left for my diploma thesis which led me to only use one of the SFH 7060´s LED´s. At first I tried to simply turn the LED on via I2C but did not get it to work. The program stops at the first try to send something through the I2C lines.

I then tried to simply see if the AFE is responding to an I2C device with a prebuild program which only identifys connected I2C devices. This program worked with other devices I got but doesn´t if I connect my board with the AFE on it. It seems like it blocks every traffic giong through the I2C lines.

I got the program from Nick Gammon at: http://www.gammon.com.au/i2c

When setting up my program, I left out a lot from the original source code due to my very limited usage of the AFE capabilities. Can you tell me if I missed something essential regardless of how many of the AFE functions I´m using?

I attached my personal source code and the circuit diagram of my board so you can get an idea of what I´m doing.

I would really appreciate some help.

Regards,

Simon

#include <Wire.h>

/* Pinbelegung */

int RESETZ = 4;

/* Variablendeklaration */

float befehl = 0;
int AFE_ADDR = 88;


/* AFE440X registers */

#define AFE_CONTROL0                0x00
#define AFE_LED2STC                 0x01
#define AFE_LED2ENDC                0x02
#define AFE_LED1LEDSTC              0x03
#define AFE_LED1LEDENDC             0x04
#define AFE_ALED2STC                0x05
#define AFE_ALED2ENDC               0x06
#define AFE_LED1STC                 0x07
#define AFE_LED1ENDC                0x08
#define AFE_LED2LEDSTC              0x09
#define AFE_LED2LEDENDC             0x0a
#define AFE_ALED1STC                0x0b
#define AFE_ALED1ENDC               0x0c
#define AFE_LED2CONVST              0x0d
#define AFE_LED2CONVEND             0x0e
#define AFE_ALED2CONVST             0x0f
#define AFE_ALED2CONVEND            0x10
#define AFE_LED1CONVST              0x11
#define AFE_LED1CONVEND             0x12
#define AFE_ALED1CONVST             0x13
#define AFE_ALED1CONVEND            0x14
#define AFE_ADCRSTSTCT0             0x15
#define AFE_ADCRSTENDCT0            0x16
#define AFE_ADCRSTSTCT1             0x17
#define AFE_ADCRSTENDCT1            0x18
#define AFE_ADCRSTSTCT2             0x19
#define AFE_ADCRSTENDCT2            0x1a
#define AFE_ADCRSTSTCT3             0x1b
#define AFE_ADCRSTENDCT3            0x1c
#define AFE_PRPCOUNT                0x1d
#define AFE_CONTROL1                0x1e
#define AFE_TIA_GAIN_SEP            0x20
#define AFE_TIA_GAIN                0x21
#define AFE_LEDCNTRL                0x22
#define AFE_CONTROL2                0x23
#define AFE_ALARM                   0x29
#define AFE_LED2VAL                 0x2a
#define AFE_ALED2VAL                0x2b
#define AFE_LED1VAL                 0x2c
#define AFE_ALED1VAL                0x2d
#define AFE_LED2_ALED2VAL           0x2e
#define AFE_LED1_ALED1VAL           0x2f
#define AFE_CONTROL3                0x31
#define AFE_PDNCYCLESTC             0x32
#define AFE_PDNCYCLEENDC            0x33
#define AFE_PROG_TG_STC             0x34
#define AFE_PROG_TG_ENDC            0x35
#define AFE_LED3LEDSTC              0x36
#define AFE_LED3LEDENDC             0x37
#define AFE_CLKDIV_PRF              0x39
#define AFE_OFFDAC                  0x3a
#define AFE_DEC                     0x3d
#define AFE_AVG_LED2_ALED2VAL       0x3f
#define AFE_AVG_LED1_ALED1VAL       0x40



void setup() {
  // put your setup code here, to run once:

  Serial.begin(19200);
  Wire.begin();  
  pinMode(RESETZ, OUTPUT);
  AFE_RESETZ_Init();
  AFE_Trigger_HWReset();
  AFE_Init();
  Serial.println("Press '1' to start and '2' to stop");
}

void loop() {
  // put your main code here, to run repeatedly:

  if (befehl == 1)
  {
    AFE_Reg_Write(9, 0);
    befehl = 0;
  }else if (befehl == 2)
  {
    AFE_Reg_Write(10, 0);
    befehl = 0;
  }
}

/**********************************************************************************************************/
/*                              Auslesen der seriellen Eingabeleiste                                      */
/**********************************************************************************************************/
void serialEvent()
{
  befehl = Serial.parseFloat();
}
/**********************************************************************************************************/
/*                              AFE4404_Initialisierung zum Start                                         */
/**********************************************************************************************************/

void AFE_Init()
{
  AFE_RESETZ_Init();
  AFE_Enable_HWPDN();
  AFE_Disable_HWPDN();
  AFE_Trigger_HWReset();
  //AFE_CLK_Init();
  AFE_Reg_Init();

}

/**********************************************************************************************************/
/*                              AFE4404_Registerinitialisierung                                           */
/**********************************************************************************************************/
void AFE_Reg_Init()
{
  AFE_Reg_Write(34, 0x0033C3);
}


/**********************************************************************************************************/
/*                              AFE4404_Enable_Read                                                       */
/**********************************************************************************************************/
void AFE_Enable_Read ()         //Prohibit writing to registers
{
  byte configData[3];
  configData[0]=0x00;
  configData[1]=0x00;
  configData[2]=0x01;
  I2C_write (AFE_ADDR, AFE_CONTROL0, configData, 3);
}

/**********************************************************************************************************/
/*                              AFE4404_Disable_Read                                                      */
/**********************************************************************************************************/
void AFE_Disable_Read ()        //Permitt writing to registers
{
  byte configData[3];
  configData[0]=0x00;
  configData[1]=0x00;
  configData[2]=0x00;
  I2C_write (AFE_ADDR, AFE_CONTROL0, configData, 3);
}

/**********************************************************************************************************/
/*                  RESETZ des AFE4404 wird Initialisiert                                                 */
/**********************************************************************************************************/
void AFE_RESETZ_Init()
{
  digitalWrite(RESETZ, HIGH);
}

/**********************************************************************************************************/
/*                  Reset internal registers by setting RESETZ = LOW for 25 - 50 us                       */
/**********************************************************************************************************/
void AFE_Trigger_HWReset()
{
  digitalWrite(RESETZ, LOW);              //Sets Arduino pins 22-29 LOW
  delayMicroseconds(30);
  digitalWrite(RESETZ, HIGH);              //Sets Arduino pins 22-29 HIGH
  delay(10);
}

/**********************************************************************************************************/
/*                             AFE4404 Power Down                                                         */
/**********************************************************************************************************/
void  AFE_Enable_HWPDN()
{
  digitalWrite(RESETZ, LOW);                  //Power Down by setting the RESETZ pin to LOW for more than 200 us
  delay(10);
}

/**********************************************************************************************************/
/*                                AFE4404 Power Up                                                        */
/**********************************************************************************************************/
void  AFE_Disable_HWPDN()
{
  digitalWrite(RESETZ, HIGH);                  //Power Up the AFE by setting the RESETZ pin to HIGH   
  delay(10);
}

/**********************************************************************************************************/
/*                                AFE4404 Set Clock Mode to Internal                                      */
/**********************************************************************************************************/
void AFE_CLK_Init()
{            
  AFE_Reg_Write(35, 0x104218);        //Set CLK Mode to internal clock (default Wert: 124218 mit interner CLK)
  AFE_Reg_Write(41, 0x2);             //Don´t set the internal clock to the CLK pin for outside usage
  AFE_Reg_Write(49, 0x000021);        //Division ratio for external clock mode set to fit the Arduino Mega 16MHz
  AFE_Reg_Write(57, 0);               //Set the lowes sampling rate to 61Hz (~17 ms)
}

/*********************************************************************************************************/
/*                                   AFE4404_Reg_Write                                                   */
/*********************************************************************************************************/
void AFE_Reg_Write (int reg_address, unsigned long data)
{
  byte configData[3];
  configData[0]=(byte)(data >>16);
  configData[1]=(byte)(((data & 0x00FFFF) >>8));
  configData[2]=(byte)(((data & 0x0000FF)));
  I2C_write(AFE_ADDR, reg_address, configData, 3); 
}

/*********************************************************************************************************/
/*                                   AFE4404_Reg_Read                                                    */
/*********************************************************************************************************/
signed long AFE_Reg_Read(int reg_address)
{
  byte configData[3];
  signed long retVal;
  I2C_read (AFE_ADDR, reg_address, configData, 3);
  retVal = configData[0];
  retVal = (retVal << 8) | configData[1];
  retVal = (retVal << 8) | configData[2];
  if (reg_address >= 0x2A && reg_address <= 0x2F)
  {
    if (retVal & 0x00200000)  // check if the ADC value is positive or negative
    {
      retVal &= 0x003FFFFF;   // convert it to a 22 bit value
      return (retVal^0xFFC00000);
    }
  }
  return retVal;
}

/**********************************************************************************************************/
/*                              Write to AFE on I2C                                                       */
/**********************************************************************************************************/
char I2C_write (int slave_address, int reg_address, byte configData[], int byteCount)
{
  int trans_end = 0;
  signed long retVal;
  
  Wire.beginTransmission(slave_address);
  Wire.write(reg_address);
  Serial.print(configData[0]);
  Serial.print(",");
  Serial.print(configData[1]);
  Serial.print(",");
  Serial.println(configData[2]);
  retVal = configData[0];
  retVal = (retVal << 8) | configData[1];
  retVal = (retVal << 8) | configData[2];
  Serial.println(retVal);
  Serial.println(reg_address);
  Wire.write(configData, 3);
  Serial.println("test");
  Wire.endTransmission();
  return (trans_end);
  
 /* while(1)
  {
    if(byteCount == 0)
    {
      Wire.endTransmission();
      Serial.println("test");
      return (trans_end);
    }else{
      //unsigned int reg_data = (unsigned int) *write_data++;
      Wire.write(configData, 3);
      byteCount--;
    }       
  }*/
}

/**********************************************************************************************************/
/*                              Read Data of AFE on I2C                                                   */
/**********************************************************************************************************/
char I2C_read(int slave_address, int reg_address, byte *read_Data, int byteCount)
{
  int trans_end = 0;
  
  Wire.beginTransmission(slave_address);
  Wire.write(reg_address);
  Wire.endTransmission();
  Wire.requestFrom(slave_address, 3);
  while(Wire.available() && (byteCount != 0))
  {
    *read_Data++ = Wire.read();
    byteCount--;
  }
  return (trans_end);
}

  • Hi Simon,

    I don't see the schematics.

    Just to narrow down the problem, can you please provide following information.
    1) Is AFE4404  giving ACK after you send salve address for any I2C operation? If not what is the slave address? Can you share analog waveform for the I2C_CLK and I2C_DATA pins during any I2C operation.
    2) Assuming AFE4404 gives ACK, can you measure voltage at INP pin of AFE after I2C_Write(0x23, 0x01)? Also measure before this I2C write operation.

    Regards,
    Prabin

  •  I´m sorry for not checking my post. I hope the schematics are attached this time. I did not get anything working on the AFE because the I2C communication stoped right at the first try to send something. I am going to get some analog waveforms for the I2C lines in the next days and will share them with you afterwards.

  • Hi Prabin,

    I regret to say that I did not manage to get proper waveforms to share yet. I´m working on it. 

    I produced one more board with an AFE on it and modified my source code a little bit. The I2C is now working and doesnt stop at the first try to communicate with the AFE. My problem now is that if I run my program to simply detect the slave address, it prints out 3 addresses for the AFE and none of them is the fixed AFE slave address.

    Further experiments led to the same outcome as last time which tells me I destroyed the AFE. I am going to produce some more boards for testing. 

    Does anyone have an idea why I´m getting multiple wrong addresses? My next try will be to vary the pullup resistors on both I2C lines.

    Simon

  • Hi Simon,

    I don't what exactly your program does to detect salve address but as mentioned in datasheet, AFE4404 has slave address of 0x58. Do you have other slaves in the I2C bus? If yes, can you remove other slaves and try again.
    Yes, can you change the pull up resistors on I2C lines to 10KOhm.

    Regards,
    Prabin
  • Hi Prabin,

    Here is the code for the I2C-Scanner I´m using to detect slave addresses. I downloaded it from the link mentioned in my first post. 

    I do not have any other devices attached to my setup. 

    Simon

    // I2C Scanner
    // Written by Nick Gammon
    // Date: 20th April 2011
    
    #include <Wire.h>
    
    void setup() {
      Serial.begin (115200);
    
      // Leonardo: wait for serial port to connect
      while (!Serial) 
        {
        }
    
      Serial.println ();
      Serial.println ("I2C scanner. Scanning ...");
      byte count = 0;
      
      Wire.begin();
      for (byte i = 8; i < 120; i++)
      {
        Wire.beginTransmission (i);
        Serial.println(i);
        if (Wire.endTransmission () == 0)
          {
          Serial.print ("Found address: ");
          Serial.print (i, DEC);
          Serial.print (" (0x");
          Serial.print (i, HEX);
          Serial.println (")");
          count++;
          delay (1);  // maybe unneeded?
          } // end of good response
      } // end of for loop
      Serial.println ("Done.");
      Serial.print ("Found ");
      Serial.print (count, DEC);
      Serial.println (" device(s).");
    }  // end of setup
    
    void loop() {}

  • Hi Simon,

    I am no expert in Arduino, however can you please change line 24 of "I2C Scanner" as

    if (Wire.endTransmission (True) == 0)

    Also if you have only one slave (AFE4404), do you really need this scanner program?

    Regards,
    Prabin
  • Hi Prabin,

    Your right. I dont need the I2C-Scanner. But since I have no idea if the AFE is working, I used the Scanner to see if it responses correctly to any I2C communication.

    I am sad to say that this project might not get finished in time. I just received a new date to assamble a new sensor board which is only a couple of days before I need to present my diploma thesis. 

    Thank you for your help.

    Simon

  • Hi Simon,

    You can do following checks to determine if AFE responding to I2C protocol.
    1) Send a slave address and look for ACK signal, if it is low that means AFE is responding.
    2) Measure the INP/INM pin before and after I2C_Write(0x23, 0x1). Before the write it should be 0.9V and after the write it should be ~0.

    Regards,
    Prabin