I have a MAX5724 8 channel 10 bit DAC's connected to a due, i believe i have it wired up correctly, however when i try to write a value to it doesn't seem to output anything. Either i misunderstood the datasheet in the wiring or im writing incorrectly to it. Since i have the LDAC connected to GND i think i can just use the CODEn command on page 21 of the datasheet.
On a Due the SPI pins are not on the same pins as the other Arduinos.
You can only get them on the ICSP header.
You can of course bit bang the signals on what ever pins you want but that will mean different software.
I have a MAX5724 8 channel 10 bit DAC's connected to a due, i believe i have it wired up correctly
WARNING: Pin 11 needs to be 3.3V - the Due is a 3.3V board, it's I/O cannot tolerate anything beyond 3.9V.
Your SCLK Frequency is too high (28MHz) - see pg7.
Try 4MHz until you get it working. Then you could ramp it up to 8, 10.5 or 21MHz depending on the strobing method.
The default SPI mode for Arduino is mode 0, so you could use this:
Ok changed the pin 11 to the 3.3V of the arduino and SPI.setClockDivider to 4MHz, also have SPI.setDataMode on SPI_MODE0
I however cannot get the output to do anything it just seems to stay on its default value, currently using CODE_ALL LOAD_ALL (on page 22), with LDAC connected to GND and sending 1024 in binary with no luck have posted code used below.
To read, I believe you'll need to use the SPI0_RDR register. See page 685 in the SAM3X/A datasheet.
You may also need to check the status register first REG_SPI0_SR.
Do i need to read before i write? I just want to write to the DAC's outputs don't really care what they send back.
I am trying to change the output of the 8 channels. I assume with CODE_ALL LOAD_ALL (page 22 2nd in the table) it would change all 8 outputs to data being sent. Once i have the outputs changing i was going to change each channel individually. I am reading the output of each channel with an oscilloscope.
I however can't get the outputs to change at all, bit stumped at the moment. I thought with the code in my previous post above i would be able to change the outputs to 5V and the DAC would stay at 5V until i changed it to a different value, but they don't do anything and stay at default MZ.
The code above seems to work however it does not send correctly. The code below i expect would according to the data sheet code_all and load_all and all channels would change to 512 about half voltage.
But what seems to happen is the register ignores the first binary number in each msg and adds a 1 to the end of each msg so my output is doing code_n on channel 101 (channel 5) and setting it 0, code below is what is actually output (number in brackets at the end is what is oddly added and number in brackets at the start is what is ignored)
You sure of that? Because it would mean that you could not put more than one device on the SPI bus.
Yes. For the Due, the library takes full control of the CS line. There's no need to configure it or write to it separately, or this would create conflicts.
But what seems to happen is the register ignores the first binary number in each msg and adds a 1 to the end of each msg so my output is doing code_n on channel 101 (channel 5) and setting it 0, code below is what is actually output (number in brackets at the end is what is oddly added and number in brackets at the start is what is ignored)
This looks like you're getting close .. check that the starting levels for the CLK and other SPI signals make sense.
May just need to change the mode to SPI_MODE1. (this has same polarity but inverted phase as mode SPI_MODE0).
EDIT: I recommend using IDE version 1.5.8 as it has some improvements made with regards to SPI.
I got it working with this code thanks a lot for your help (tidied up the code a bit and made it generic)! Had to change the SPI MODE, i don't really understand why it works at SPI_MODE3 and why if i change the clock to about 20MHz, when the datsheet (page1) says it should work up to 50MHz.
Can i change the VDD (analog supply voltage) to 5V and the Vref to 5v, while leaving VDDIO (Digital Supply Voltage) to 3.3v, so i can out 5V and not damage my arduino due?
quick question i can only have 3 of these per arduino due right? On CS line 4,10,52?
#include <SPI.h>
#define CS_DAC1 52
void dacSetup (int CS)
{
SPI.begin(CS);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(CS, SPI_MODE3); //this is correct none of the others work
SPI.setClockDivider(CS, 21); // low to start with
}
void dacWrite (int CS, int value, int channel)
{
if (value > 1023)
{
value = 1023;
}
byte msg1 = (byte)channel;
msg1 = msg1 | B10000000;// CODEn + DAC selection (Page 21 MAX5724 datasheet)
byte msg3 = (byte)value;
byte msg2 = (byte)(value >> 2);
msg3 = msg3 & B00000011;
SPI.transfer(CS, msg1, SPI_CONTINUE);
SPI.transfer(CS, msg2, SPI_CONTINUE);
SPI.transfer(CS, msg3, SPI_LAST);
}
void setup()
{
dacSetup(CS_DAC1);
}
void loop()
{
static int channel = 2;
static int value = 0;
dacWrite(CS_DAC1, value, 0);
dacWrite(CS_DAC1, value, 1);
dacWrite(CS_DAC1, value, 2);
dacWrite(CS_DAC1, value, 3);
dacWrite(CS_DAC1, value, 4);
dacWrite(CS_DAC1, value, 5);
dacWrite(CS_DAC1, value, 6);
dacWrite(CS_DAC1, value, 7);
value += 100;
if (value > 1100)
{
value = 0;
}
delay(3);
}
Had to change the SPI MODE, i don't really understand why it works at SPI_MODE3...
I think the DAC would work in other modes, but the method for reading the data might be different (see pg 19).
... and why if i change the clock to about 20MHz, when the datsheet (page1) says it should work up to 50MHz.
Readback speeds are 12.5/25/50MHz depending on the details mentioned on pg19. I wouldn't trust much more than 4MHz while testing on a breadboard. For higher speed operation, the shorter the leads, the better - a PCB solution is best. Note that on the Due, 21MHz would be about the top speed, however I think I've read somewhere about a memory interface with test results @ 42MHz when using SPI with DMA.
Can i change the VDD (analog supply voltage) to 5V and the Vref to 5v, while leaving VDDIO (Digital Supply Voltage) to 3.3v, so i can out 5V and not damage my arduino due?
This looks possible (see pg32) as long as OUT0-7 are not directly connected to the Due.
quick question i can only have 3 of these per arduino due right? On CS line 4,10,52?
You should be able to extend this to more than three by using an appropriate analog switch IC (or similar).
I know, it has been some time since the last post in this topic, but I had to use the MAX5725(wich is just the 12-bit version of the 5724) an figured out how to do that. Maybe some one out there is still looking for some working code!
I just had 8bit Iformation to shift out thouth the DACs so the functions i wrote just handle bytes.
So here we go:
SPISettings SettingsMAX( 16000000, MSBFIRST, SPI_MODE1);
//write a a byte value to any DAC from 0 to 7, 8 will write to all DACs
void writeMAX5725 (byte value, byte dac_channel)
{
if (value > 255)
{
value = 255;
}
byte msg[3];
msg[0] = B10110000 |dac_channel;// CODEn&LOADn + DAC selection (Page 21 MAX5725 datasheet)
msg[1] = value;
msg[2] = 0;
digitalWrite(SS_MAX5725,HIGH);
asm("nop\n"); // delay of one operation ( I think this is 62.5ns; 20ns needed)
digitalWrite(SS_MAX5725, LOW);
SPI.beginTransaction(SettingsMAX);
SPI.transfer(msg[0]);
SPI.transfer(msg[1]);
SPI.transfer(msg[2]);
SPI.endTransaction();
}
void setupMAX5725()
{
//get all pins ready
digitalWrite(SS_MAX5725, LOW);
digitalWrite(13, LOW); // CLK pin
digitalWrite(11, LOW); // MOSI pin
byte msg[3] = {0};
msg[0] = B00100101 ;// set the internal REF to 2,5V Change last 2 bit to "11" for 4.1V or "10" for 2V
msg[1] = B00000000;
msg[2] = B00000000;
digitalWrite(SS_MAX5725,HIGH);
asm("nop\n"); // dealy of one operation ( i think this is 62.5ns; 20ns needed)
digitalWrite(SS_MAX5725, LOW);
SPI.beginTransaction(SettingsMAX);
SPI.transfer(msg[0]);
SPI.transfer(msg[1]);
SPI.transfer(msg[2]);
SPI.endTransaction();
delay(2); // just to be safe
}
PIN SETUP for an Arduino UNO/NANO:
MAX5725:
1: / ( check here for right REF voltage)
2-9: DAC OUT 0-7
10: 5V ( or any other possible Vcc)
11: 5V (for me, can be different 3.3V is typical too)
12: / ( i dont need to read back anything)
13: connect to pin 11 ( MOSI)
14: connect to pin 13 (CLK)
15: connect to the SalveSelect pin (choose one)
16: / ( i dont need timeout interupst)
17: connect to VCCIO or any pin witch is HIGH (LOW causes to clear all DAC OUTs.Iif this is unconected nothing will happen!!!)
18: connect to VCC
19: connect to GND
20: connect to GND
Additionaly I used a smal Cap of 100nF between GND and 5V. That helps to supply all the devices with enough current for fast rising an falling times!
Also given the DAC works at 3.3V, I'd have initially used 3.3V supply for it rather than
risk over-voltage death for the expensive Due while testing stuff. Its really not happy with
5V on any pin.