PSU Project #5 – Arduino SPI

September 19th 2015
In this video I get the hardware SPI up and running on the Arduino and write code for the MCP3304 and MCP4822
The example Arduino code further down the page will read channel 0 of the ADC and output it to both channels of the DAC.
I recorded this with a Sony DCR-SR300 camcorder I borrowed from the college, turns out that it’s not a HD recorder. I didn’t realize this until I was nearly done editing. I will make sure I get a HD camera for next time.

Arduino code (can be downloaded here):
#include "SPI.h"

#define DAC_CS 9 // DAC chip-select
#define ADC_CS 10 // ADC chip-select

void setup() {
 //set pin modes 
 pinMode(DAC_CS, OUTPUT); 
 pinMode(ADC_CS, OUTPUT); 
 // disable all devices to start with 
 digitalWrite(ADC_CS, HIGH); 
 digitalWrite(DAC_CS, HIGH); 

void set_dac(byte chan, unsigned int value,byte ga, byte shdn)
 byte b,c,conf;
 // ga : 0=2x (0-4096v), 1=1x (0-2.048v)
 // shdn : 0 = shutdown DAC channel, 1 = output available
 // [ A'/B , x , GA', SHDN', D11, D10, D9, D8 ]
 conf=(chan&0x01)<<7; // mask out channel number and shift it to bit 7
 conf=conf|(ga&0x01)<<5; // mask out gain select and shift it to bit 5 and or it to conf
 conf=conf|(shdn&0x01)<<4; // mask out shutdown select and shift it to bit 4 and or it to conf
 conf=conf|(value>>8); // or in the top nibble of value left in conf
 b = value; // bottom byte of value
 SPI.beginTransaction(SPISettings(15000000, MSBFIRST, SPI_MODE0));
 digitalWrite (DAC_CS, LOW); // enable DAC
 SPI.transfer(conf); // send configuration and top nibble of value
 SPI.transfer(b); // send bottom byte
 digitalWrite (DAC_CS, HIGH); // disable DAC


unsigned int get_adc(byte chan)
 unsigned int a,b,c,conf;
 conf=conf=((chan&0b00000111)<<1)|0b00110000; // create configuration byte
 SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
 digitalWrite (ADC_CS, LOW); // enable ADC
 SPI.transfer(conf); // send configuration byte
 b = SPI.transfer(0x00); // receive sign bit & top 4 bits 
 c = SPI.transfer(0x00); // receive lower 8 bits
 digitalWrite (ADC_CS, HIGH); // disable ADC
 b = b&0b00011111; // filter out unwanted stuff from high byte
 a = (b*0x100)+c; // convert 2 8-bit numbers into a single 16-bit number

unsigned int get_adc_avg(byte chan)
 long tempx = 0;
 byte ax = 0;
 for (ax=0;ax<10;ax++)
 return (tempx);

void loop() 
 unsigned int xx;
 set_dac(0, (get_adc_avg(0)/2),0, 1);
 set_dac(1, (get_adc_avg(0)/2),0, 1);

Leave a Reply