0

I am fairly new to programming so I have no idea if what I am doing is right here. This is the datasheet page 71 is most helpful I think, or 71-75. Which I have been following, as well as some prewritten code. This is an example of where I try to select the pointer

  writeNAFE16b(0x30, 0x8020, CS_AFE);  //SYS_CONFIG0
  writeNAFE16b(0x32, 0x0000, CS_AFE);  //GLOBALARMENABLE

  writeNAFE16b(0x00, 0x0000, CS_AFE);  //CMD_SETPOINTER0
  //sendCommand16(0x0000);
  writeNAFE16b(0x20, 0x11F1, CS_AFE);  //CH_CONFIG0
  writeNAFE16b(0x21, 0x909B, CS_AFE);  //CH_CONFIG1
  writeNAFE16b(0x22, 0x4400, CS_AFE);  //CH_CONFIG2
  writeNAFE16b(0x23, 0xAC10, CS_AFE);  //CH_CONFIG3
  

  writeNAFE16b(0x01, 0x0000, CS_AFE);  //CMD_SETPOINTER1
  //sendCommand16(0x0001);
  writeNAFE16b(0x20, 0x71F1, CS_AFE);  //CH_CONFIG0
  writeNAFE16b(0x21, 0x909B, CS_AFE);  //CH_CONFIG1
  writeNAFE16b(0x22, 0x4400, CS_AFE);  //CH_CONFIG2
  writeNAFE16b(0x23, 0xAC10, CS_AFE);  //CH_CONFIG3

  writeNAFE16b(0x24, 0x0003, CS_AFE);  //CH_CONFIG4

and also here where I try to read data

if (newDataAvailable){
    newDataAvailable = false;
    
    writeNAFE16b(0x00, 0x0000, CS_AFE);
    //sendCommand16(0x0000);
    delayMicroseconds(5);
    int32_t raw1 = readNAFE24b(0x40,CS_AFE);//read channel 0

    // Sign extension for 24-bit negative numbers
    if (raw1 & 0x800000) {
      raw1 |= 0xFF000000;
    }

    latestRaw1Value = raw1; // Save the result

    writeNAFE16b(0x01, 0x0000, CS_AFE);
    //sendCommand16(0x0001);
    delayMicroseconds(5);
    int32_t raw2 = readNAFE24b(0x41,CS_AFE);//read channel 1

    // Sign extension for 24-bit negative numbers
    if (raw2 & 0x800000) {
      raw2 |= 0xFF000000;
    }

    latestRaw2Value = raw2; // Save the result
  }

This method of choosing a pointer has worked in the past but the code fails under specific applications (and sometimes I can clearly see I am reading data from the wrong register) so I think I'm missing something and just getting lucky sometimes. I have tried switching the writeNAFE() function for sendcommand16() (commented) but I don't know if the function works as intended

#define SPI_CMD_WORD(addr, cmd, dir)    (((addr & 0x01) << 15) | (cmd << 1) | (dir<<14))
#define HIGH_BYTE(word)                 (((word) >> 8) & 0xFF)
#define LOW_BYTE(word)                  ((word) & 0xFF)

void sendCommand16(uint16_t cmd) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
  digitalWrite(CS_AFE, LOW);
  SPI.transfer((cmd >> 8) & 0xFF);  // high byte first
  SPI.transfer(cmd & 0xFF);         // low byte
  digitalWrite(CS_AFE, HIGH);
  SPI.endTransaction();
}

I've tried switching between writeNAFE16b(0x01,0x0000) and sendCommand16(0x0001) with no success. I printed out the register values after writing to each one and at first the pointer1 registers were the same as an old piece of code, I commented out the pointer0 register writing and after a few uploads the pointer1 registers were right. But when I tried to read both pointer's registers back again after a reload (sendCommand16(0x0016)) only pointer1's registers were read back to me.

Let me know if I can improve this question in any way!

EDIT: Here is the smallest example of how I'm trying to use this code. It requires a PT100 as well as the NAFE 13388

#include <SPIFFS.h>             //to store HTML on flash memory
#include <SPI.h>
#include <cmath>

constexpr uint8_t SPI_MOSI = 11; //6;
constexpr uint8_t SPI_MISO = 13; //5;
constexpr uint8_t SPI_SCK = 12; //4;
constexpr uint8_t CS_AFE = 10; //19;
constexpr uint8_t DRDY = 21;
constexpr uint8_t SYNC = 47; //should be 22; for real thing

#define SPI_CMD_WORD(addr, cmd, dir)    (((addr & 0x01) << 15) | (cmd << 1) | (dir<<14))
#define HIGH_BYTE(word)                 (((word) >> 8) & 0xFF)
#define LOW_BYTE(word)                  ((word) & 0xFF)

float GAIN = 16;
const float VREF = 10;
volatile int32_t latestRaw1Value = 0;
volatile int32_t latestRaw2Value = 0;
volatile bool newDataAvailable = false; // Flag for new data read
const float IREF = 0.000509;            //checked using multimeter

//An interrupt function, means data is ready to be sent from AFE
void IRAM_ATTR dataReady() {
    newDataAvailable = true; 
}

void sendCommand16(uint16_t cmd) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
  digitalWrite(CS_AFE, LOW);
  SPI.transfer((cmd >> 8) & 0xFF);  // high byte first
  SPI.transfer(cmd & 0xFF);         // low byte
  digitalWrite(CS_AFE, HIGH);
  SPI.endTransaction();
}

void writeNAFE16b(uint16_t reg, uint16_t value, uint8_t cs_pin) {
    uint16_t word = SPI_CMD_WORD(0, reg, 0);
    
    SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
    digitalWrite(cs_pin, LOW);
  
    SPI.transfer(HIGH_BYTE(word));
    SPI.transfer(LOW_BYTE(word));
    SPI.transfer(HIGH_BYTE(value));
    SPI.transfer(LOW_BYTE(value));
  
    digitalWrite(cs_pin, HIGH);
    SPI.endTransaction();
}

int32_t readNAFE24b(uint16_t reg, uint8_t cs_pin) {
    uint16_t word = SPI_CMD_WORD(0, reg, 1);
    
    SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
    digitalWrite(cs_pin, LOW);
  
    SPI.transfer(HIGH_BYTE(word));
    SPI.transfer(LOW_BYTE(word));
    uint8_t high_value = SPI.transfer(0x00);
    uint8_t mid_value = SPI.transfer(0x00);
    uint8_t low_value = SPI.transfer(0x00);
  
    digitalWrite(cs_pin, HIGH);
    SPI.endTransaction();
    
    int32_t raw = ((int32_t)high_value << 16) | ((int32_t)mid_value << 8) | ((int32_t)low_value);

    return raw;
}


void setup() {
  Serial.begin(115200);

  pinMode(CS_AFE, OUTPUT);
  pinMode(SYNC, OUTPUT);
  pinMode(DRDY, INPUT);

  digitalWrite(CS_AFE, HIGH);
  digitalWrite(SYNC, LOW);
  //turns DRDY into interrupt pin, so when there is data ready, it's pulled low and onDataReady is called
  attachInterrupt(digitalPinToInterrupt(DRDY), dataReady, RISING);

  SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);   //Initializes SPI with these pin

  //Pulse SYNC low to reset digital logic
  digitalWrite(SYNC, HIGH);
  delayMicroseconds(10);
  digitalWrite(SYNC, LOW);
  delay(5); //allow time to settle

  // Reset device
  sendCommand16(0x0014); // RESET
  delay(50);

  writeNAFE16b(0x30, 0x8020, CS_AFE);  //SYS_CONFIG0
  writeNAFE16b(0x32, 0x0000, CS_AFE);  //GLOBALARMENABLE

  //PT100 red wires connected to AICOM and AI1P, white wire to AI2P and AI1N (another wire is used to connect these 2 pins and the white wire is in 1)

  writeNAFE16b(0x00, 0x0000, CS_AFE);  //CMD_SETPOINTER0
  //sendCommand16(0x0000);                                //Alternative way to set pointer?
  writeNAFE16b(0x20, 0x11F1, CS_AFE);  //CH_CONFIG0
  writeNAFE16b(0x21, 0x909B, CS_AFE);  //CH_CONFIG1
  writeNAFE16b(0x22, 0x4400, CS_AFE);  //CH_CONFIG2
  writeNAFE16b(0x23, 0xAC10, CS_AFE);  //CH_CONFIG3
  

  writeNAFE16b(0x01, 0x0000, CS_AFE);  //CMD_SETPOINTER1
  //sendCommand16(0x0001);
  writeNAFE16b(0x20, 0x71F1, CS_AFE);  //CH_CONFIG0
  writeNAFE16b(0x21, 0x909B, CS_AFE);  //CH_CONFIG1
  writeNAFE16b(0x22, 0x4400, CS_AFE);  //CH_CONFIG2
  writeNAFE16b(0x23, 0xAC10, CS_AFE);  //CH_CONFIG3

  writeNAFE16b(0x24, 0x0003, CS_AFE);  //CH_CONFIG4

}

void loop() {

  delay(5000);

  digitalWrite(SYNC, HIGH);
  delayMicroseconds(2);
  digitalWrite(SYNC, LOW);
  
  if (newDataAvailable){
    newDataAvailable = false;
    
    writeNAFE16b(0x00, 0x0000, CS_AFE);
    //sendCommand16(0x0000);
    delayMicroseconds(5);
    int32_t raw1 = readNAFE24b(0x40,CS_AFE);//read channel 0

    // Sign extension for 24-bit negative numbers
    if (raw1 & 0x800000) {
      raw1 |= 0xFF000000;
    }

    latestRaw1Value = raw1; // Save the result

    writeNAFE16b(0x01, 0x0000, CS_AFE);
    //sendCommand16(0x0001);
    delayMicroseconds(5);
    int32_t raw2 = readNAFE24b(0x41,CS_AFE);//read channel 1

    // Sign extension for 24-bit negative numbers
    if (raw2 & 0x800000) {
      raw2 |= 0xFF000000;
    }

    latestRaw2Value = raw2; // Save the result
  }

  // If new data is available, process it
  noInterrupts(); // Critical section
  int32_t raw1 = latestRaw1Value;
  interrupts();

  // Voltage conversion
  float sINT24A = ((raw1 + 8388608) % 16777216) - 8388608;
  float voltage1 = (VREF / 16777216.0) * (sINT24A / GAIN);
  Serial.print("voltage1: ");
  Serial.println(voltage1,6);

  noInterrupts(); // Critical section
  int32_t raw2 = latestRaw2Value;
  interrupts();

  // Voltage conversion
  
  float sINT24B = ((raw2 + 8388608) % 16777216) - 8388608;
  float voltage2 = (VREF / 16777216.0) * (sINT24B / GAIN);
  Serial.print("voltage2: ");
  Serial.println(voltage2,6);

  float diff = abs(voltage1-voltage2);
  Serial.print("difference: ");
  Serial.println(diff,6);
  float R = diff/IREF;
  Serial.print("RTD resistance: ");
  Serial.println(R,6);
  float temp = -0.0000000007497*R*R*R*R + 0.000001462*R*R*R + 0.0005452*R*R + 2.4097*R -247.8075;
  Serial.print("temp: ");
  Serial.println(temp,6);
  Serial.println("");
}

The setup details can be found here in section 4

1
  • You never really ask a question or explain what you are trying to read, and what is the expected result and what and where is not working. You are asking people to read the datasheet and check against your code to guess what is not working. Secondly, to test on whether SPI can function correctly, the PT100 is irrelevant, you could connect the ADC input to a a voltage divider with two equal values resistors connect between 3.3V and GND, if you could get a raw value or voltage reading that equal to half of th 3.3V, you then know your ADC and SPI is working correctly. Commented Sep 9 at 2:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.