Pages: [1]   Go Down
Author Topic: Digital Analog Converter MCP4922  (Read 1083 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi to everyone,

I need to give an output between 0 and 4V with my Arduino DUE.

I have a Digital to Analog Converter MCP4922 but to use it I should change the SPI library because the stuff I was using for the Arduino UNO, on the DUE is not working because The sketch is written for an ATmega based Arduino. On a Due I can't use the direct port manipulation commands of the ATmega platform, so I have to rewrite the sketch to use digitalWrite() instead of the port manipulations and the SPI library instead of the register manipulations in the sketch.

I know that on the DUE there is already a DAC integrated, but the output can be only between 0 and 3.3V, actually they give an output between 0.549V and 2.775V.

I want an output between 0 and 4V. How can I have it?

I was thinking that there are mainly 2 ways:

1. Add an Operational Amplifier
2. Change the SPI library to let it work with the DUE.

What do you think is the best way? or what do you suggest to me and why?

Thanks a lot,
Fab.
Logged

L'impossibile...richiede solo piu' tempo!

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

If you go with SPI look at this thread. SPI is different on the ARM chip
http://forum.arduino.cc//index.php?topic=157203.msg1424519#msg1424519
I know its more about slave mode but plenty of tips for DUE SPI in there.

If you can use the Due 12bit DAC all the better.

Can you not use a pair of resistors to do a voltage divide and then a bit of math on the output to scale it to what you want.
Logged

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

Just noticed this post
http://forum.arduino.cc//index.php?topic=194694.0

Puts a damper on the idea of using the Due DAC.
Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 435
Posts: 23602
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://ww1.microchip.com/downloads/en/DeviceDoc/22250A.pdf

See page 23-24.
You bring CS low, send out 2 bytes via SPI.transfer(x);  bring CS high.
You really need a library for that?
Due does not support SPI.transfer( ) command?
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just noticed this post
http://forum.arduino.cc//index.php?topic=194694.0

Puts a damper on the idea of using the Due DAC.

Thanks for the reply but that page is not really useful for me because people are searching for a solution to connect the DUE as slave and it also seemed that they didn´t find a solution . By the way my problem is another one.

I want to use a DAC MCP4922 on the Arduino DUE

http://ww1.microchip.com/downloads/en/DeviceDoc/22250A.pdf

See page 23-24.
You bring CS low, send out 2 bytes via SPI.transfer(x);  bring CS high.
You really need a library for that?
Due does not support SPI.transfer( ) command?

Thanks for the reply ,

I will look into it.

Fab.
Logged

L'impossibile...richiede solo piu' tempo!

Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok. I looked a little bit more into it and what I have to send is the one in the picture attached.

So now I know what message I have to send but, in your opinion can I send it with just an SPI.write(msg) command?

Thanks a lot,
fab.



* dac_message.png (20.64 KB, 937x116 - viewed 34 times.)
Logged

L'impossibile...richiede solo piu' tempo!

Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think I can do it in this way:

Code:
#include <SPI.h>

void setup() {
  // put your setup code here, to run once:
SPI.begin(10);
}

void loop() {
  // put your main code here, to run repeatedly:
 
  // The entire message to send a 4095 number will be:
  // 0011 | 111111111111
 
  msg= ...
  SPI.transfer(10,msg)
}

What is msg?

The problem now is how to create a message of 2 bytes on the Arduino DUE, because the integers are of 32 bits.

Thanks for your help,
Fab.
Logged

L'impossibile...richiede solo piu' tempo!

Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried with this:

Code:
short msg=0011111111111111;
 
  SPI.transfer(10,msg);

and with this:
Code:
byte msg1=00111111;
byte msg2=11111111;
SPI.transfer(10,msg1,SPI_CONTINUE);
SPI.transfer(10,msg2);

But nothing is working smiley-sad .

Please help
« Last Edit: October 31, 2013, 02:42:19 am by f.schiano » Logged

L'impossibile...richiede solo piu' tempo!

Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I figured out that the library SPI.h is only for 8 bit data values. So I can´t use the library to address my MCP4922 DAC.

Assumed that this is true what I have to do now is to port the following code, that is working on my Arduino UNO, to the DUE:

Code:
/*
  MCP4922 test
  outputs steadily rising voltages through both DACs
 
  Steve Woodward, 2010
  most code borrowed from
  http://mrbook.org/blog/2008/11/22/controlling-a-gakken-sx-150-synth-with-arduino/
 
  connections
  ====================================================
 
  +5v           > 4922 pin 1
  Ard pin 10    > 4922 pin 3   (SS - slave select)
  Ard pin 13    > 4922 pin 4   (SCK - clock)
  Ard pin 11    > 4922 pin 5   (MOSI - data out)
  Ground        > 4922 pin 8   (LDAC)
  +5v           > 4922 pin 11  (voltage ref DAC B)
  Ground        > 4922 pin 12
  +5v           > 4922 pin 13  (voltage ref DAC A)
 
 
  4922 pin 14 DAC A > 1k resistor > synth CV in
 
 */
 
// MCP4922 DAC out
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO - not used, but part of builtin SPI
#define SPICLOCK  13//sck
#define SLAVESELECT0 10//ss
 
int i = 0;
 
void setup() {
  SPI_setup();
  Serial.begin(115200);
}
 
void loop() {
 i++;
 Serial.println(i);
 write_note(i);
 if(i>=4096) {
  i=0;
 }
 delay(8);
}
 
void write_note(int i) {
  write_valueY(i);
  write_valueX(i);
}
 
// **************************************************
// SPI for DAC
 
void SPI_setup(){
 
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT0,OUTPUT);
  digitalWrite(SLAVESELECT0,HIGH); //disable device
 
  SPCR = (1<<SPE)|(1<<MSTR) | (0<<SPR1) | (0<<SPR0);
  clr=SPSR;
  clr=SPDR;
  delay(10);
}
 
// write out through DAC A
void write_valueX(int sample)
{
  // splits int sample in to two bytes
  byte dacSPI0 = 0;
  byte dacSPI1 = 0;
  dacSPI0 = (sample >> 8) & 0x00FF; //byte0 = takes bit 15 - 12
  dacSPI0 |= (1 << 7);// A/B: DACa or DACb - Forces 7th bit of x to be 1. all other bits left alone.
  dacSPI0 |= 0x10;
  dacSPI1 = sample & 0x00FF; //byte1 = takes bit 11 - 0
  dacSPI0 |= (1<<5);  // set gain of 1
  digitalWrite(SLAVESELECT0,LOW);
  SPDR = dacSPI0;   // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
 
  SPDR = dacSPI1;
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  digitalWrite(SLAVESELECT0,HIGH);
  //delay(2);
}
 
// write out through DAC B
void write_valueY(int sample)
{
  // splits int sample in to two bytes
  byte dacSPI0 = 0;
  byte dacSPI1 = 0;
  dacSPI0 = (sample >> 8) & 0x00FF; //byte0 = takes bit 15 - 12
  dacSPI0 |= 0x10;
 
  dacSPI1 = sample & 0x00FF; //byte1 = takes bit 11 - 0
  dacSPI0 |= (1<<5);  // set gain of 1
 
  digitalWrite(SLAVESELECT0,LOW);
  SPDR = dacSPI0;   // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
 
 
  SPDR = dacSPI1;
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  digitalWrite(SLAVESELECT0,HIGH);
  //delay(2);
}


I need some help for that please.
Logged

L'impossibile...richiede solo piu' tempo!

Germany
Offline Offline
Edison Member
*
Karma: 1
Posts: 1353
Here we go!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I figured out how to solve my problem. smiley

The library was useful , what I wrote in my previous post was a bullshit.

Here you can find a small tutorial to understand what I did:
http://schianorobotics.altervista.org/arduino.html

Hope it helps someone. If yes a "thanks" would be really appreciated !!!
Logged

L'impossibile...richiede solo piu' tempo!

Pages: [1]   Go Up
Jump to: