Hallo guys i am controlling my DAC MAX5217 with i2c and it has the address ( 0x1D ) i used the i2c scanner for that. and two rotary enocders to control from 0 to 5V.
Unfourtantly i am not getting error messages in the code but i dont get 5V out of my DAC . i get nothing ( measured with multimeter ), what am doing wrong in my code? i already did the same thing for MCP4725 and it worked out. i just wanted to have better resolution and accuracy.
The connection are also correct am pretty sure its software thing.
here is my code:
#include <Wire.h>
#define MAX5217 0x1D
// Rotary knob state
volatile int old_state = 0;
volatile int state = 0;
// Value to send to DAC
volatile int value = 0;
volatile int new_value = 65000;
// Used to limit the frequency of timer updates to 30 times per sec
int old_time = 0;
// Interrupt handler for rotary encoder
ISR(PCINT2_vect) {
state = PIND;
int changes = state ^ old_state;
// If bit 2, update the value
if (bitRead(changes, 2)) {
if (bitRead(state, 2) ^ bitRead(old_state, 3)) {
new_value++;
} else {
new_value--;
}
}
// If bit 4, update the value with a coarse resolution
if (bitRead(changes, 4)) {
if (bitRead(state, 4) ^ bitRead(old_state, 5)) {
new_value += 8;
} else {
new_value -= 8;
}
}
// Store the state to compare against next time
old_state = state;
}
void setup(void) {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
Wire.begin(0x1D);
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(4, INPUT);
digitalWrite(4, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
noInterrupts();
// Pin change interrupt control register
PCICR |= 0b100;
// Pin change mask registers decide which pins are enabled as triggers
PCMSK2 |= (_BV(PCINT18) | _BV(PCINT19) | _BV(PCINT20) | _BV(PCINT21));
interrupts();
}
void loop(void) {
float dac_expected_output;
int time = millis();
// Limit frequency of timer updates to 30 per second
if (time - old_time < 33) {
return;
}
old_time = time;
if (value != new_value) {
digitalWrite(13, HIGH);
delay(10);
digitalWrite(13, LOW);
delay(10);
value = new_value;
dac_expected_output = (5.0/65000.0) * value;
if (value > 65000) {
new_value = value = 65000;
}
if (value < 8) {
new_value = value = 8;
}
}
}
With the first part you mentioned you are right cause it was 4096 when i was using the 12 bit dac and i changed the number only.
and i just noticed that in the end of the code i had before the function dac.setvoltage(value, False).
and i have to replace that one now for the 16 bit and i dont really know how cause that function was linked with a library. and the max5217 has no library. Do you have any idea for this?
Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Did you google MAX5217 arduino
If you freeze a frame in this YouTube you can see the short bit of code used.
Hi Tom sorry for the code thing i will try to edit it.
Yes i googled and i saw the link you posted but the guy dont provide any code or anything the video wasnt so good. I saw ur comment also i appreciate the help!! but i cant link my code on his .. it seems that the loop is too short and am complicating it .
it's hard that i take picture of the circuit now but i can tell you the 8 connections of my DAC.
REF connected to external 5v Ref Chip
ADDR to GND
SDA To SDA
SCL To SCL
#include <Wire.h>
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
// Rotary knob state
volatile int old_state = 0;
volatile int state = 0;
// Value to send to DAC
volatile int value = 0;
volatile int new_value = 4095;
// Used to limit the frequency of timer updates to 30 times per sec
int old_time = 0;
// Interrupt handler for rotary encoder
ISR(PCINT2_vect) {
state = PIND;
int changes = state ^ old_state;
// If bit 2, update the value
if (bitRead(changes, 2)) {
if (bitRead(state, 2) ^ bitRead(old_state, 3)) {
new_value++;
} else {
new_value--;
}
}
// If bit 4, update the value with a coarse resolution
if (bitRead(changes, 4)) {
if (bitRead(state, 4) ^ bitRead(old_state, 5)) {
new_value += 8;
} else {
new_value -= 8;
}
}
// Store the state to compare against next time
old_state = state;
}
void setup(void) {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
dac.begin(0x60);
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(4, INPUT);
digitalWrite(4, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
noInterrupts();
// Pin change interrupt control register
PCICR |= 0b100;
// Pin change mask registers decide which pins are enabled as triggers
PCMSK2 |= (_BV(PCINT18) | _BV(PCINT19) | _BV(PCINT20) | _BV(PCINT21));
interrupts();
}
void loop(void) {
int time = millis();
// Limit frequency of timer updates to 30 per second
if (time - old_time < 33) {
return;
}
old_time = time;
if (value != new_value) {
digitalWrite(13, HIGH);
delay(10);
digitalWrite(13, LOW);
delay(10);
value = new_value;
if (value > 4095) {
new_value = value = 4095;
}
if (value < 8) {
new_value = value = 8;
}
dac.setVoltage(value, false);
}
}
Hi,
Does it work?
Have you got code just to make the DAC go up and down in cycles, forget the encoder etc etc.
Just the DAC.....
START with the basic code to prove I2C comms.
Have you tried the triangle example in the library examples?
You may try the following setup for quick functional check of MAX5217 DAC (untested due to lack of the DAC chip):
1. Build the following circuit between the UNO and the DAC. (AUX/ function is disabled.)
2. Connect a DVM at Out-pin of the DAC.
3. Upload the following sketch. Bring in the Serial Monitor at 9600 Baud.
#include <Wire.h>
void setup()
{
Serial.begin(9600);
Wire.begin();
pinMode(8, INPUT_PULLUP); //Dpin-8 is input with internal pull-up resistor
byte busStatus;
do
{
Wire.beginTransmission(0x1D); //checking the presence of DAC
busStatus = Wire.endTransmission();
}
while (busStatus !=0x00); //checking that DAc has aaccepted its address and has sent ACk signal
Serial.println(busStatus); //Serial Monitor should show 0
//--------------------------------
while(digitalRead(8) != LOW)
; //wait until K1 is closed
Wire.beginTransmission(0x1D); //address of DAC 0x1D
Wire.write(0x08); //pointing user configurable regsiter
Wire.write(0x00); //value for configurable register; AUX/ input is disabled
Wire.endTransmission(); //transfer all the above queued data to the ADC
//--------------------------------
Wire.beginTransmission(0x1D); //address of DAC
Wire.write(0x01); //address of command byte register/load code and load to DAC
Wire.write(0x7F); //upper 8-bit data for DAC
Wire.write(0xFF); //lower 8-bit data for DAC
Wire.endTransmission(); //transfer all the above queued data
}
void loop()
{
}
4. Check that 0 has appeared on the Serial Monitor.
5. Gently press the K1 switch.
6. Check that the DVM shows about 2.50V DC.
This is the end of simple functional check of the MAX5217 DAC.
GolamMostafa:
You may try the following setup for quick functional check of MAX5217 DAC (untested due to lack of the DAC chip):
1. Build the following circuit between the UNO and the DAC. (AUX/ function is disabled.)
2. Connect a DVM at Out-pin of the DAC.
3. Upload the following sketch. Bring in the Serial Monitor at 9600 Baud.
#include <Wire.h>
void setup()
{
Serial.begin(9600);
Wire.begin();
pinMode(8, INPUT_PULLUP); //Dpin-8 is input with internal pull-up resistor
byte busStatus;
do
{
Wire.beginTransmission(0x1D); //checking the presence of DAC
busStatus = Wire.endTransmission();
}
while (busStatus !=0x00); //checking that DAc has aaccepted its address and has sent ACk signal
Serial.println(busStatus); //Serial Monitor should show 0
//--------------------------------
while(digitalRead(8) != LOW)
; //wait until K1 is closed
Wire.beginTransmission(0x1D); //address of DAC 0x1D
Wire.write(0x08); //pointing user configurable regsiter
Wire.write(0x00); //value for configurable register; AUX/ input is disabled
Wire.endTransmission(); //transfer all the above queued data to the ADC
//--------------------------------
Wire.beginTransmission(0x1D); //address of DAC
Wire.write(0x01); //address of command byte register/load code and load to DAC
Wire.write(0x7F); //upper 8-bit data for DAC
Wire.write(0xFF); //lower 8-bit data for DAC
Wire.endTransmission(); //transfer all the above queued data
}
void loop()
{
}
**4.** Check that **0** has appeared on the Serial Monitor.
**5.** Gently press the K1 switch.
**6.** Check that the DVM shows about 2.50V DC.
This is the end of simple functional check of the MAX5217 DAC.
Thanks alot for your effort.
Till point 4 everything is working fine. I got the 0 on the Serial Monitor. But i didnt get the 2.5 on my DVM. i am still getting 0 Volt. i checked the pins VDD, Vref, SDA, SCL, AUX they all have almost 5V. and didnt connect anything to ADDR. GND is 0 and output is also 0.
Oh the switch i used was damaged now its producing the 2.5V Finally, i changed the switch button.
So Basically the MAX5217 is working :D. Now heading back to the main topic, is there any suggesstions?
1. When you have said that you have got 0 on the Serial Monitor (SM), I was observing Light upon Light in advance -- ; getting 0 on the SM is the proof that the MAX has accepted its address (0x1D) and has sent back the ACK (acknowledgement signal) to the Master.
2. Button K1 is added to give you some control on deciding the start of conversion of the DAC.
3. Check that the DAC works for some other values. For example: DAC upper 8-bit = 0x3F; DAC lower 8-bit = 0xFF; upload the new program and check that DVM reads about 1.25V. Try, using 0x00 and 0x00; DVM should read about 0V. Also try, using 0xFF and 0xFF; DVM should read about 5V.
GolamMostafa: 1. When you have said that you have got 0 on the Serial Monitor (SM), I was observing Light upon Light in advance -- ; getting 0 on the SM is the proof that the MAX has accepted its address (0x1D) and has sent back the ACK (acknowledgement signal) to the Master.
2. Button K1 is added to give you some control on deciding the start of conversion of the DAC.
3. Check that the DAC works for some other values. For example: DAC upper 8-bit = 0x3F; DAC lower 8-bit = 0xFF; upload the new program and check that DVM reads about 1.25V. Try, using 0x00 and 0x00; DVM should read about 0V. Also try, using 0xFF and 0xFF; DVM should read about 5V.
Have a nice time!
Thanks alot Man this is brilliant all are working
now atleast from one side i know its only Software to work on.
i will try to control this with two rotary encoders to adjust 0 .. 5V output voltage.
i think the best way to do this now is to modify my mcp4725 12bit Code with two rotary encoders i provided above to the max5217, what do you think?
It worked out now with the rotary encoders but with a bad resolution 0.04V instead of having 0,0000763 V For each step between 0 .. 65535 (0...5V).
it means am getting at step 1 : 0,04V
Step 2: 0,08 V
The right thing which it should be
Step 1: 0,0000763 V
Step 2: 0,00015259 V
Anyone know how to fix this problem now?
Here is the code:
#include <Wire.h>
// Rotary knob state
volatile unsigned int old_state = 0;
volatile unsigned int state = 0;
// Value to send to DAC
volatile unsigned int value = 0;
volatile unsigned int new_value = 65535;
// Used to limit the frequency of timer updates to 30 times per sec
int old_time = 0;
// Interrupt handler for rotary encoder
ISR(PCINT2_vect) {
state = PIND;
int changes = state ^ old_state;
// If bit 2, update the value
if (bitRead(changes, 2)) {
if (bitRead(state, 2) ^ bitRead(old_state, 3)) {
new_value++;
} else {
new_value--;
}
}
// If bit 4, update the value with a coarse resolution
if (bitRead(changes, 4)) {
if (bitRead(state, 4) ^ bitRead(old_state, 5)) {
new_value += 8;
} else {
new_value -= 8;
}
}
// Store the state to compare against next time
old_state = state;
}
void setup(void) {
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
Wire.begin();
Wire.beginTransmission(0x1D); //address of DAC 0x1D
Wire.write(0x08); //pointing user configurable regsiter
Wire.write(0x00); //value for configurable register; AUX/ input is disabled
Wire.endTransmission(); //transfer all the above queued data to the ADC
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(4, INPUT);
digitalWrite(4, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
noInterrupts();
// Pin change interrupt control register
PCICR |= 0b100;
// Pin change mask registers decide which pins are enabled as triggers
PCMSK2 |= (_BV(PCINT18) | _BV(PCINT19) | _BV(PCINT20) | _BV(PCINT21));
interrupts();
}
void loop(void) {
int time = millis();
// Limit frequency of timer updates to 30 per second
if (time - old_time < 33) {
return;
}
old_time = time;
if (value != new_value) {
digitalWrite(13, HIGH);
delay(10);
digitalWrite(13, LOW);
delay(10);
value = new_value;
if (value > 65535) {
new_value = value = 65535;
}
if (value < 8) {
new_value = value = 8;
}
Wire.beginTransmission(0x1D); //address of DAC
Wire.write(0x01); //address of command byte register/load code and load to DAC
Wire.write(value); //upper 8-bit data for DAC
Wire.write(value); //lower 8-bit data for DAC
Wire.endTransmission(); //transfer all the above queued data
Serial.println(value);
}
}
Wire.beginTransmission(0x1D); //address of DAC
Wire.write(0x01); //address of command byte register/load code and load to DAC
Wire.write(value); //upper 8-bit data for DAC
Wire.write(value); //lower 8-bit data for DAC
Wire.endTransmission(); //transfer all the above queued data
Something is not in the right way in the above instructions. (a)value is a 16-bit unsigned number (0x0000 - 0xFFFF). (b) Upper 8-bit of value should enter into the upper part of the DAC. Lower 8-bit of value should enter into lower 8-bit of DAC. So, the instructions should be:
Wire.beginTransmission(0x1D); //address of DAC
Wire.write(0x01); //address of command byte register/load code and load to DAC
Wire.write(highByte(value)); /upper 8-bit data for DAC
Wire.write(lowByte(value)); //lower 8-bit data for DAC
Wire.endTransmission(); //transfer all the above queued data
The above correction should also solve your resolution problem. The Full Scale of DAC = 5V. It sweeps over 65536 steps. If you feed 0x0001 into DAC, you will get 5/65536 = 0.0000763V at the OUT-pin of the DAC.
Do you happen to have the picture of the test setup laying around? I am facing the same issue currently. I managed to get it working at some point but it doesn't work atm.
I have pullup resistors(1K), AUX to GND, VREF to VCC VCC to 5V VREF IC
GolamMostafa:
You may try the following setup for quick functional check of MAX5217 DAC (untested due to lack of the DAC chip):
1. Build the following circuit between the UNO and the DAC. (AUX/ function is disabled.)
2. Connect a DVM at Out-pin of the DAC.
3. Upload the following sketch. Bring in the Serial Monitor at 9600 Baud.
#include <Wire.h>
void setup()
{
Serial.begin(9600);
Wire.begin();
pinMode(8, INPUT_PULLUP); //Dpin-8 is input with internal pull-up resistor
byte busStatus;
do
{
Wire.beginTransmission(0x1D); //checking the presence of DAC
busStatus = Wire.endTransmission();
}
while (busStatus !=0x00); //checking that DAc has aaccepted its address and has sent ACk signal
Serial.println(busStatus); //Serial Monitor should show 0
//--------------------------------
while(digitalRead(8) != LOW)
; //wait until K1 is closed
Wire.beginTransmission(0x1D); //address of DAC 0x1D
Wire.write(0x08); //pointing user configurable regsiter
Wire.write(0x00); //value for configurable register; AUX/ input is disabled
Wire.endTransmission(); //transfer all the above queued data to the ADC
//--------------------------------
Wire.beginTransmission(0x1D); //address of DAC
Wire.write(0x01); //address of command byte register/load code and load to DAC
Wire.write(0x7F); //upper 8-bit data for DAC
Wire.write(0xFF); //lower 8-bit data for DAC
Wire.endTransmission(); //transfer all the above queued data
}
void loop()
{
}
**4.** Check that **0** has appeared on the Serial Monitor.
**5.** Gently press the K1 switch.
**6.** Check that the DVM shows about 2.50V DC.
This is the end of simple functional check of the MAX5217 DAC.