DAC 7612..With arduino due - Page 1
Forum section: electronics / general

author: brendan
author_rank: Contributor
timestamp: March 26, 2015, 04:01:48 pm
content: 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.pdfhere 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: //AdacPrimarybyte |=0b10000000;break;case 1: //BdacPrimarybyte |=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

author: brendan
author_rank: Contributor
timestamp: March 26, 2015, 04:10:41 pm
content: 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

author: PeterFW
author_rank: Frequent Contributor
timestamp: March 26, 2015, 05:27:46 pm
content: 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 LOADDACSafteryou 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.

author: sunnyhighway
author_rank: Frequent Contributor
timestamp: March 26, 2015, 08:16:35 pm
content: I can see only one problem that keeps the code from functioning properly.The DAC expects only14bits coming into the shift register. MSB first and LSB last.The problem is that with the following two line you push16bits into the shift register.Code: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:int dacSecondaryMask = 0b0000000011111111;byte dacPrimarybyte = value >> 8; // Drop the 8 LSB'sbyte 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 0bxx100000dacPrimarybyte |= 0b00100000; // A1 = 1, A0 = 0break;case 1://B 0bxx110000dacPrimarybyte |= 0b00110000; // A1 = 1, A0 = 1break;}edit:fixed typo.

author: brendan
author_rank: Contributor
timestamp: March 26, 2015, 10:17:28 pm
content: 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.

author: sunnyhighway
author_rank: Frequent Contributor
timestamp: March 26, 2015, 11:36:29 pm
content: Quote from: brendan on March 26, 2015, 10:17:28 pmWith the following line you told the arduino to start transmitting with the MSB first. In your case the A1 bit.Code: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:SPI.transfer(dacPrimarybyte);Bit-BucketA1A0D11D10D09D08D07D06D05D04D03D02D01D00CLKSDIxxxxxxxxxxxxxxxLOWA1xxxxxxxxxxxxxxA1HIGHA1xxxxxxxxxxxxxA1xLOWA0xxxxxxxxxxxxxA1A0HIGHA0xxxxxxxxxxxxA1A0xLOWD11xxxxxxxxxxxxA1A0D11HIGHD11xxxxxxxxxxxA1A0D11xLOWD10xxxxxxxxxxxA1A0D11D10HIGHD10xxxxxxxxxxA1A0D11D10xLOWD09xxxxxxxxxxA1A0D11D10D09HIGHD09xxxxxxxxxA1A0D11D10D09xLOWD08xxxxxxxxxA1A0D11D10D09D08HIGHD08xxxxxxxxA1A0D11D10D09D08xLOWD07xxxxxxxxA1A0D11D10D09D08D07HIGHD07xxxxxxxA1A0D11D10D09D08D07xLOWD06xxxxxxxA1A0D11D10D09D08D07D06HIGHD06Btw, 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:SPI.transfer(dacSecondarybyte)

author: brendan
author_rank: Contributor
timestamp: March 27, 2015, 10:36:37 am
content: 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.pdfPlease if you have time, i will be pleased to be helped.

author: brendan
author_rank: Contributor
timestamp: March 27, 2015, 10:38:16 am
content: sorry I wrote 4.95V, but it is 4.095V

author: brendan
author_rank: Contributor
timestamp: March 27, 2015, 12:08:24 pm
content: 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;}

author: brendan
author_rank: Contributor
timestamp: March 30, 2015, 03:12:01 pm
content: 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 OscilloscopedelayMicroseconds(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;}

author: sunnyhighway
author_rank: Frequent Contributor
timestamp: March 31, 2015, 04:52:16 am
content: First of all, what are you trying to do here?Code: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 0111That is hex 0x00018AF7

author: brendan
author_rank: Contributor
timestamp: March 31, 2015, 04:33:26 pm
content: 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