MCP49x1 DAC library...works on Duemilanove but not MEGA2560... ? SOLVED

Hi peeps. :slight_smile:

Having a bit of trouble and I wondered if anyone else has had this..
I have an MCP4921 DAC connected up to my MEGA2560 via the icsp header. The CS pin is in pin 10.
I am using the MCP49x1 DAC library from here:

It works on my Duemilanove but not on my MEGA2560...
It uses the SPI library so I would have thought that MEGA would be selected automatically for pinout..
Anyone else had a problem with this??
Oh, I did manage to get another library working:
Arduino Projekte but I much prefer the other one although I'm very grateful to Arduino-Projekte for the site....

but not the one I want..

I am using the MCP49x1 DAC library from here:

Your code is?

    PORTB &= 0xfb; // Clear PORTB pin 2 = arduino pin 10

I can’t imagine why that library thinks it needs to use non-portable code in the shutdown() method. Of course, it uses non-portable code in other methods, too, so I shouldn’t pick on that method.

Hi Paul! :slight_smile:
Code is here:

//
// Example for the MCP49x1 *single* DACs
// For the dual MCP49x2 series, see the other bundled example sketch.
//

#include <SPI.h>         // Remember this line!
#include <DAC_MCP49xx.h>
#define STEPS 256	
// The Arduino pin used for the slave select / chip select
#define SS_PIN 10

byte wavetable[STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2,
2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 17,
18, 19, 20, 22, 23, 24, 26, 27, 29, 30, 32, 34, 36, 37, 39, 41
, 43, 45, 47, 49, 51, 54, 56, 58, 61, 63, 66, 68, 71, 74, 76, 79,
82, 85, 88, 91, 94, 97, 100, 103, 107, 110, 113, 116, 120, 123,
127, 130, 134, 137, 141, 144, 148, 152, 155, 159, 162, 166, 170, 
173, 177, 180, 184, 187, 191, 194, 197, 201, 204, 207, 210, 213,
216, 219, 222, 225, 228, 230, 233, 235, 237, 239, 241, 243, 245,
246, 248, 249, 251, 252, 253, 253, 254, 255, 255, 255, 255, 255,
255, 255, 254, 253, 253, 252, 251, 249, 248, 246, 245, 243, 241,
239, 237, 235, 233, 230, 228, 225, 222, 219, 216, 213, 210, 207,
204, 201, 197, 194, 191, 187, 184, 180, 177, 173, 170, 166, 162,
159, 155, 152, 148, 144, 141, 137, 134, 130, 127, 123, 120, 116,
113, 110, 107, 103, 100, 97, 94, 91, 88, 85, 82, 79, 76, 74, 71,
68, 66, 63, 61, 58, 56, 54, 51, 49, 47, 45, 43, 41, 39, 37, 36, 34,
32, 30, 29, 27, 26, 24, 23, 22, 20, 19, 18, 17, 15, 14, 13, 12, 11,
10, 9, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0};

volatile int indx=0;
volatile int mi=1;
// Set up the DAC. 
// First argument: DAC model (MCP4901, MCP4911, MCP4921)
// Second argument: SS pin (10 is preferred)
// (The third argument, the LDAC pin, can be left out if not used)
DAC_MCP49xx dac(DAC_MCP49xx::MCP4921, SS_PIN);

void setup() {
  // Set the SPI frequency to 1 MHz (on 16 MHz Arduinos), to be safe.
  // DIV2 = 8 MHz works for me, though, even on a breadboard.
  // This is not strictly required, as there is a default setting.
  dac.setSPIDivider(SPI_CLOCK_DIV2);
  
  // Use "port writes", see the manual page. In short, if you use pin 10 for
  // SS (and pin 7 for LDAC, if used), this is much faster.
  // Also not strictly required (no setup() code is needed at all).
  dac.setPortWrite(false);
}

// Output something slow enough that a multimeter can pick it up.
// For MCP4901, use values below (but including) 255.
// For MCP4911, use values below (but including) 1023.
// For MCP4921, use values below (but including) 4095.
void loop() {
 
 
 indx+=4;
// dac.setSPIDivider(SPI_CLOCK_DIV2       );
  dac.output(wavetable[indx]);
 
  if (indx>=STEPS)
 indx=0;

 
}

Fairly standard stuff. Just a no-go on the MEGA2560. SCK, SDI and Vcc/Vss connected to ICSP. CS connected to pin 10. Vref to 5V…

You'd need to determine if pin 2 on port B is really pin 10 on the Mega. I have my doubts. If it isn't you'd need to modify the library to have different behavior on the Mega vs. the Uno.

Ha!! :open_mouth:

Got it. I changed all the references to PORT B pin 2 (UNO DUEMIL etc…) to PORT B pin 0 (which is the MEGA Variant.) so where there was

PORTB &= 0xfb; // Clear PORTB pin 2 = arduino pin 10

There is now

PORTB &= 0xfe; // Clear PORTB pin 2 = arduino pin 53 i.e. 11111110

and where there was

PORTB |= (1 << 2); // set PORTB pin 2 = arduino pin 10

there is now

PORTB |= (1 << 0); // set PORTB pin 2 = arduino pin 53

at this very second I am looking at a nice sine wave on my oscilloscope…
Thanks again for the help Paul.
Now to find a nice efficient way of being able to change frequencies… 8)

Hi to all,

I am searching for a "wiring" instruction or diagramm for this MCP49x1 chip + arduino.
Could somebody provide this?

thx Alex

Alex,

Which Arduino board are you using?
Generally the Vdd goes to 5V, AVss and LDAC to gnd, Vref: 0 to 5V(depends on your requirement), CS to any digital output pin on Arduino, and then SCK to SCk of Arduino, SDI to SDI of Arduino.

Hi vik_13,

I have an Uno, Meag2560 and the new Arduino DUE. Choose the one you can provide an example.

thx Alex