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