Library for DAC855X Digital to Analogic converters by Texas Instruments

So let's list the differences between them:
8550 ==> has only the power down of bits 17 and 16 (possibilities: 0x00 [normal], 0x01 [1kOhm], 0x10 [100kOhm] and 0x11 [hi-Z])
8551 ==> looks identical to the 8550.
8552 ==> described above.
8554 and 8555 (yes, one more!) ==> appear to be identical. Addressing is a bit trickier, but I'll try to do it.

Rob, could you please clarify the utility of power down and buffer?

I didn't read the datasheets - that takes a few hours.

Powerdown
From the schema in the start of the datasheet (and its name) powerdown seems to disconnect the DAC from the output and so effectively disable the signal. When switched on I expect it will have the original voltage again (or it must be overwritten). I expect the Vout will be connected to ground GND.

Buffer
Don't know. Could be a way to set all DAC's at the very same time. First write into all buffers (multiple commands) and then put them in the registers with a single command.

By my experiments here, bits 20 and 21 command to update the value in "memories" A and B, respectively. Bit 18 releases the value present in memory A (0) and B (1) for the respective output. Therefore, if we want the value to be directed to channel A, we must use the address 0x10 (updates A and releases A). For channel B, we will use the address 0x24 (refresh B and release B). I'll do it without power down.

I made a flowchart (attached) about the basic operation of the library, discarding the use of power down. Now it's programming!
(Thanks for the explanations, Rob! When you come to Brazil, visit Patos de Minas, Minas Gerais, and try our pão de queijo ("cheese bread"))

Fluxograma.pdf (26.1 KB)

Here how I make:

DAC855X.h

/*************************************************************************
**  Device: DAC855X                                                 	**
**  File:   DAC855X.h - Library for DACs of TI							**
*************************************************************************/
#ifndef DAC855X_h
#define DAC855X_h

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

class DAC855X
{
  public:
    DAC855X();    
    void setPinsChip(uint8_t DIN, uint8_t SCK, uint8_t SYNC, uint8_t CHIPX);
	void setChanValue(uint8_t chan, uint16_t value);
	void initializeDAC855X();
	
  private:
    uint8_t _DIN;
    uint8_t _SCK;
    uint8_t _SYNC;
	uint8_t _CHIPX;
};
#endif

DAC855X.ccp

/*************************************************************************
**  Device: DAC855X                                                 	**
**  File:   DAC855X.h - Library for DAC855X of TI                    	**
**************************************************************************/
#include "DAC855X.h"
#include "SPI.h"

DAC855X::DAC855X(){
}
void DAC855X::setPinsChip(uint8_t DIN, uint8_t SCK, uint8_t SYNC, uint8_t CHIPX){
_DIN = DIN;
_SCK = SCK;
_SYNC = SYNC;
pinMode(_DIN,OUTPUT);
pinMode(_SCK,OUTPUT);
pinMode(_SYNC,OUTPUT);
int header;
}

void DAC855X::initializeDAC855X(){
	Serial.begin(9600);
  // initialize pins:
 
  digitalWrite(_SYNC, HIGH); 
  delay(1);
  SPI.begin();// initialize SPI
  delay(1);
  SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE1));
  delay(100);
}
void DAC8552::setChanValue(uint8_t chan, int value) {
	//Choose of chips and channels - define the header byte
	switch(CHIPX){
	case 0: //DAC8550 and 8551
		header = 0x00;
		break;
	case 1: //DAC8552
		switch(chan){
			case 0: //Channel A
				header = 0x10;
			break;
			case 1: //Channel B
				header = 0x24;
			break;
			default:
				Serial.println("Wrong channel for DAC8552. Choose 0, 1. Using default = 0");
				header = 0x10;
		}
	break;
	case 2: //DAC8554 and 8555
		switch(chan){
			case 0: //Channel A
				header = 0x00;
				break;
			case 1: //Channel B
				header = 0x04;
				break;
			case 2: //Channel C
				header = 0x08;
				break;
			case 3: //Channel D
				header = 0x0C;
				break;
			default:
				Serial.println("Wrong channel for DAC8554. Choose 0, 1, 2 or 3. Using default = 0");
				header = 0x00;
		}
	break;
	default:
		Serial.println("Wrong DAC. Choose 0, 1 or 2");
	}
  digitalWrite(_SYNC, LOW); //Turn on the transfer
  byte hiByte = highByte(value); //Divides the integer into two bytes
  byte loByte = lowByte(value);
  SPI.transfer(header); //Transfer configuration byte
  SPI.transfer(hiByte); //Transfer data bytes 15 to 8
  SPI.transfer(loByte); //Transfer data bytes 7 to 0
  digitalWrite(_SYNC, HIGH); //Turn off the transfer
}

Example:

#include <DAC855X.h>
DAC855X dac;

void setup() {
  dac.setPinsChip(11, 13, 10, 1);
  dac.initializeDAC855X();

}

void loop() {
  dac.setChanValue(0, 23456);
  int ChA = analogRead(0);
  delay(10);
  Serial.print("Channel A = ");
  Serial.print(ChA);
  dac.setChanValue(1, 456);
  delay(10);
  int ChB = analogRead(0);
  Serial.print("\t Channel B =");
  Serial.println(ChB);
  delay(1000);
}

Error compiling:

Arduino: 1.8.5 (Windows 10), Placa:"Arduino/Genuino Uno"

C:\Users\RENATO~1\AppData\Local\Temp\ccpxKWG4.ltrans0.ltrans.o: In function `__static_initialization_and_destruction_0':

C:\Users\Renato Ianhez\Documents\Arduino\DAC\TesteDAC\TesteDAC1/TesteDAC1.ino:2: undefined reference to `DAC855X::DAC855X()'

C:\Users\RENATO~1\AppData\Local\Temp\ccpxKWG4.ltrans0.ltrans.o: In function `setup':

C:\Users\Renato Ianhez\Documents\Arduino\DAC\TesteDAC\TesteDAC1/TesteDAC1.ino:5: undefined reference to `DAC855X::setPinsChip(unsigned char, unsigned char, unsigned char, unsigned char)'

C:\Users\Renato Ianhez\Documents\Arduino\DAC\TesteDAC\TesteDAC1/TesteDAC1.ino:6: undefined reference to `DAC855X::initializeDAC855X()'

C:\Users\RENATO~1\AppData\Local\Temp\ccpxKWG4.ltrans0.ltrans.o: In function `loop':

C:\Users\Renato Ianhez\Documents\Arduino\DAC\TesteDAC\TesteDAC1/TesteDAC1.ino:11: undefined reference to `DAC855X::setChanValue(unsigned char, unsigned int)'

C:\Users\Renato Ianhez\Documents\Arduino\DAC\TesteDAC\TesteDAC1/TesteDAC1.ino:16: undefined reference to `DAC855X::setChanValue(unsigned char, unsigned int)'

collect2.exe: error: ld returned 1 exit status

exit status 1
Erro compilando para a placa Arduino/Genuino Uno

Este relatório teria mais informações com
"Mostrar a saida detalhada durante a compilação"
opção pode ser ativada em "Arquivo -> Preferências"

I spent the afternoon today trying to find the cause of this error ...

Primary error: not ".ccp" but ".cpp"!
Continuing with other errors, I will try to fix them before posting the code again!

Here the codes:

DAC855X.h

/*************************************************************************
** Library for Digital to Analogic Converters by Texas Instruments      **
** DAC8550, DAC8551, DAC8552, DAC8554, DAC8555 on Arduino.              **
**                                                                      **
*************************************************************************/
#ifndef DAC855X_H
	#define DAC855X_H

		#include "Arduino.h"
		#include "SPI.h"

			class DAC855X
			{
				public:
					DAC855X();
					void setPinsChip(int DIN, int SCK, int SYNC, int CHIPX);
					void setChanValue(int chan, int value);
					void initializeDAC855X();

				private:
					int _DIN;
					int _SCK;
					int _SYNC;
					int _CHIPX;
			};
#endif

DAC855X.cpp

/*************************************************************************
**  Device: DAC855X                                                 	**
**  File:   DAC855X.h - Library for DAC855X of TI                    	**
**************************************************************************/
#include "DAC855X.h"

DAC855X::DAC855X() {
}
void DAC855X::setPinsChip(int DIN, int SCK, int SYNC, int CHIPX) {
	_DIN = DIN;
	_SCK = SCK;
	_SYNC = SYNC;
	pinMode(_DIN,OUTPUT);
	pinMode(_SCK,OUTPUT);
	pinMode(_SYNC,OUTPUT);
	
}

void DAC855X::initializeDAC855X() {
	Serial.begin(9600);
	// initialize pins:
	digitalWrite(_SYNC, HIGH);
	delay(1);
	SPI.begin();// initialize SPI
	delay(1);
	SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE1));
	delay(100);
}
void DAC855X::setChanValue(int chan, int value) {
	int header;
	//Choose of chips and channels - define the header byte
	switch(CHIPX) {
		case 0: //DAC8550 and 8551
			header = 0x00;
			break;
		case 1: //DAC8552
			switch(chan) {
				case 0: //Channel A
					header = 0x10;
					break;
				case 1: //Channel B
					header = 0x24;
					break;
				default:
					Serial.println("Wrong channel for DAC8552. Choose 0, 1. Using default = 0");
					header = 0x10;
			}
			break;
		case 2: //DAC8554 and 8555
			switch(chan) {
				case 0: //Channel A
					header = 0x00;
					break;
				case 1: //Channel B
					header = 0x04;
					break;
				case 2: //Channel C
					header = 0x08;
					break;
				case 3: //Channel D
					header = 0x0C;
					break;
				default:
					Serial.println("Wrong channel for DAC8554. Choose 0, 1, 2 or 3. Using default = 0");
					header = 0x00;
			}
			break;
		default:
			Serial.println("Wrong DAC. Choose 0, 1 or 2");
	}
	digitalWrite(_SYNC, LOW); //Turn on the transfer
	byte hiByte = highByte(value); //Divides the integer into two bytes
	byte loByte = lowByte(value);
	SPI.transfer(header); //Transfer configuration byte
	SPI.transfer(hiByte); //Transfer data bytes 15 to 8
	SPI.transfer(loByte); //Transfer data bytes 7 to 0
	digitalWrite(_SYNC, HIGH); //Turn off the transfer
}

The example:

#include <DAC855X.h>

DAC855X dac = DAC855X();
dac.setPinsChip(11, 13, 10, 1);
dac.initializeDAC855X();

void setup() {

}

void loop() {

  dac.setChanValue(0, 23456);
  int ChA = analogRead(0);
  delay(10);
  Serial.print("Channel A = ");
  Serial.print(ChA);
  dac.setChanValue(1, 456);
  delay(10);
  int ChB = analogRead(0);
  Serial.print("\t Channel B =");
  Serial.println(ChB);
  delay(1000);
}

And the error:

Arduino: 1.8.5 (Windows 10), Placa:"Arduino/Genuino Uno"

TesteDAC1:4: error: 'dac' does not name a type

 dac.setPinsChip(11, 13, 10, 1);

 ^

TesteDAC1:5: error: 'dac' does not name a type

 dac.initializeDAC855X();

 ^

exit status 1
'dac' does not name a type

Este relatório teria mais informações com
"Mostrar a saida detalhada durante a compilação"
opção pode ser ativada em "Arquivo -> Preferências"

I could not find where my error is for "'dac' does not name a type" ...

Too much Christmas activities :slight_smile: I will have a look later today.

This sketch compiles, but the tension is 0 V on both channels... I have not figured out what I did wrong.

#include <DAC855X.h>

DAC855X dac;

void setup() {
  dac.setPinsChip(11, 13, 10, 1);
  dac.initializeDAC855X();
}

void loop() {
  dac.setChanValue(0, 23456);
  int ChA = analogRead(0);
  delay(10);
  Serial.print("Channel A = ");
  Serial.print(ChA);
  dac.setChanValue(1, 456);
  delay(10);
  int ChB = analogRead(0);
  Serial.print("\t Channel B = ");
  Serial.println(ChB);
  delay(1000);
}

I got it! I did a program to generate a sawtooth wave on channel A and a sine wave on channel B! Here goes the codes. I am already creating a repository in Github.

DAC855X.h

/*************************************************************************
** Library for Digital to Analogic Converters by Texas Instruments      **
** DAC8550, DAC8551, DAC8552, DAC8554, DAC8555 on Arduino.              **
** By Renato Ianhez                                                     **
*************************************************************************/
#ifndef DAC855X_H
#define DAC855X_H

	#include "Arduino.h"
	#include "SPI.h"

		class DAC855X
		{
			public:
				DAC855X();
				void setPins(int DIN, int SCK, int SYNC);
				void setChipChanValue(int CHIPX, int chan, int value);
				void initializeDAC855X();

			private:
				int _DIN;
				int _SCK;
				int _SYNC;
				
		};
#endif

DAC855X.cpp

/*************************************************************************
** Library for Digital to Analogic Converters by Texas Instruments      **
** DAC8550, DAC8551, DAC8552, DAC8554, DAC8555 on Arduino.              **
** By Renato Ianhez                                                     **
*************************************************************************/
#include "DAC855X.h"

DAC855X::DAC855X() {
}
void DAC855X::setPins(int DIN, int SCK, int SYNC) {
	_DIN = DIN;
	_SCK = SCK;
	_SYNC = SYNC;
	pinMode(_DIN,OUTPUT);
	pinMode(_SCK,OUTPUT);
	pinMode(_SYNC,OUTPUT);
	
}

void DAC855X::initializeDAC855X() {
	Serial.begin(9600);
	// initialize pins:
	digitalWrite(_SYNC, HIGH);
	delay(1);
	SPI.begin();// initialize SPI
	delay(1);
	SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE1));
	delay(100);
}
void DAC855X::setChipChanValue(int CHIPX, int chan, int value) {
	int header;
	//Choose of chips and channels - define the header byte
	switch(CHIPX) {
		case 0: //DAC8550 and 8551
			header = 0x00;
			break;
		case 1: //DAC8552
			switch(chan) {
				case 0: //Channel A
					header = 0x10;
					break;
				case 1: //Channel B
					header = 0x24;
					break;
				default:
					Serial.println("Wrong channel for DAC8552. Choose 0, 1. Using default = 0");
					header = 0x10;
			}
			break;
		case 2: //DAC8554 and 8555
			switch(chan) {
				case 0: //Channel A
					header = 0x00;
					break;
				case 1: //Channel B
					header = 0x04;
					break;
				case 2: //Channel C
					header = 0x08;
					break;
				case 3: //Channel D
					header = 0x0C;
					break;
				default:
					Serial.println("Wrong channel for DAC8554. Choose 0, 1, 2 or 3. Using default = 0");
					header = 0x00;
			}
			break;
		default:
			Serial.println("Wrong DAC. Choose 0, 1 or 2");
	}
	digitalWrite(_SYNC, LOW); //Turn on the transfer
	byte hiByte = highByte(value); //Divides the integer into two bytes
	byte loByte = lowByte(value);
	SPI.transfer(header); //Transfer configuration byte
	SPI.transfer(hiByte); //Transfer data bytes 15 to 8
	SPI.transfer(loByte); //Transfer data bytes 7 to 0
	digitalWrite(_SYNC, HIGH); //Turn off the transfer
}

Example

//This program exemplifies the use 
//of the library on a Texas Instruments 
//DAC8552 2-channel chip. Channel A 
//will make a saw tooth wave, and 
//channel B will make a sine wave, sumultaneously.

#include <DAC855X.h>

DAC855X dac;

const float radian = 0.000488281F;
uint32_t sen;
float numpi = 0.0;

void setup() {
  dac.setPins(11, 13, 10);
  dac.initializeDAC855X();
}

void loop() {
  for (int i=1; i<4096; i=i+4){
    int dacA = i*16; // Channel A shows the sawtooth wave
    dac.setChipChanValue(1, 0, dacA); // DAC8552 chip, channel A
    int ChA = analogRead(0);
    delay(10);
    Serial.print("Channel A = ");
    Serial.print(ChA);
    numpi = PI*radian*i; //Channel B shows the sinewave
    int dacB = (1+(sin(numpi)))*32768;
    dac.setChipChanValue(1, 1, dacB); // DAC8552 chip, channel B
    delay(10);
    int ChB = analogRead(1);
    Serial.print("\t Channel B = ");
    Serial.println(ChB);
    delay(100);
  }  
}

A quick look pointed me to this line

--> dac.setPinsChip(11, 13, 10, 1);

CHIPX is set to 1 (as parameter) but it is not remembered (= internal copy) by the dac object.
So the setChanValue() uses an uninitialized var

furthermote the assigned SPI pins are not used...(they just happen to be the same)

The library and example are now in GitHub!
There is also a small user manual in Readme.

Thanks, Rob! It was a great learning experience!

You're right. This is what made it not work! So in the last version I put the choice of the chip along with the channels and the value of the DAC. Then it worked perfectly. Thank you!

Reading through the datasheets of the 4 devices, they look alike but differ just too much in the details to make one superclass immediately. Only the 8550 and 8551 are compatble, so we will end up with three classes. Maybe merge them later.

I will keep the interfaces similar so switching is not difficult. Time to write some code.

Avoid the power down, It seems with correct headers...

Published an experimental version of my DAC8552 library on Github.

The 8552 library is MINIMAL tested as I do not have the sensors. The 5 demo sketches cover most of the functionality of the library and they compile for Arduino UNO.

Also published an experimental version of my DAC8551 library

The 8551 library is NOT tested, for the same reason. The 3 demo sketches compile for Arduino UNO.

Test volunteers are welcome, just like remarks and comments.

Also published an experimental version of my DAC8554 library

The 8554 library is NOT tested, for the same reason as above.
The demo sketches compile for Arduino UNO.

Test volunteers are welcome, just like remarks and comments.