Pages: 1 [2] 3   Go Down
Author Topic: DAC support  (Read 11378 times)
0 Members and 1 Guest are viewing this topic.
Forum Administrator
Offline Offline
God Member
*****
Karma: 47
Posts: 629
I find plain exciting
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

andy_g

The Due is still in beta, there is still work to be done on the documentation.

m
Logged

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 22
Posts: 292
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I could find no information about the DAC range in the SAM3X datasheet.
But on page 1059 of SAM3S datasheet, it is said that the voltage range of the DAC is from (1/6) x VADVREF to (5/6) x VADVREF.
So I suspect, the same applies to SAM3U, and range is 1/6 x 3.3V = 0.55V to 5/6 x 3.3V = 2.75V, which is verified by your measures.

I've just checked with Atmel support and they confirm that SAM3S and SAM3X features the same DAC IP, what you have measured is correct.

Logged

C.

Nice, France
Offline Offline
Full Member
***
Karma: 11
Posts: 234
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As far as the DAC is concerned it's a pity to have such limits but I guess for audio applications there are way to circumvent the issue.

Yes, for audio applications, if voltage range of the DAC is from (1/6) x VADVREF to (5/6) x VADVREF then you use a differential op-amp with the second input connected to (1/2) x VADVREF - though it would require a symmetric power supply. Or just use a DC blocking capacitor.

It is a surprising limitation for other uses, though.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
i'am experiencing the same problem as smay4finger described in original post, using this code:
Code:
void setup() {
  analogWriteResolution(12);
  analogWrite(DAC0, 4095);
  analogWrite(DAC1, 4095);
}
void loop(){}
however, this code set correct output values:
Code:
void setup() {
  analogWriteResolution(12);
  analogWrite(DAC0, 4095);
  analogWrite(DAC1, 4095);
  delay(2);
  analogWrite(DAC0, 2047);
  analogWrite(DAC1, 1023);
}
i suspect problem in this line in wiring_analog.c:
Code:
while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_TXRDY) == 0);
but you guys know better.
Regards,Vladimir
Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@vdorr

Hi,
Are you using the amended code (Reply #2)?

Jim
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@jgmdavies

Hi, i'm using Arduino 1.5.1 which allready contains this patch.

V.
Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@vdorr

OK, I'm using 1.5.1r2.

The following works as expected here, giving independent control of the two DACs:

Code:
       while (true)
        {
            analogWrite(DAC0, 240);
            delayMicroseconds(200);

            for (int i = 0; i < 8; i++)
            {
                analogWrite(DAC1, 240);
                delayMicroseconds(20);
                analogWrite(DAC1, 120);
                delayMicroseconds(80);
            }

            analogWrite(DAC0, 0);
            analogWrite(DAC1, 0);
            delay(9);
        }

Several people in this forum seem to have had trouble and have possibly blown their DAC output(s) by following an Audio example with a loudspeaker (which I haven't tried).

For anyone following with an 'early production' Due like me, please note that the constant 'DAC0' (66) corresponds to pin 'DAC2' on the board header, and 'DAC1' (67) corresponds to pin 'DAC1'.

Attached are screenshots from a Rigol scope. N.B. I'm using x10 probes.

HTH
Jim


* aaa.bmp (146.3 KB, 320x234 - viewed 59 times.)

* bbb.bmp (146.3 KB, 320x234 - viewed 47 times.)
« Last Edit: January 05, 2013, 09:54:31 am by jgmdavies » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@jgmdavies

i guess you are writing DAC in loop() but my (non-working) example was writing DAC in setup(), your code also has delay before writing second DAC channel, just like my second (working) example. In my opionion, there is bug in analogWrite(), related to initialization of DAC.
V.
Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi V,

The following works as expected here, with outputs as per the earlier scope 'screenshots':

Code:
void setup()
{
       while (true)
        {
            analogWrite(DAC0, 240);
            delayMicroseconds(200);

            for (int i = 0; i < 8; i++)
            {
                analogWrite(DAC1, 240);
                delayMicroseconds(20);
                analogWrite(DAC1, 120);
                delayMicroseconds(80);
            }

            analogWrite(DAC0, 0);
            analogWrite(DAC1, 0);
            delay(9);
        }
}

void loop()
{
}

What do you get?

Jim
Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi V,

And commenting out the initial delay like so:

Code:
void setup()
{
       while (true)
        {
            analogWrite(DAC0, 240);

            for (int i = 0; i < 8; i++)
            {
                analogWrite(DAC1, 240);
                delayMicroseconds(20);
                analogWrite(DAC1, 120);
                delayMicroseconds(80);
            }

            analogWrite(DAC0, 0);
            analogWrite(DAC1, 0);
            delay(9);
        }
}

void loop()
{
}

gives the outputs shown below.

Jim



* ccc.bmp (146.3 KB, 320x234 - viewed 38 times.)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@jgmdavies

I tried your code and from what i can tell (using Velleman HPS5), it works as expected, BUT it is equivalent to example from my first post which works as expected:
Code:
void setup()
{
analogWrite(DAC0, 255);
delayMicroseconds(200);
analogWrite(DAC1, 255);
}
void loop(){}
both outputs are at 2.8V, what is NOT working is this piece of code:
Code:
void setup()
{
analogWrite(DAC0, 255);
analogWrite(DAC1, 255);
}
void loop(){}
using this code DAC0 is at 0.54V and DAC1 at 2.8V
V.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@jgmdavies

Insertion of some delay between first two writes is perfectly acceptable workaround for me, but IMO this behaviour is bug and should be fixed. Am i crying on wrong place(forum)?
Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@vdorr

OK, I've caught up with you now!

And I agree, it seems to be a bug.  The delay between the writes in start() needs to be at least 30 us on mine (using the default 8 bit resolution).

Jim
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@jgmdavies

This modification seem to fix this buggy behaviour:
Code:
diff --git a/hardware/arduino/sam/cores/arduino/wiring_analog.c b/hardware/arduino/sam/cores/arduino/wiring_analog.c
index 58bd87a..97f50e8 100644
--- a/hardware/arduino/sam/cores/arduino/wiring_analog.c
+++ b/hardware/arduino/sam/cores/arduino/wiring_analog.c
@@ -243,8 +243,8 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) {
 
                        // Write user value
                        ulValue = mapResolution(ulValue, _writeResolution, DACC_RESOLUTION);
-                       while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_TXRDY) == 0);
                        dacc_write_conversion_data(DACC_INTERFACE, ulValue);
+                       while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_EOC) == 0);
                        return;
                }
        }
also with this change should desired value be on output pin by the time analogWrite() exits. Opinions?

V.
Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@vdorr

Looks good to me.  I repeated the basic test in start() with no delays and now it's fine, and my other tests are still good.

I think the person to discuss this with is cmaglie in this forum.

Thanks,
Jim
Logged

Pages: 1 [2] 3   Go Up
Jump to: