Skip to main content

AFE4300 with Arduino Due

In this post, I make an experiment to use Arduino Due to control AFE4300 for measuring in BCM mode.

The code based on a guy in this link from Arduino Forum
https://forum.arduino.cc/index.php?topic=319141.0

However, this not work now because the SPI library now have changed to new style and really different if you want control Clock of SPI with the command SPI.setClockDevider().

Actually, if you use this function to control SPI, the clock of SCLK keep around 4Mhz and it gives incorrect data when you communicate with AFE4300.

For solving it, you need to rewrite two functions writeRegister() and readRegister() as below:

void writeRegister(unsigned char address, unsigned int data)
{
unsigned char firstByte = (unsigned char)(data >> 8); //LA CARA ES UN OCHO)
unsigned char secondByte = (unsigned char)data;
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));

digitalWrite(SS,LOW);
SPI.transfer(address);
//Send 2 bytes to be written
SPI.transfer(firstByte);
SPI.transfer(secondByte);
digitalWrite(SS,HIGH);

SPI.endTransaction();
}   

int readRegister(unsigned char address)
{
 
   SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
   
   int spiReceive = 0;
   unsigned char spiReceiveFirst = 0;
   unsigned char spiReceiveSecond = 0;
   
   address = address & 0x1F; //Ultimos 5 bits especifican la direccion
   address = address | 0x20; //Los primeros 3 bits tienen que ser 001 por código de operación de lectura
     //SPI.begin();
     digitalWrite(SS,LOW);
     SPI.transfer(address);
     spiReceiveFirst  = SPI.transfer(0x00);
     spiReceiveSecond = SPI.transfer(0x00);
     digitalWrite (SS, HIGH);
     //SPI.end();
    SPI.endTransaction();
   
       //Combine the two received bytes into a signed int
    spiReceive = (spiReceiveFirst << 8);  //LA CARA ES UN OCHO)
    spiReceive |= spiReceiveSecond;
    return spiReceive;
}

Here, we need to use  SPI.beginTransaction() with setting 1Mhz clock for SCLK and SPI.SPI.endTransaction(); to assure when communication no interruption is permitted.

Furthermore, AFE4300 requires a 1Mhz CLK from outside to make inject current from 1khz - 150khz. From the library pwm_lib.h we can make a 1Mhz Clk which not affected the operation of the Due board because it is based on the DMA technique.

Lastly, to read the value of the ADC_DATA_RESULT register. I use an interrupt on the DRDY pin which connects to PIN 2 of Due board.
When Data conversation on AFE4300 finishes DRDY will make a pulse in 8us and we can read the value of this register after this signal state and send data through serial(115200) to plot on PC.

The full  program can access through  this link
https://github.com/LongNguyen1984/AFE4300-

Notice:
AFE4300 when reading any registers except the data output register (read-only register), the stored register value will be clear, so we need to rewrite the content of the register.  When you use the readRegister() function above to read ADC_DATA_RESULT, it is fine. However, for read any other  registers, must be careful to rewrite the value you have just read. So for safety readRegister we need a function to read and rewrite the register:

int readRewriteRegister(unsigned char address, int valAFE)
{
    valAFE = readRegister(registerAddress);
    writeRegister(registerAddress,valAFE);
    return valAFE;
}

The image below shows the SCLK and MISO wires on Oscilloscope when using AFE4300EVM with MMB3 board to read a value from ADC_DATA_RESULT:

As you can see, after reading the register, it rewrites the have-just-read value. 
 

Comments

Popular posts from this blog

Serial Port Profile with CC2650 and CC2640R2 (part 2) Modified to transfer ADC values up to PC Step 1:  Include ACD.h library #include <ti/drivers/ADC.h>  Step 2: Insert period event in order to update ADC read values from the potentiometer #define SSSS_ICALL_EVT                         ICALL_MSG_EVENT_ID // Event_Id_31 #define SSSS_QUEUE_EVT                         UTIL_QUEUE_EVENT_ID // Event_Id_30 #define SSSS_PERIODIC_EVT                      Event_Id_00 //SOLUTION // Bitwise OR of all events to pend on #define SSSS_ALL_EVENTS                        (SSSS_ICALL_EVT        | \                                ...
Experiment Sensor Booster Pack with CC2650 In this experiment, we use CC2650 rather CC2640Rx2 to read light level from OTP3001 on the sensor board. It follows the Task 3, Task 4 from TI tutorial http://dev.ti.com/tirex/content/simplelink_academy_cc2640r2sdk_1_13_02_07/modules/ble_02_thermostat/ble_02_thermostat.html Here we need some modified like last post to make the project run. First, to define the board CC2650 in file Board.h #define     Board_I2C_TMP           CC2650_LAUNCHXL_I2C0 Also, define IC address in file otp3001.c( replaced for tmp007.c) #define Board_TMP_ADDR   0x47 #if defined(ONBOARD_TMP006) #define TMP_REGISTER TMP_DIE_TEMP #define TMP_ADDR     Board_TMP_ADDR #else #define TMP_REGISTER TMP_OBJ_TEMP #define CONF_REGISTER 0x01 #define TMP_ADDR     Board_TMP_ADDR #endif Declare two new variables for reading exponent part and result uint16_t       ...
Serial Port Profile with CC2650 and CC2640R2 This test based on code from TI support under link: For CC2650: https://github.com/ti-simplelink/ble_examples/blob/ble_examples-2.2/docs/spp_ble.md For CC2640R2: https://github.com/ti-simplelink/ble_examples/blob/simplelink_cc2640r2_sdk-2.20/examples/rtos/CC2640R2_LAUNCHXL/bleapps/simple_serial_socket_client/readme.md In this experiment, I use CC2640R2 as Server (Peripheral) and CC2650 as Client (Central) as the image below: Step1: import project spp_ble_client_cc2650lp (app and stack) for CC2650 Step2: modify Code of Service in file serial_port_service:               C0E0 ==> C0C0               C0E1 ==> C0C1               C0E2 ==> C0C2 If you don't change, Two Blue Tooth Board cant know to service each other. Step 3: import project simple_serial_socket_client_CC2640r2 for CC2640R2 here we using RealTerm...