-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Welcome to the dac_shield wiki!
This is a work in progress. If you have a specific question which isn't answered here, please leave a comment and we'll add it in!
##Changelog Rev 4.5
- C2 - 47u, ceramic
- Pluggable headers for power input and output connections
Rev4
- Adjustment potentiometer - The direction of the adjustment pot has changed. In Rev 4, turning the pot clockwise increases gain and turning counter-clockwise decreases gain. The pot has also been labeled with a "+" and "-" in Rev 4
- Minor routing changes, improved silkscreen size and clarity
Rev3
- C2 - 22u, Tantalum
- R7, R8, R9 - 2.2k
Equipment Needed:
- Power DAC Shield
- Dual-output power supply or two batteries
- Arduino Uno, Duemilanove, Mega, or compatible board
- Oscilloscope
The easiest way to get a dual output power supply is to connect two 9 or 12v batteries in series where the middle junction is ground.
The most common split rail power supply uses a 12V center tapped transformer, bridge rectifier and large filtering capacitors.
If you don't have a dual-output power supply, two single-output, isolated power supplies can be used TODO: Add notes about connecting the shield to two bench supplies
The heart of this shield is the MCP4921 (Datasheet). This DAC uses the SPI protocol and can be written to either using the hard SPI on the Uno or bit-banged on Mega. The first step is to write a method that can send a unsigned 16 integer to the DAC. Since this is a 12bit The max voltage will be 4098, zero volts is 2048 and the negative max voltage is 0. The DAC is triggered one one of the 4 slave select pins (10,9,8,7) depending on the jumper. There are two ways these ping can be written, the first is to use the Arduino Digital Write.
//Method to write to the DAC
void writeMCP492x(uint16_t data,uint8_t slave_select) {
// Take the top 4 bits of config and the top 4 valid bits (data is actually a 12 bit number)
//and OR them together
uint8_t config = 0x30;
uint8_t top_msg = (config & 0xF0) | (0x0F & (data >> 8));
// Take the bottom octet of data
uint8_t lower_msg = (data & 0x00FF);
// Select our DAC, Active LOW
digitalWrite(slave_select, LOW);
// Send first 8 bits
SPI.transfer(top_msg);
// Send second 8 bits
SPI.transfer(lower_msg);
//Deselect DAC
digitalWrite(slave_select, HIGH);
}
While this is very straight forward, the digitalWrite method is fairly slow and can impact the ability to produce high frequency waves. An alternative is to write directly using the PORT. A good article explaining this can be found here.
For the Uno we can define Slave Select pins the following way:
#define SS0 (1 << 2) //Slave Select 0 PORTB
#define SS0PORT PORTB
#define SS1 (1 << 1) //Slave Select 1 PORTB
#define SS1PORT PORTB
#define SS2 (1 << 0) //Slave Select 2 PORTB
#define SS2PORT PORTB
#define SS3 (1 << 7) //Slave Select 2 PORTD
#define SS3PORT PORTD
For the Mega the Slave Selects are defined the as the following.
#define SS0 (1 << 4) //Slave Select 0 PORTB
#define SS0PORT PORTB
#define SS1 (1 << 6) //Slave Select 1 PORTH
#define SS1PORT PORTH
#define SS2 (1 << 5) //Slave Select 2 PORTH
#define SS2PORT PORTH
#define SS3 (1 << 4) //Slave Select 2 PORTH
#define SS3PORT PORTH
The WriteMCP Method will now be modified:
//Method to write to the DAC
void writeMCP492x(uint16_t data,uint8_t ss,volatile uint8_t* slave_port) {
// Take the top 4 bits of config and the top 4 valid bits (data is actually a 12 bit number)
//and OR them together
uint8_t config = 0x30;
uint8_t top_msg = (config & 0xF0) | (0x0F & (data >> 8));
// Take the bottom octet of data
uint8_t lower_msg = (data & 0x00FF);
// Select our DAC, Active LOW
*slave_port &= ~ss;
// Send first 8 bits
SPI.transfer(top_msg);
// Send second 8 bits
SPI.transfer(lower_msg);
//Deselect DAC
*slave_port |= ss;
}
Here are is of is an example of generating a square wave using the digital Digitalwrite version
while(1) {
writeMCP492x(4097,10); //Write max voltage to shield 0 (SS pin 10)
writeMCP492x(0,10); //Write min voltage to shield 0 (SS pin 10)
}
The same example using the direct port
while(1) {
writeMCP492x(4097,10,SS0,SS0PORT); //Write max voltage to shield 0
writeMCP492x(0,10,SS0,SS0PORT); //Write min voltage to shield 0
}
SAY what the frequency difference is