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.

ADS7038: Auto-sequence mode code

Part Number: ADS7038

Hi tried to set up a code for auto sequenceing through 8 channels (sensors) and concerting the anaolg to digital signal (reding out with Arduino Mega). Apparently the data does not make sense. I checked with the oscilloscope that the transmission and receiving works properly. Hence, I assume it is due to the code. Could you please help me? The sample code did not help me in this regard.

#include <SPI.h>

// chip select
uint8_t csPins[] = {53}; //ADC csPins to Arduino, specify the Arduino pins

// Mode       Clock Polarity (CPOL)  Clock Phase (CPHA)     Output Edge     Data Capture
// SPI_MODE0        0                         0               Falling         Rising
// SPI_MODE1        0                         1               Rising          Falling
// SPI_MODE2        1                         0               Rising          Falling
// SPI_MODE3        1                         1               Falling         Rising
static const SPISettings SPI_SETTINGS {1000000, MSBFIRST, SPI_MODE0};

// Register addresses
static const uint8_t ADDR_SYSTEM_STATUS   {0x00};
static const uint8_t ADDR_GENERAL_CFG     {0x01};
static const uint8_t ADDR_DATA_CFG        {0x02};
static const uint8_t ADDR_OSR_CFG         {0x03};
static const uint8_t ADDR_PIN_CFG         {0x05};
static const uint8_t ADDR_SEQUENCE_CFG    {0x10};
static const uint8_t ADDR_CHANNEL_SEL     {0x11};
static const uint8_t ADDR_AUTO_SEQ_CH_SEL {0x12};

static const uint8_t OPCODE_NO_OP   {0x00};
static const uint8_t OPCODE_WR_REG  {0x08};
static const uint8_t OPCODE_RD_REG  {0x10};
static const uint8_t OPCODE_SET_BIT {0x18};
static const uint8_t OPCODE_CLR_BIT {0x20};

int8_t selected_adc_idx {-1};

void selectADC(uint8_t idx = 0) {
  digitalWrite(csPins[idx], LOW);
  selected_adc_idx = idx;
}

void deselectADC() {
  digitalWrite(csPins[selected_adc_idx], HIGH);
  selected_adc_idx = -1;
}

uint8_t readRegister(uint8_t adc_idx, uint8_t reg)
{
  // send 24-bit cmd: RD_REG, addr, NO_OP
  uint8_t cmd[3] {OPCODE_RD_REG, reg, OPCODE_NO_OP};
  uint8_t response[3];

  selectADC(adc_idx);
  SPI.beginTransaction(SPI_SETTINGS);

  for (int i = 0; i < 3; i++)
  {
    SPI.transfer(cmd[i]);
  }

  // CS needs to be pulled high for the command to be processed
  deselectADC();
  delayMicroseconds(100);
  selectADC(adc_idx);

  for (int i = 0; i < 3; i++)
  {
    response[i] = SPI.transfer(0);
  }
 
  SPI.endTransaction();
  deselectADC();

  return response[0];
}

void writeRegister(uint8_t adc_idx, uint8_t addr, uint8_t val)
{
  // send 24-bit cmd: WR_REG, addr, data
  uint8_t cmd[3] {OPCODE_WR_REG, addr, val};

  selectADC(adc_idx);
  SPI.beginTransaction(SPI_SETTINGS);

  for (int i = 0; i < 3; i++)
  {
    SPI.transfer(cmd[i]);
  }

  SPI.endTransaction();
  deselectADC();
}

void calibrateADC(uint8_t adc_idx)
{
  bool calibrated = false;

  // Set calibration bit
  uint8_t cfg = readRegister(adc_idx, ADDR_GENERAL_CFG);
  cfg |= 0x02;
  writeRegister(adc_idx, ADDR_GENERAL_CFG, cfg);

  // Wait for calibration bit to go back to 0
  while (!calibrated)
  {
    delayMicroseconds(100);
    cfg = readRegister(adc_idx, ADDR_GENERAL_CFG);
    //Serial.print(cfg);
    if ((cfg && 0x02) == 0)
    {
      calibrated = true;
    }
  }
  Serial.print("finished calibration");
}

void initADC(uint8_t adc_idx)
{
  // Add channel ID to ADC data
  uint8_t data_cfg = readRegister(adc_idx, ADDR_DATA_CFG);
  data_cfg |= 0x10;
  writeRegister(adc_idx, ADDR_GENERAL_CFG, data_cfg);

  // Enable all channels to be in sequence
  writeRegister(adc_idx, ADDR_AUTO_SEQ_CH_SEL, 0xFF);

  // Select auto sequence mode
  uint8_t seq_cfg = readRegister(adc_idx, ADDR_SEQUENCE_CFG);
  seq_cfg |= 0x11;
  writeRegister(adc_idx, ADDR_GENERAL_CFG, seq_cfg);
}

void readADC(uint8_t adc_idx, float* outputData)
{
  uint8_t data[2];
  uint8_t channel;
  uint16_t adcValue;

  selectADC(adc_idx);
  SPI.beginTransaction(SPI_SETTINGS);

  for (int i = 0; i < 2; i++)
  {
    data[i] = SPI.transfer(0);
   
    //Serial.println(data[i]);
  }
 
  SPI.endTransaction();
  deselectADC();

  channel = data[1] & 0x0F;

  adcValue = ((((uint16_t) data[0]) << 4) & 0x0FF0) | ((((uint16_t) data[1]) >> 4) & 0x000F);
  Serial.println(adcValue);
  // Scaling: AVDD / 4096
  *(outputData + channel) = ((float) adcValue) * (5.0f/4096.0f);
}

void setup()
{
  // Setup CS pins
  for (int i = 0; i < sizeof(csPins); i++)
  {
    pinMode(csPins[i], OUTPUT);
    digitalWrite(csPins[i], HIGH);
  }

  // Setup SPI
  SPI.begin();

  // Setup Serial
  Serial.begin(115200);

  // Setup ADC
  for (int i = 0; i < sizeof(csPins); i++)
  {
    calibrateADC(0);
    initADC(0);
  }

  delay(1);
}

void loop()
{
  float adcValues[8];
  char buffer[50];

  for (int i = 0; i < 8; i++)
  {
   
    Serial.print("channel "); Serial.println(i);
    readADC(0, adcValues);
    delayMicroseconds(10);
   }

 // sprintf(buffer, "ADC Values: \t CH0: %.2f \t CH1: %.2f \t CH2: %.2f \t CH3: %.2f \t CH4: %.2f \t CH5: %.2f \t CH6: %.2f \t CH7: %.2f \n\n", adcValues[0], adcValues[1], adcValues[2], adcValues[3], adcValues[4], adcValues[5], adcValues[6], adcValues[7]);
 // Serial.print(buffer);

  delay(1000);
}