Post Go back to editing

Problem with AD7856 SPI in Arduino... Help!!

Hi, I try using the AD7856 in Arduino Mega ADK board, I read the datasheet and I have programing under Mode 2, but the AD7856 don't answer me, I connect a oscilloscope to MOSI and MISO lines and Arduino board send correctly the 16bits in MOSI line but in MISO only LOW! so this is my code in Arduino IDE, I hope you can help me!

#include <SPI.h>
uint8_t adcMSB = 0, adcLSB = 0;
unsigned int read_adc;
void setup()
{
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV4); //master clock 4MHZ
  SPI.setDataMode(SPI_MODE3);               //mode SPI 3
  SPI.setBitOrder(MSBFIRST);
  pinMode(53,OUTPUT);     
  digitalWrite(53,HIGH);
  pinMode(46,OUTPUT);
  digitalWrite(46,HIGH);
  Serial.begin(9600);
}


void loop()
{
  digitalWrite(46,LOW);     //this start the conversion in specific pin CONVST
  delay(1);                              //wait the device busy pin
  digitalWrite(46,HIGH);     //and start the trans.
  digitalWrite(53,LOW);     //enable device
  adcMSB=SPI.transfer(0b11100001); //here I configure the bits in Control Register, read channel 1, power mode normal
  adcLSB=SPI.transfer(0b00010001); //this read from ADC OUTPUT DATA REGISTER, start the Conversion, select mode 2
  digitalWrite(53,HIGH); //disable device
  delay(300);
  
//read for results
  read_adc= word(adcMSB, adcLSB);
  Serial.print(read_adc,HEX);
  Serial.print(" ");
  Serial.println(read_adc,DEC);
  
}

and this is my schematic:

  • Hi,

    Thanks for your question. We are looking into this and will get back to you soon.

    Regards,

    Karen

  • Hi,

    Apologies for the delayed response. Please note that this part should be allowed 150 ms after power up to perform its calibration before any reading or writing takes place. Can you provide scope shots of the digital signals for us to take a closer look?

    Thanks,

    Karen

  • Hi, sorry to don't answering soon but I have many work and I still fight with this ADC. I write this code to drive the ADC:

    #include <SPI.h>
    
    
    
    
    
    uint8_t adcMSB = 0, adcLSB = 0;
    unsigned int read_adc;
    //uint8_t CtrlRegMSB = B11100001;
    //uint8_t CtrlRegLSB = B00010001;
    uint8_t CtrlRegMSB = B11100000;
    uint8_t CtrlRegLSB = B00010000;
    float Vin=0;
    float N=3.05194e-4;
    void setup()
    {
    
      SPI.begin();
      SPI.setClockDivider(SPI_CLOCK_DIV128);
      SPI.setDataMode(SPI_MODE0);
      SPI.setBitOrder(MSBFIRST);
      pinMode(53,OUTPUT);
      digitalWrite(53,HIGH);
      pinMode(12,OUTPUT);
      digitalWrite(12,HIGH);
      Serial.begin(9600);
      //delay(500);
    }
    
    
    void loop()
    {
      digitalWrite(12,LOW);
      delayMicroseconds(1);
      digitalWrite(12,HIGH);
      delayMicroseconds(10);
    
      digitalWrite(53,LOW);
      SPI.transfer(CtrlRegMSB); 
      SPI.transfer(CtrlRegLSB); 
      digitalWrite(53,HIGH);
    
      delayMicroseconds(10);
    
      digitalWrite(53,LOW);
      adcMSB=SPI.transfer(0x00);  
      adcLSB=SPI.transfer(0x00);  
      digitalWrite(53,HIGH);
    
      delay(100);
    
      read_adc= word(adcMSB, adcLSB);
      Vin=N*read_adc;
      Serial.print(Vin, DEC);
    //  Serial.print("\t");
    //  Serial.print(comm,BIN);
      Serial.print("\t");
      Serial.println(read_adc,DEC); 
    }
    
    

    The ADC works one time, one or two seconds, then stops and does not send anything to the master then turns off and turns on the ADC (a kind of reboot), and work again one or two seconds.

    The operation is performed with hardware SPI, SPI previously had with software and the device did not stop and I require that the ADC works with hardware SPI speed matters.

    I use the external clock in the CLKIN (pin 22) and pin to CONVST.

    This is answer of ADC when the AN1 is in 5VDC:

    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.6274788379 2056
    0.0701946163 230
    0.1196360473 392
    0.0701946163 230
    0.1171944975 384
    0.0701946163 230
    0.1196360473 392
    0.0701946163 230
    0.0704998111 231
    0.0701946163 230
    0.0704998111 231
    0.1196360473 392
    0.0390648317 128
    0.0000000000 0
    4.9999933242 16383
    4.9999933242 16383
    4.9999933242 16383
    0.0778244733 255
    0.0778244733 255
    0.0778244733 255
    4.9413962364 16191
    4.9996881484 16382
    1.2497694492 4095
    4.9929738044 16360
    4.9221687316 16128
    0.2151617765 705
    0.0585972499 192
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0537141418 176
    0.0109869837 36
    1.2451915740 4080
    4.9929738044 16360
    4.9905323982 16352
    4.9993829727 16381
    4.9978570938 16376
    4.6969356536 15390
    4.9954152107 16368
    4.9978570938 16376
    4.9999933242 16383
    4.9999933242 16383
    4.9267468452 16143
    0.0488310384 160
    0.6879072666 2254
    0.0045779104 15
    0.0006103880 2
    0.0000000000 0
    0.0390648317 128
    0.0347921180 114
    0.0109869837 36
    4.9984674453 16378
    4.9905323982 16352
    4.9978570938 16376
    4.9996881484 16382
    4.9984674453 16378
    1.2491590976 4093
    1.0901529788 3572
    1.2497694492 4095
    4.9996881484 16382
    4.9978570938 16376
    4.9996881484 16382
    4.9999933242 16383
    1.2299318313 4030
    4.9999933242 16383
    4.9999933242 16383
    4.9929738044 16360
    4.9954152107 16368
    4.9954152107 16368
    4.9966363906 16372
    4.9978570938 16376
    4.9954152107 16368
    1.2497694492 4095
    1.2491590976 4093
    4.9978570938 16376
    4.4482026100 14575
    4.9926686286 16359
    4.9978570938 16376
    4.9969415664 16373
    0.3076355457 1008
    0.0744673347 244
    0.0231947445 76
    0.0073246564 24
    0.0000000000 0
    0.0146493124 48
    0.0000000000 0
    0.0000000000 0
    0.0704998111 231
    0.0000000000 0
    0.0488310384 160
    0.0488310384 160
    0.0439479351 144
    4.9905323982 16352
    0.3119082689 1022
    4.9902272224 16351
    4.9948048591 16366
    4.9734416007 16296
    4.9734416007 16296
    1.2497694492 4095
    4.9743571281 16299
    4.9999933242 16383
    4.9920582771 16357
    4.9999933242 16383
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0
    0.0000000000 0

    thanks a lot, best regards!

    El mensaje fue editado por: José Miguel Hernández I edit because add the answer of ADC

  • I have a new version, in this version I read and write in ADC via SPI hardware:

    but i have problems with interfacing, I have waiting 15 ms and repeat the instruction as a minimum twice to read more than two channelss: this is the new version:


    #include <Expander32.h>
    #include <SPI.h>
    
    /*
    Definitions to work all channels
    */
    #define AN1 B11100001
    #define AN2 B11110001
    #define AN3 B11100101
    #define AN4 B11110101
    #define AN5 B11101001
    #define AN6 B11111001
    #define AN7 B11101101
    #define AN8 B11111101
    
    Expander32 expander(40, 41); //Enable pins to Expander32SS board
    
    //uint8_t adcMSB1 = 0, adcLSB1 = 0;
    //unsigned int read_adc1;
    
    uint8_t RstADCMSB = B01000000;    //this command 
    uint8_t RstADCLSB = B00000010;    //reset the spi in ADC
    uint8_t CtrlRegMSB = B11100000;    //this command select the chhanel 1
    uint8_t CtrlRegLSB = B00010001;    //this commans is the same to all channels
    //uint8_t CtrlRegMSB = B11100001;
    //uint8_t CtrlRegLSB = B00010001;
    
    //uint8_t StatRegMSB = B11100001;
    //uint8_t StatRegLSB = B10010001;
    
    uint16_t AD1=0;
    uint16_t AD2=0;
    uint16_t AD3=0;
    float Vin1=0, Vin2=0, Vin3=0;
    float N=3.05194e-4;    //cte to voltaje convertion 5/((2^14)-1)
    void setup()
    {
      expander.init();        //initialitation of the Expander32SS board
      SPI.begin();
      SPI.setClockDivider(SPI_CLOCK_DIV128);    //Spi to 125kHz
      SPI.setDataMode(SPI_MODE0);                //SPI in mode 0
      SPI.setBitOrder(MSBFIRST);          //send the most significant bit first
      pinMode(53,OUTPUT);
      digitalWrite(53,HIGH);        //Disable the ADC
      pinMode(12,OUTPUT);          
      digitalWrite(12,HIGH);        //PIN to convst ADC
      Serial.begin(9600);
      delay(150);              //Wait for ADC auto calibration
    }
    
    void loop()
    {
      
      setChannel(AN1);            //What channel read?
      delayMicroseconds(10);    //wait the complete convertion 5us
      AD1 = readChannel();        //read the ADC value
      
    //  delayMicroseconds(100);
    //
    
      setChannel(AN2);            //What channel read?
      delayMicroseconds(10);    //wait the complete convertion
      AD2 = readChannel();        //read the ADC value
      
      Vin1=N*AD1;          //Voltaje convertion
      Vin2=N*AD2;          //Voltaje convertion
      
      /*Print the results in serial RS232*/
      Serial.print(Vin1, DEC);
      Serial.print("\t");
      Serial.print(AD1,DEC);
      Serial.print("\t");
      Serial.print(Vin2,DEC);
      Serial.print("\t");
      Serial.println(AD2,DEC); 
      
    }
    
    /*
    Method to select the channel of ADC
    */
    void setChannel(uint8_t channel){
      for (int i=1; i>=0; i--){    // this methos call twice and dont kwon why
      digitalWrite(12,LOW);        //start convertion 
      delayMicroseconds(1);        //
      digitalWrite(12,HIGH);       //
      delayMicroseconds(10);       //Wait a moment
      expander.Spin(16);        //Enable of SPin 16 in Expander32SS board 
      digitalWrite(53,LOW);      //Enable ADC
      SPI.transfer(channel);     //channel to set
      SPI.transfer(CtrlRegLSB);  //Same command all channels
      digitalWrite(53,HIGH);      //Disable ADC
      expander.disable();
      delay(15);                  //Wait 15 ms and dont kwon why
      }
    }
    
    /*
    Method to read the value of ADC
    */
    uint16_t readChannel(void){
      uint16_t out=0;
      uint8_t adcMSB=0;
      uint8_t adcLSB=0;
      for (int i=1; i>=0; i--){    // this methos call twice and dont kwon why
      digitalWrite(12,LOW);        //start convertion 
      delayMicroseconds(1);        //
      digitalWrite(12,HIGH);       //
      delayMicroseconds(10);       //Wait a moment
      expander.Spin(16);        //Enable of SPin 16 in Expander32SS board 
      digitalWrite(53,LOW);      //Enable ADC
      adcMSB=SPI.transfer(0x00);  //send 0x00 to generate clock signal 
      adcLSB=SPI.transfer(0x00);  //send 0x00 to generate clock signal
      digitalWrite(53,HIGH);      //Disable ADC
      expander.disable();
      delay(15);                  //Wait 15 ms and dont kwon why
      }
      out= word(adcMSB, adcLSB);
    
      return out;
    }
    

    With this code the ADC don't stops but and I write to zero un bus spi to read the sample.


    best regards!

  • Hi,

    Let me check on this. Meanwhile, if you could provide scope shots of the digital signals (/SYNC, SCLK, DOUT, DIN) together in one cycle, it would help a lot.

    Regards,

    Karen

  • thanks, I don't have a scope with four channels only have a two channels I hope  this serves.

    Best regards!

    Miguel

  • Hi, Miguel.

    Thanks for providing these. Am I correct to assume that SS refers to your /SYNC line? If so, why is this high? This pin is level triggered active low and frames the serial clock for the read and write operations. Also, please check how you are configuring the part. The 1st two bits of MOSI determine which register is addressed, and the subsequent 14 bits of data are written to the addressed register. From the scope shots, the first two bits are 00 which does not address any register. Hence, the next 14 bits are ignored.

    Regards,

    Karen

  • Sorry Karen but I don't know what happen with the channel one of the scope but the signals are in negative state i.e. zeros are ones and ones are zeros, I check this in other scope but this don't have screen shoots sorry!

  • I check the scope and have a incorerct configuration in the channel one, this scope shoots are correct:

    SS is connect in SYNC pin.

    This is the command in to setChannel() function.

    This is the command in to readChannel() function.

    This scope shoot is the answer of ADC.

    thanks for help me!

  • Hi, Miguel.

    I would just like to clarify, is the MISO line (4th image) the captured ADC result for an input of 5VDC on AIN1? Also, can you check if your channel 2 (for SCK) is also inverted? Note that the AD7856 datasheet states that when a noncontinuous SCLK is used, it should idle high.

    Regards,

    Karen