Post Go back to editing

AD7928 Interfacing with Arduino

Category: Hardware
Product Number: AD7928
Software Version: Arduino - VS Code

Hello, I am trying to interface AD7928 with Teensy (Arduino Framewok) using the SPI Communication. My goal is to read 8 sensors with this ADC

  1. I set the SPI Mode to 2 for this communication as the Data clocks out on the DIN line at the falling SCLK cycles
  2. I wrote the Poweup mode function as shown in Figure 24 and Page 22 of the datasheet and towards the end I set the Control register to read channel 0 for the conversion.
  3. I do not intend to use the SEQ and Shadow at this point as they seemed to complicated for a beginner.
  4. I am following the Normal mode operation indicated in Fig 22 and the schematic in Figure 11.

I have the following function code to read all the sensors and update a global array that stores the analog value : ADCout[8] is the global array storing the the converted values.

The powerup mode already sets the channel address in the Control register to Vin0; hence at the end of the 7th iteration, the channel address is reset to Vin0;

void readAD7928All()
{ // By default read all 8 pins

 
  int digValue[8];

  u_int16_t ADC_Mask = 4095; // 0b0|AD2|AD1|AD0|0000 // Mask to isolate converted output

  // Step 1 : read channel 0 and move onto next until the end

  for (int itr = 0; itr < 8; itr++)
  {

    // Write Control Register for next and read the first channel

    byte Ctrlreg1_mask = 0b10000011;
    byte Ctrlreg1;
    byte channelBits;

    if (itr == 7)
    {
      channelBits = 0 << 2;                   // Channel Bit for next capture : reset channel bit to 0 for last channel
      Ctrlreg1 = Ctrlreg1_mask | channelBits; // Including ADD2-> ADD0
    }
    else
    {
      channelBits = (itr + 1) << 2;             // Channel Bit for next capture
      Ctrlreg1 = Ctrlreg1_mask | channelBits; // Including ADD2-> ADD0
    }

    // Byte 2: SHADOW | DON’TCARE | RANGE | CODING | - | - |- |-
    byte Ctrlreg2 = 0b00000011;

    u_int16_t CTRLReg = Ctrlreg1 << 4 | Ctrlreg2; // Control Register Stored as 16-bit

    // Transfer Begin
    SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE2));

    // noInterrupts(); // disable interupts to prepare to send address data to the ADC.
    digitalWrite(ADCChipSel, LOW);
    delayMicroseconds(1);

    digValue[itr] = SPI.transfer16(CTRLReg<<4); // Transfer and capture the reading

    digitalWrite(ADCChipSel, HIGH);
    delayMicroseconds(1);

    // interrupts();
    SPI.endTransaction();

    // Transfer Complete
    digValue[itr] = digValue[itr] & ADC_Mask;
    ADCout[itr] = float(digValue[itr]) * 2.5 / 4096;
  }
 
}

The ADC output determined this way is very random. I even connected the 4 SPI channels to the Oscilloscope and I get random output from the ADC. I seek help here to improve my understanding and help me acquire the signals using this ADC

Thank you.

Yellow - CS; Turqoise - SCLK; Pink : DIN, Blue - Dout - I was trying to read channel 0