Go Down

Topic: Problems reading an analog input and output with 12 bits resolution (Read 4932 times) previous topic - next topic

zeluiz

      I´m trying to read 1.000 V at A0 (analog input) wjth 12 bits resolution, multiply by a factor of 1.625 and output it at DAC1 but it doesn't work. The sketch follows, please help me. Thanks a lot.
Code: [Select]
/*
Read the value of the potentiometer (1.000V) at A0 and multiply
for 1.625 and output it at DAC1 both with 12 bits resolution
*/
float val = 0; // variable to store the value coming from A0
float val2 = 0;
float outputValue =0;
int ananalogInPin = 0; // Analog input pin connected to the variable resistor
void setup()
{
// nothing in setup
}
void loop() {
 
val = analogRead(analogInPin); // read the voltage on the pot
analogReadResolution(12);
val2=val*1.625;
analogWriteResolution(12);
outputValue = map(val2,0,1023,0,4095);
  analogWrite(1,outputValue); //write at DAC1
}

shteii01

#1
Feb 17, 2013, 12:09 am Last Edit: Feb 17, 2013, 12:14 am by shteii01 Reason: 1
My guess is that you need to make the analogReadResolution(12); first.  Then do the reading.  Try this order of the code:
analogReadResolution(12);
val = analogRead(analogInPin); // read the voltage on the pot

gbduino

There are still some issues with the ADC and DAC.
I found and reported earlier, that the ADC readings drop as soon the ARM is warming up a bit (>32*C).
The DAC is obviously outputting voltages only in the range of 1/6..5/6 of 3300mV -
see also postings at: http://arduino.cc/forum/index.php/topic,129765.15.html
I have modified your code as follows which should work with above limitations:

Code: [Select]
/*
Read the value of the potentiometer (1.000V) at A0 and multiply
for 1.625 and output it at DAC1 both with 12 bits resolution
*/
unsigned long val = 0; // variable to store the value coming from A0
unsigned long val2 = 0;
unsigned long outputValue =0;
int analogInPin = 0; // Analog input pin connected to the variable resistor
void setup()
{
  analogReadResolution(12); //read-resolution to be set first
  analogWriteResolution(12); //this should not apply according to documentation but surprisingly does not show up as error?
}
void loop() {
  val = analogRead(analogInPin); // read the voltage on the pot
  val2=val*1625/1000; //recommended and faster to use integers instead of float for calculations.
  outputValue = map(val2,550,2750,0,3300); //to normalize limited output range
  analogWrite(DAC1,outputValue); //write at DAC1
  delay(500);
}


shteii01

#3
Feb 18, 2013, 09:18 pm Last Edit: Feb 18, 2013, 09:20 pm by shteii01 Reason: 1
gbduino, thank you for the example.  Like you said, you moved the instruction to use 12 bit resolution from loop() to setup().  I was wondering about that myself.  It seemed to me kind of wasteful to call for 12 bit resolution every single time that machine tried to read from analog input, it made more sense to setup 12 bit resolution one time in setup().  But the example for using 12 bit resolution on the main website, where it talks about using 10 bit and 12 bit resolution, had the command in the loop(), I think that is why OP also placed it in the loop().

zeluiz

It´s just necessary to write the followig code
[quote/*
Read the value of the potentiometer (1.000V) at A0 and multiply
for 1.652 and output it at DAC1 both with 12 bits resolution
*/
float val = 0; // variable to store the value coming from A0
float val2 = 0;
int analogInPin = 0; // Analog input pin connected to the variable resistor
void setup()
{
analogReadResolution(12);
analogWriteResolution(12);
}
void loop() {
 
val = analogRead(analogInPin); // read the voltage on the pot
val2=val*1.625;
analogWrite(DAC0,val2);
delay(5);
}][/quote]

zeluiz

I'll write again the code. It's just necessary to write this


Quote
/*
Read the value of the potentiometer (1.000V) at A0 and multiply
for 1.652 and output it at DAC1 both with 12 bits resolution
*/
float val = 0; // variable to store the value coming from A0
float val2 = 0;
int analogInPin = 0; // Analog input pin connected to the variable resistor
void setup()
{
analogReadResolution(12);
analogWriteResolution(12);
}
void loop() {
 
val = analogRead(analogInPin); // read the voltage on the pot
val2=val*1.625;
analogWrite(DAC0,val2);
delay(5);
}

gbduino

zeluiz,
it is not just clear if you still have a problem, what the problem is or if you already could solve it.
In case you solved it - what have been your findings and why was it "just necessary to write this" (might be of interest or help for others).

zeluiz

You don1t have to use map.   As you can see in the code.   Thank´s.

gbduino

thank you for your reply.
For me it was necessary to use mapping, to be able to obtain the correct voltage relation (as to your project) in the limited outout range my Dues provide. It could have been completely done in one step with "map", but for better understanding I used your multiplicator as first step to translate the input by 1.625 and the used map to obtain the correct voltage from the DAC as I found that not to be 1:1 (the value read for xV from ADC input did not result in xV when fed to DAC).
Are you able to set the voltage of the ADC-outputs in the full range from 0.0 to 3.3V !?
This would be different to what I and also others found.

Gericom


thank you for your reply.
For me it was necessary to use mapping, to be able to obtain the correct voltage relation (as to your project) in the limited outout range my Dues provide. It could have been completely done in one step with "map", but for better understanding I used your multiplicator as first step to translate the input by 1.625 and the used map to obtain the correct voltage from the DAC as I found that not to be 1:1 (the value read for xV from ADC input did not result in xV when fed to DAC).
Are you able to set the voltage of the ADC-outputs in the full range from 0.0 to 3.3V !?
This would be different to what I and also others found.

No, that's not possible. It's a limitation of the chip.
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

shteii01

From reading the this forum, the DAC only does 5/6 of 3.3 volts, so the maximum out of DAC is 2.75 volts.
This fact is actually important to me too because I am using Due in a project and plan to use DAC to control speed of a fan. 

Sorry to take this thread on a tangent.  But since we have listed the DAC limit.  Does ADC has a similar limit for input?  Or does it actually accept the maximum of 3.3 volts?

gbduino

If you need the output voltage starting from zero, you might compensate that by usage of a diode which shifts the min. as well the max. voltage by approx. -0.7V giving you a range of ~0..2V.
The ADCs work in full range 0..3300mV = 0..4095. There is only a slight variation for the upper limit, as the reference Voltage at AREF is built from the DUE's 3,3V regulator which is not that accurate in the range of some mV. You can apply your own AREF-voltage, but have to modify the hardware (remove a resistor) for that. AREF is not selectable by software at the DUE.
Further I found the ADC not to react below 13mV (which causes a small offset) and also the temperature issue I already reported before - that could cause a significant missreading.

zeluiz

    The problem is: I have is to emulate an analogical function control with amplifications, derivators, integrators, etc  So I need to perform mathemathicals operations, that is why I use float in my sketch.   I do believe that the DACs are linear between 0 to 3.3VDC i.e. the first grade 0 the next 0.00081VDC and so on.  That´s why I'm using the Due. I think my multimeter is not exact enough to mesure that.   Could someone elucidate that? 

zeluiz

       I wanted to know exactly the relation among the ADC (input) and the output (DAC) so I modify the sketch and multiply by 1.000.   This way with 0V at the input, it outputs to 0.55V (1/6) of 3.3V; 3.3V in the input, it outputs with 2.75V (5/6) of 3.3V.    So if the input is among 0 to 3.3V the output is among 0 to 2.75V linearly.   I think if someone wants a relation 1 to 1, between the input and the output, he needs to use operational amplifiers.  It follows my sketch.

Code: [Select]
/*
Read the value of the potentiometer (1.000V) at A0 and multiply
for 1.652 and output it at DAC1 both with 12 bits resolution
*/
float val = 0; // variable to store the value coming from A0
float val2 = 0;
int analogInPin = 0; // Analog input pin connected to the variable resistor
void setup()
{
analogReadResolution(12);
analogWriteResolution(12);
}
void loop() {
 
val = analogRead(analogInPin); // read the voltage on the pot
val2=val*1.000;
analogWrite(DAC0,val2);
delay(5);
}


retrolefty

I thought it was posted back when the Due first came out that the DAC hardware could not start at 0 volts base output voltage, but rather some elevated starting value?

Lefty

Go Up