PSU Project #1 – MCP3304

(Transplanted from old website)
August 9th 2015:
This is the first episode of the series, since it’s an odd numbered episode we will be discussing digital things.
The MCP3304 is a 13-Bit ADC. The 13th bit is the sign bit for when in differential mode, but since we are using single ended we will be getting our results in 12-Bit format.
This episode is about 11 minutes long, I would eventually like to make longer episodes but I’m still finding my feet with it all. If I keep the episodes short it will allow me to get more of them out regularly as it won’t take as long for me to edit and annotate them, but we will see what happens as we progress.
This is the wiring of the MCP3304 and it’s reference and the connections to the Arduino as refered to in the video. I show a schematic with the MCP4822 DAC in the video, but this is the same schematic without the DAC.

PSU Project #1 – MCP3304

For those who are playing along at home, here is the Arduino code for testing the MCP3304:
 code can be found here
#define ADC_CS 10    // chip-select
#define ADC_MOSI 11   // ADC_MOSI 
#define ADC_MISO 12    // ADC_MISO 
#define SPI_CLK 13  // Clock
 
void pulse_MCP_clock(void)
{
  digitalWrite(SPI_CLK, LOW); delayMicroseconds(50);
  digitalWrite(SPI_CLK, HIGH); delayMicroseconds(50);
}
 
long read_MCP(int channel)
{
  long value=0;
  signed int x=0;
  digitalWrite(ADC_CS, HIGH);
  delayMicroseconds(50);
  digitalWrite(ADC_CS, LOW);
  delayMicroseconds(50);
  digitalWrite(ADC_MOSI, HIGH); //start pulse
  pulse_MCP_clock();
  digitalWrite(ADC_MOSI, HIGH); //single mode
  pulse_MCP_clock();
  for(x=2; x>=0; --x)
  {
    if(bitRead(channel,x))
    {
      digitalWrite(ADC_MOSI, HIGH);
    }
    else
    {
      digitalWrite(ADC_MOSI, LOW);
    }
    pulse_MCP_clock();
  }
  digitalWrite(ADC_MOSI, LOW);//put low throughout
  for(x=1;x<=3;++x)
  {
    //blank, Null, and sign bit (always 0 in single mode)
    pulse_MCP_clock();
  }
  //now get twelve bits
  for(x=11; x>=0; --x)
  {
      pulse_MCP_clock();
      if (digitalRead(ADC_MISO))
      {
         bitSet(value,x);
      }
      else
      {
         bitClear(value,x);
      }
  }
  digitalWrite(ADC_CS, HIGH);
  delayMicroseconds(10);
  return value;
 }
 
 void init_ADC(void)
 {
  digitalWrite(SPI_CLK,HIGH); //clock
  digitalWrite(ADC_MISO, LOW); //output -- supposed to be float but not sure how to do this on Arduino
  digitalWrite(ADC_MOSI, HIGH); //input
  digitalWrite(ADC_CS, HIGH);
  delayMicroseconds(50);
  digitalWrite(ADC_CS, LOW);
  delayMicroseconds(50);
 }
 
int get_adc_avg(int channel)
{
  long tempx = 0;
  byte ax = 0;
  for (ax=0;ax<10;ax++)
  {
    tempx+=read_MCP(channel);
  }
  tempx/=10;
  return (tempx);
}
 
void setup() {
   //set pin modes 
  pinMode(ADC_CS, OUTPUT); 
  pinMode(ADC_MOSI, OUTPUT); 
  pinMode(ADC_MISO, INPUT); 
  pinMode(SPI_CLK, OUTPUT); 
  
  init_ADC();
  // disable device to start with 
  digitalWrite(ADC_CS, HIGH); 
  Serial.begin(115200); 
  Serial.print("Hello2");
}
 
void loop() {
  // put your main code here, to run repeatedly:
  int tempx = 0;
  tempx = get_adc_avg(0);
  Serial.print("In = ");
  Serial.println(tempx,HEX);
  delay(50);
}

Leave a Reply