Showing posts with label Microchip. Show all posts
Showing posts with label Microchip. Show all posts

Tuesday, May 3, 2016

Design a bipolar voltage source using the Microchip DAC MCP4922

Design a bipolar voltage source using the Microchip DAC MCP4922

The microchip device (MCP4922) is a very easy to use DAC that is accessed via SPI interface. I found it easier to interface with a +5V bus and VCC as opposed to +3.3V despite of what the datasheet says. (http://ww1.microchip.com/downloads/en/DeviceDoc/22250A.pdf)

In addition, I created a simple spreadsheet to enter different values in order to design before layout.

Once you read the datasheet, you'll understand where I got the values from.

DA and DB are the values that control the gain as well as the offset (Maximum 4095 in decimal).

VREFA and VREFB are your input reference sources. I typicaly use 2.5Vdc.

R1-R4 are the gain and offset resistors. I set all to 10k Ohms 1% 1/4Watts.

GA and GB are gain x1 or x2 as desire.

Vo is the output.

Enjoy.


Download worksheet here!!

Monday, March 7, 2016

Control the MCP4922 DAC using an Arduino MEGA2560

Control the Microchip MCP4922-E/P Digital to Analog Converter using an Arduino board.


I've been using the microchip DAC to output a +/-5V output. I used the Arduino MEGA2560 to write to the SPI bus and it worked great. The code is as follows:

//pin#  Pin Name    Mapped Pin Name
//19  PB0 ( SS/PCINT0 ) Digital pin 53 (SS)
//20  PB1 ( SCK/PCINT1 )  Digital pin 52 (SCK)
//21  PB2 ( MOSI/PCINT2 ) Digital pin 51 (MOSI)
//22  PB3 ( MISO/PCINT3 ) Digital pin 50 (MISO)
////////////////////////////////////////////////////////////////////////////////////////////////////

//Microchip MCP4922-E/P 
//Pin No.   Symbol  Function
//1         VDD     Supply Voltage Input (2.7V to 5.5V)
//3         CS      Chip Select Input
//4         SCK     Serial Clock Input
//5         SDI     Serial Data Input
//8         LDAC    Synchronization Input. This pin is used to transfer DAC settings (Input Registers)
//                  to the output registers (VOUT)
//9         SHDN    Hardware Shutdown Input
//10        VOUTB   DACB Output
//11        VREFB   DACB Reference Voltage Input (VSS to VDD)
//12        VSS     Ground reference point for all circuitry on the device
//13        VREFA   DACA Reference Voltage Input (VSS to VDD)
//14        VOUTA   DACA Output
////////////////////////////////////////////////////////////////////////////////////////////////////


// inslude the SPI library:
#include <SPI.h>

// set pin 10 and 11 as the chip select
const int nCS0 = 8;
const int nCS1 = 11;
const int nLDAC = 12;
const int nSHDN = 9;

const int GAINx1 = 1;   
const int GAINx2 = 0;    

const int Write_to_DACA = 0;
const int Write_to_DACB = 1;

const int BUF = 1;
const int nSHDown = 1;

// analog potentiometer joystick
int joystickBlue = A1;
int AnalogValue = 0;    //to store the value here





void setup() {
    
  pinMode(nCS0, OUTPUT);
  pinMode(nCS1, OUTPUT);
  pinMode(nLDAC, OUTPUT);
  pinMode(nSHDN, OUTPUT);
  
//  Set shutdown pin to high
  digitalWrite(nSHDN, HIGH);

// initialize the nLDAC to high
  pinMode(nLDAC, HIGH);
      
  // initialize SPI:
  SPI.begin();
  
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
  
  Serial.begin(115200);
}



void loop() {
  // analog values  
      AnalogValue = analogRead(joystickBlue);
  
  // Write to DA
  String myBinString = String(Write_to_DACA) + String(BUF) + String(GAINx2)+ String(nSHDown) + ConvertInt2Bin12(3000);
  
  // Write to DB
  String myBinStringB =String(Write_to_DACB) + String(BUF) + String(GAINx2)+ String(nSHDown) + ConvertInt2Bin12(2048);
  
  
  
  Serial.println(myBinString);  
  int tempA = ConvertBin2Dec(myBinString);
  Serial.println(tempA, HEX);
  Serial.println(" ");

  Serial.println(myBinStringB);  
  int tempB = ConvertBin2Dec(myBinStringB);
  Serial.println(tempB, HEX);
  Serial.println(" ");
  delay(500);
    

  digitalWrite(nCS0, LOW);    //Enable the chip U4 for X output
  SPI.transfer16(tempA);
  digitalWrite(nCS0, HIGH);
  
  digitalWrite(nCS0, LOW);    
  SPI.transfer16(tempB);
  digitalWrite(nCS0, HIGH);
  
  
  Latch_DAC_Input();

  
}


void DAC_Write(int address, int value, int CSNum){
  // Do the chip select value
  if (CSNum == 0) {
    digitalWrite(nCS0, LOW);
  }else if (CSNum == 1) {
    digitalWrite(nCS1, LOW);
  }

  //  send in the address and value via SPI:
  SPI.transfer(address);
  
  SPI.transfer(value);

  if (CSNum == 0) {
    digitalWrite(nCS0, HIGH);
  }else if (CSNum == 1) {
    digitalWrite(nCS1, HIGH);
  }
  
}

void Latch_DAC_Input(){
  //toggle the nLDAC to output voltage
  
  digitalWrite(nLDAC, LOW);
  
  digitalWrite(nLDAC, HIGH);
}


String ConvertInt2Bin12(int Value){
  //this sub will convert any integer value to its corresponding 12 bit
  String myString = String(Value, BIN);
  int lenString = myString.length();
  
  for ( int i=lenString; i<12; ++i){
    myString = "0" + myString;
  }
  
  return myString;
}

int ConvertBin2Dec(String BinData){
  //this sub will convert a 16 bit binary string to its equivalent HEX
  int LenString = BinData.length();
  double ValueDec = 1;
  int DataOut = 0;
  
  

  for ( int i = 0; i < LenString; i++){
  String MyStr =BinData.substring(LenString-i-1, LenString-i);

  if (MyStr == "0"){
    // add a zero
  }else{
    //add a 2^i
    ValueDec = pow(2,(float)i) + ValueDec;
  }

    
  }

  DataOut = ValueDec;

  return DataOut;
}