Arduino MKR ZERO DAC resolution

Hello all,

I have created a code for 10 bit DAC using Arduino MKR zero board with SAMD21 controller. Here is the code. it created with default voltage reference 3.3V. i get desired output. Problem statement stated below the code:

**Voltage reference 3.3V**
void setup()
{
  Serial.begin(9600); //start serial communication
  
  analogWriteResolution(10); //set the Arduino DAC for 10 bits of resolution (max)
  //Get user entered voltage, convert to DAC value, output DAC value
  analogWrite(A0,setDAC(getVoltValue()));

}

void loop()
{
  
}

//this function converts a user entered voltage value into a 10 bit DAC value 
int setDAC(float volt) {
 //formula for calculating DAC output voltage Vdac = (dVal / 1023)*3.3V
 int ipval = (int)((volt*1023)/3.3);
 return ipval;
}

//this function gets the user entered DAC voltage value from serial monitor
float getVoltValue() {
 float v = 0; //variable to store voltage 
 Serial.println("Enter the voltage you want the DAC to output (range 0V to 3.3V)");
 v = readParameter();
 if (v < 0 || v > 3.3) v = 0; //check to make sure it is between 0 and 3.3V
 Serial.print("DAC voltage set to ");
 Serial.println(v);
 Serial.println("Outputting DAC value........");
 return v;
}

//waits for serial data and reads it in. This function reads in the parameters
// that are entered into the serial terminal
float readParameter() {
 while(!Serial.available()); //Wait for user to enter setting
 return Serial.parseFloat(); //get int that was entered on Serial monitor
}

Problem Statement:
To increase the resolution. i am trying to use the internal reference(1V) in place of Default reference (3.3V)

here is the modified code but i am not getting appropriate output. Please check this modified code and add your directions.

**Voltage reference 1.0V**
void setup()
{
  Serial.begin(9600); //start serial communication
  
  analogWriteResolution(10); //set the Arduino DAC for 10 bits of resolution (max)
  analogReference(AR_INTERNAL1V0);
  //analogReference(AR_DEFAULT);
  //Get user entered voltage, convert to DAC value, output DAC value
  analogWrite(A0,setDAC(getVoltValue()));

}

void loop()
{

} 

//this function converts a user entered voltage value into a 10 bit DAC value 
int setDAC(float volt) {
 //formula for calculating DAC output voltage Vdac = (dVal / 1023)*1.0V
 int ipval = (int)((volt*1023)/1.0);
 return ipval;
}

//this function gets the user entered DAC voltage value from serial monitor
float getVoltValue() {
 float v = 0; //variable to store voltage 
 Serial.println("Enter the voltage you want the DAC to output (range 0V to 1.0V)");
 v = readParameter();
 if (v < 0 || v > 1.0) v = 0; //check to make sure it is between 0 and 3.3V
 Serial.print("DAC voltage set to ");
 Serial.println(v);
 Serial.println("Outputting DAC value........");
 return v;
}

//waits for serial data and reads it in. This function reads in the parameters
// that are entered into the serial terminal
float readParameter() {
 while(!Serial.available()); //Wait for user to enter setting
 return Serial.parseFloat(); //get int that was entered on Serial monitor
}

Working code for 1V Reference


void setup()
{
  Serial.begin(9600); //start serial communication
  
  DAC->CTRLB.bit.REFSEL = 0;
  delay(1000);
  analogWriteResolution(10); //set the Arduino DAC for 10 bits of resolution (max)
  //Get user entered voltage, convert to DAC value, output DAC value
  analogWrite(A0,setDAC(getVoltValue()));

}

void loop()
{
  
}

//this function converts a user entered voltage value into a 10 bit DAC value 
int setDAC(float volt) {
 //formula for calculating DAC output voltage Vdac = (dVal / 1023)*3.3V
 int ipval = (int)((volt*1023)/1.0);
 return ipval;
}

//this function gets the user entered DAC voltage value from serial monitor
float getVoltValue() {
 float v = 0; //variable to store voltage 
 Serial.println("Enter the voltage you want the DAC to output (range 0V to 3.3V)");
 v = readParameter();
 if (v < 0 || v > 1.0) v = 0; //check to make sure it is between 0 and 3.3V
 Serial.print("DAC voltage set to ");
 Serial.println(v);
 Serial.println("Outputting DAC value........");
 return v;
}

//waits for serial data and reads it in. This function reads in the parameters
// that are entered into the serial terminal
float readParameter() {
 while(!Serial.available()); //Wait for user to enter setting
 return Serial.parseFloat(); //get int that was entered on Serial monitor
}



End of query

Please post the code using the <CODE/> button.

See the 'How to get the best out of this forum' post; in particular, the ' Posting code and common code problems' section.

How will that increase the resolution ?

So what are you getting?

I don't know how to do that using button.

For example: when V ref is 3.3V, If i command the DAC to produce 3.3V then the output is 3.255V, Similarly If i command the DAC to produce 3.29V the output is 3.252V do u see it is off by 3 mV. to reduce the 3-mV difference if i change my internal reference to 1V 3 mV comes down to 1mV.

It is still taking the default reference value 3.3V. Not using the function analogReference(AR_INTERNAL1V0);

See the 'How to get the best out of this forum ' post; in particular, the ' Posting code and common code problems' section.

Does it? :thinking:

Please review code and help me know why am i not getting 1V reference working . it is still taking 3.3V

Please post the code legibly.

Edited post. please check

It's not helpful to edit a post after there's been replies to it - because now the replies no longer make sense!

The documentation for analogReference() only mentions it being used for analogue input - are you sure it is supposed to also affect the output?

The analog input reference value is used to calculate the DAC output voltage.

DAC output voltage Vdac = (dVal / 1023)*3.3V

where 3.3 is Reference voltage V ref. in my case it will be 1V

Hello,

I have figured this out. Yes you are right . Analog ref is only analog input .

I have added DAC->CTRLB.bit.REFSEL = 0; it got worked with internal reference of 1 V.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.