Author Topic: DAC 7612..With arduino due  (Read 5942 times)

0 Members and 1 Guest are viewing this topic.

Offline brendanTopic starter

  • Contributor
  • Posts: 15
DAC 7612..With arduino due
« on: March 26, 2015, 04:01:48 pm »
Hey, i am programming an external DAC 7612  with arduino DUE. I think there is something wrong in my Programm, but i dont know where. here is the datasheet of my DAC: http://www.ti.com/lit/ds/symlink/dac7612.pdf
here is the Programm i wrote:

#include<SPI.h>
int dacChipselectPin = 8;
int load  = 9;
void setup() {
                     
  pinMode(dacChipselectPin, OUTPUT);                     
  pinMode(load, OUTPUT);
  digitalWrite(load, LOW);
  digitalWrite(dacChipselectPin, HIGH);                 
  SPI.begin();                             
  SPI.setDataMode(SPI_MODE3);             
  SPI.setClockDivider(dacChipselectPin,21);             
  SPI.setBitOrder(MSBFIRST);               
  Serial.begin(9600);
}
void loop(){
 
 
  readDAc(2048,1);
  delayMicroseconds(10);
}
int readDAc(int value,int channel){
 
  int dacSecondaryMask = 0b0000000011111100;
  byte dacPrimarybyte = (value>>6);
  byte dacSecondarybyte = (value<<2)&dacSecondaryMask;
  Serial.println(dacSecondarybyte);
  switch(channel){
    case 0:       //A
    dacPrimarybyte |=0b10000000;
    break;
    case 1:    //B
    dacPrimarybyte |=0b11000000;
    break;
    }
    digitalWrite(load, HIGH);
    delayMicroseconds(1);
    digitalWrite(dacChipselectPin, LOW);
    SPI.transfer(dacPrimarybyte);
    SPI.transfer(dacSecondarybyte);
    digitalWrite(dacChipselectPin,HIGH);
    digitalWrite(load, LOW);
    delayMicroseconds(100);
 
}   

Please if someone has an idea, i will be pleased to be helped




 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #1 on: March 26, 2015, 04:10:41 pm »
When i send readDAC(4095,1), i am supposed to get 4.095 V at Output B. but whith this Programm i got 4.095 on both output
 

Offline PeterFW

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: de
    • Stuff that goes boom
Re: DAC 7612..With arduino due
« Reply #2 on: March 26, 2015, 05:27:46 pm »
At first glance i see a few "problems".

Initialise the SPI first, keep your fingers off the CS pin until after that.

It may be that you are using the "SPI.setClockDivider" function wrong.

If i am not mistaken you have to toggle LOADDACS after you clocked the data into the input register to latch it to the output register.

Why is the function called read? The dac is a output device.

There is at least one case mismatch in your code the compiler should have told you that.
 

Offline sunnyhighway

  • Frequent Contributor
  • **
  • Posts: 276
  • Country: nl
Re: DAC 7612..With arduino due
« Reply #3 on: March 26, 2015, 08:16:35 pm »
I can see only one problem that keeps the code from functioning properly.

The DAC expects only 14 bits coming into the shift register. MSB first and LSB last.
The problem is that with the following two line you push 16 bits into the shift register.
Code: [Select]
    SPI.transfer(dacPrimarybyte);
    SPI.transfer(dacSecondarybyte);

As a result the first two bits that went into the shift register will fall out of the shift register,  straight into the proverbial bit-bucket.
In your code that will be the A1 and A0 bit.

The following code takes into account that the first two bits send into the shift register will be lost.

Code: [Select]
  int dacSecondaryMask = 0b0000000011111111;
  byte dacPrimarybyte = value >> 8; // Drop the 8 LSB's
  byte dacSecondarybyte = value & dacSecondaryMask; // Drop the 8 MSB's
 
  // The two bits marked with xx can be anything because they are shifted out of the register into the bitbucket,
  switch (channel) {
    case 0://A          0bxx100000
      dacPrimarybyte |= 0b00100000; // A1 = 1, A0 = 0
      break;
    case 1://B          0bxx110000
      dacPrimarybyte |= 0b00110000; // A1 = 1, A0 = 1
      break;
  }

edit:fixed typo.
« Last Edit: March 26, 2015, 08:26:42 pm by sunnyhighway »
 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #4 on: March 26, 2015, 10:17:28 pm »
hey thank you for your reply. i will test your code tomorow.
but I have another question, you said the two leading bits of primarybyte of your code are shifted out. I though the SPI.transfer would shift the last to bits of secondarybyte out. may be i am wrong, i just want to be sure. I am new in spi programming.
 

Offline sunnyhighway

  • Frequent Contributor
  • **
  • Posts: 276
  • Country: nl
Re: DAC 7612..With arduino due
« Reply #5 on: March 26, 2015, 11:36:29 pm »
hey thank you for your reply. i will test your code tomorow.
but I have another question, you said the two leading bits of primarybyte of your code are shifted out. I though the SPI.transfer would shift the last to bits of secondarybyte out. may be i am wrong, i just want to be sure. I am new in spi programming.

With the following line you told the arduino to start transmitting with the MSB first. In your case the A1 bit.
Code: [Select]
SPI.setBitOrder(MSBFIRST);
Below you see a table that visualizes the states of the shift-register bits and the CLK and SDI lines, when the following code is executed.
Code: [Select]
SPI.transfer(dacPrimarybyte);
Bit-BucketA1A0D11D10D09D08D07D06D05D04D03D02D01D00CLKSDI
xxxxxxxxxxxxxxxLOWA1
xxxxxxxxxxxxxxA1HIGHA1
xxxxxxxxxxxxxA1 xLOWA0
xxxxxxxxxxxxxA1A0HIGHA0
xxxxxxxxxxxxA1A0xLOWD11
xxxxxxxxxxxxA1A0D11HIGHD11
xxxxxxxxxxxA1A0D11xLOWD10
xxxxxxxxxxxA1A0D11D10HIGHD10
xxxxxxxxxxA1A0D11D10xLOWD09
xxxxxxxxxxA1A0D11D10D09HIGHD09
xxxxxxxxxA1A0D11D10D09xLOWD08
xxxxxxxxxA1A0D11D10D09D08HIGHD08
xxxxxxxxA1A0D11D10D09D08xLOWD07
xxxxxxxxA1A0D11D10D09D08D07HIGHD07
xxxxxxxA1A0D11D10D09D08D07xLOWD06
xxxxxxxA1A0D11D10D09D08D07D06HIGHD06

Btw, the Bit-Bucket does not really exist, but it is a good way to visualize it as a sort of trashcan where all the obsolete bits end their life.

I'll leave as an exercise for the reader to figure out what happens when the following line of code is executed:
Code: [Select]
SPI.transfer(dacSecondarybyte)
« Last Edit: March 27, 2015, 05:48:13 am by sunnyhighway »
 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #6 on: March 27, 2015, 10:36:37 am »
hey..Thank you for your help.
I did the excercise and now i understand how the Bits are shifted into the Register. My Programm is also working very well.
for example when i call the function readDac(4095,0), i get like expected 4.95 V at Output A.
 Thank you very much for your help!!!  :-+

I am now going to work on the  Programm of my ADC(AD7921) also wiht arduino due.
here is the Datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/AD7911_7921.pdf

Please if you have time, i will be pleased to be helped.



 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #7 on: March 27, 2015, 10:38:16 am »
sorry I wrote 4.95V, but it is 4.095V :)
 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #8 on: March 27, 2015, 12:08:24 pm »
I wrote the actually code, but something is wrong in my Programm:

#include <SPI.h>

int cs = 8;

void setup(){
  SPI.begin();
  pinMode(cs, OUTPUT);                     
  digitalWrite(cs, HIGH);                                             
  SPI.setDataMode(SPI_MODE2);             
  SPI.setClockDivider(cs,21);             
  SPI.setBitOrder(MSBFIRST);               
  Serial.begin(9600);
}

void loop()
{
  int adcWert0;
  int adcWert1;
 
  adcWert1 = readAdc(1);
  delayMicroseconds(20);
  adcWert0 = readAdc(0);
}
 
 int readAdc(int channel)
 {
   int adcValue;
   byte adcPrimaryByteMask;
   byte adcPrimaryRegister;
   byte adcPrimarybyte;
   byte adcSecondarybyte;
   
   //adcPrimaryByteMask=0x2F;
   adcPrimaryRegister=channel<<5;
   
   digitalWrite(cs, LOW);
   adcPrimarybyte = SPI.transfer(adcPrimaryRegister); 
   adcSecondarybyte = SPI.transfer(0x00);
   digitalWrite(cs, HIGH); 
   //adcPrimarybyte &= adcPrimaryByteMask;
   adcValue = (adcPrimarybyte <<8 )|adcSecondarybyte;
   return adcValue;   
 }
 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #9 on: March 30, 2015, 03:12:01 pm »
Hey.

I changed the device. now i am using the AD7911. That means the result will look like this: 00chx10bits00; the 10 bits represent the result of my convertion. The convertion is working very well. I Thing the Problem was not my Programm, but rather the AD7921 was already broken.

 now I have a Problem with the compilation. I get with the Oscilloscope the result like expected (you can see it in attachment), but with Serial.print i get another result, which is wrong.

here is my code:


#include <SPI.h>

int cs = 8;

void setup(){
  SPI.begin();                             
  SPI.setDataMode(SPI_MODE2);             
  SPI.setClockDivider(cs,21);             
  SPI.setBitOrder(MSBFIRST);
  pinMode(cs, OUTPUT);                   
  digitalWrite(cs, HIGH);                               
  Serial.begin(9600);
}

void loop()
{
  int adcWert1 = readAdc(1);
Serial.println(adcwert1);// this Shows mee a result, which is different from the result shown by the Oscilloscope
  delayMicroseconds(50);
  int adcWert0 = readAdc(0);
  //delay(1);
 }

In the Attachement you can see the result of 5v convertion on both channels.

 int readAdc(int channel)
 {
   byte adcPrimarybyte=0;
   byte adcSecondarybyte=0;
   byte adcPrimaryByteMask=00101111;
   byte adcPrimaryRegister=channel<<5;
   digitalWrite(cs, LOW); 
   adcPrimarybyte = SPI.transfer(adcPrimaryRegister);
   //Serial.println(adcPrimarybyte);
   adcSecondarybyte = SPI.transfer(0x00);   
   digitalWrite(cs, HIGH);
   adcPrimarybyte &= adcPrimaryByteMask;
   int adcPrimarybyte1 = adcPrimarybyte << 8;
   int adcValue = adcPrimarybyte1|adcSecondarybyte;
   Serial.println(adcValue);
   return adcValue;
 }
 

Offline sunnyhighway

  • Frequent Contributor
  • **
  • Posts: 276
  • Country: nl
Re: DAC 7612..With arduino due
« Reply #10 on: March 31, 2015, 04:52:16 am »
First of all, what are you trying to do here?
Code: [Select]
byte adcPrimaryByteMask=00101111;
The way you wrote it, you assign the decimal value 00101111 to the variable adcPrimaryByteMask.

adcPrimaryByteMask can only contain 8 bits, while you want to assign it the 32 bit binary value 0000 0000 0000 0001 1000 1010 1111 0111
That is hex 0x00018AF7
 

Offline brendanTopic starter

  • Contributor
  • Posts: 15
Re: DAC 7612..With arduino due
« Reply #11 on: March 31, 2015, 04:33:26 pm »
hey.

sorry it was a mistake. I dont Need this line in my Programm. I still have the same Problem in my code. the result of the oscilloskope is right, but with Serial.print(adcValue) i always get 65535, Independent of the Value on Vin0 and Vin1
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf