Arduino MEGA interfacing with the MCP4821 DAC

Hi,

Firstly, sorry if this answer exists elsewhere on this forum. I've searched but nothing seems to address my current situation.

So I'm trying to use the MCP4821 to convert some D to some A. I had the whole thing working first time around without a problem. I transferred the circuit to a more permanent format and suddenly no functionality. Moving the chip back to a breadboard after failure, and the original circuit, no longer functions. So i figure ah i must have wrecked the chip. However, after replacing the MCP4821 the circuit still does not function. All of the connections are the same as the first working circuit but no output from the MCP4821. Could it a possibly be a problem with the Arduino itself? I'm just baffled and run completely dry of debugging ideas.

see attached the code I'm using to test the circuit.

The circuit connections I'm using are:

Arduino MCP4821

1 VCC
53 (SS) 2
52 (SCK) 3
51 (MOSI) 4
7 GND
8 OUTPUT

Any help at all with this bizarre situation would be greatly appreciated!

Thanks in advance!

MCP4821.ino (841 Bytes)

A breadboard is not a good base for exploring sudden malfunction. And it must be a hardware issue if you got the code working already some time ago. Now remote diagnosis of hardware issues is very difficult.

Do you have another SPI device at hand for testing the Arduino?

Sorry for the slow reply, work has been hell. Thanks so much for replying. This is pretty much where I'd landed too!

Since my last post, I have actually discovered my problem - Not the solution however.

My problem lies somewhere in the communication from MEGA to IC. So, I realised, when I had the circuit functioning correctly it was in fact using an UNO board. So I ordered an UNO board (I broke the one I used first time around) and hey presto it worked. Sorry for the initial IDIOCY. Now my problem is i'm still too uneducated to understand the code I'm using fully. As far as i'm aware the clock line to the MCP4821 is the only pin that needs to be defined. the others are hard wired either in our out... correct???

So what do I have to change when transferring the circuit from UNO to MEGA (I need the outputs!!!) to get this thing working?????

THANKS AGAIN!!!!!!

Jordan

The SS pin is designed to select the device on the SPI bus. SCK and MOSI are shared by all devices, MISO as required.

Of course it doesn't work on a Mega, it was written specifically for the atMega328 processor. It was explained on the website that was the source of the code you're using. In case you don't know the origin:

http://www.kerrywong.com/2012/07/25/code-for-mcp4821-mcp4822/

You can try this, it might work. I cannot test. It certainly has a better chance than code written for the Uno.

#include <SPI.h>
 
const int PIN_CS = 53;
const int GAIN_1 = 0x1;
const int GAIN_2 = 0x0;
 
void setup()
{
  pinMode(PIN_CS, OUTPUT);
  SPI.begin();  
  SPI.setClockDivider(SPI_CLOCK_DIV2);
}
 
//assuming single channel, gain=2
void setOutput(unsigned int val)
{
  byte lowByte = val & 0xff;
  byte highByte = ((val >> 8) & 0xff) | 0x10;
    
  PORTC &= 0xFE;
  SPI.transfer(highByte);
  SPI.transfer(lowByte);
  PORTC |= 0x1;
}
 
void setOutput(byte channel, byte gain, byte shutdown, unsigned int val)
{
  byte lowByte = val & 0xff;
  byte highByte = ((val >> 8) & 0xff) | channel << 7 | gain << 5 | shutdown << 4;
   
  PORTC &= 0xFE;
  SPI.transfer(highByte);
  SPI.transfer(lowByte);
  PORTC |= 0x1;
}
 
void loop()
{
 //high-res triangular wave
 for (int i=0; i < 4096; i+=32)   
 {
  setOutput(0, GAIN_2, 1, i);
  //setOutput(i);
 }
}

If it doesn't work, this should but will be slower as explained on Kerry's blog.

#include <SPI.h>
 
const int PIN_CS = 53;
const int GAIN_1 = 0x1;
const int GAIN_2 = 0x0;
 
void setup()
{
  pinMode(PIN_CS, OUTPUT);
  SPI.begin();  
  SPI.setClockDivider(SPI_CLOCK_DIV2);
}
 
//assuming single channel, gain=2
void setOutput(unsigned int val)
{
  byte lowByte = val & 0xff;
  byte highByte = ((val >> 8) & 0xff) | 0x10;
    
  digitalWrite(PIN_CS,LOW);
  SPI.transfer(highByte);
  SPI.transfer(lowByte);
  digitalWrite(PIN_CS,HIGH);
}
 
void setOutput(byte channel, byte gain, byte shutdown, unsigned int val)
{
  byte lowByte = val & 0xff;
  byte highByte = ((val >> 8) & 0xff) | channel << 7 | gain << 5 | shutdown << 4;
   
  digitalWrite(PIN_CS,LOW);
  SPI.transfer(highByte);
  SPI.transfer(lowByte);
  digitalWrite(PIN_CS,HIGH);
}
 
void loop()
{
 //high-res triangular wave
 for (int i=0; i < 4096; i+=32)   
 {
  setOutput(0, GAIN_2, 1, i);
  //setOutput(i);
 }
}

If the same (and only) SPI device is used, the SS line can be kept active all the time, no need for toggling and register bit fiddling.

Hey guys! Thank you for all of your help. I now have the circuit functioning and without your help this would have taken me weeks. Once again sorry for my lack of knowledge, its evident why you guys are GOD tier.

The problem was the code as stated by WattsThat, with a few adjustments to the code provided by them its working perfectly.

Also thanks for the link to the original code - this code was actually just given to me by a friend without the blog link!!! All very useful information and I now understand where I was going WRONG!!!!!

Thanks again guys! You've saved this project!

Hi,
Me too having the same problem.
I worked with mcp4821(STM32) and i get the output, but after that i changed my mcp4821 interfaces to another micro-controller(MCP432P4XX) and there too i get the output.
but after some days i suddenly not getting the output which i was already geted from that micro-controller.
So i changed the interface to my old micro-controller(STM32) and there too its not working.
I even checked everything , there is no shorts too.
So please tell me what changes should i do to bring it to work again.
Thanking You,
Karthikeyan J

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