Go Down

Topic: MCP3903 - Super Fast Delta Sigma 24bit ADC over SPI coding problem (Read 774 times) previous topic - next topic

Aug 14, 2013, 02:01 pm Last Edit: Aug 15, 2013, 01:26 pm by WriteView Reason: 1
Hi,

I searched for a cheap ADC which is really fast and accurate. I found the MCP3903.
But this chip really kills me.

What I want to do:
I want to use this chip for logging values on analogue sensors. This should be done very very fast.
I want to use it in 16-bit-mode to reduce data transmission but with the option to go to 24-bit resolution.
Maybe somebody accepts this post as a competition to make that project as fast as possible.

The datasheet can be found here: http://ww1.microchip.com/downloads/en/DeviceDoc/25048B.pdf

Maybe my code is confusing. This just happened with on-going frustration. But maybe it helps:
Code: [Select]


#include <SPI.h>

#include <HardwareSerial.h>

long ticks = 0;

// for Mega2560 / Max32
#define SELPIN 0    // chip-select
#define DATAOUT 3   // MOSI
#define DATAIN 2    // MISO
#define SPICLOCK 1  // Clock

#define CS 21    // chip-select

//***************************************************************************



#define CS_setup_time for (t=0;t<5;t++) // CS setup time
#define CS_hold_time for (t=0;t<10;t++) // Last SPI cycle time + CS hold time
#define CS_disable_time for (t=0;t<10;t++) // CS disable time



//#define MAX_PC_COMMAND 27 // number of bytes in the packet received from GUI
//#define MAX_BUFF 516 // read data buffer
//#define REAL_N 256
//#define MAX_BUFF 1 // read data buffer
//#define REAL_N 1

#define SPI_device_address 0x40
#define SPI_read_command 0x01

//MCP3903 Internal Register Addresses
#define CHANNEL0 0x00
#define CHANNEL1 0x01
#define CHANNEL2 0x02
#define CHANNEL3 0x03
#define CHANNEL4 0x04
#define CHANNEL5 0x05
#define MOD 0x06
#define PHASE 0x07
#define GAIN 0x08
#define STATUS_COM 0x09
#define CONFIG 0x0A

//****************************************************************************

void setup(){
 SPI.setClockDivider( SPI_CLOCK_DIV4 ); // slow the SPI bus down
 SPI.setBitOrder(MSBFIRST);
 SPI.setDataMode(SPI_MODE0);    
 SPI.begin();
 Config_MCP3903();
 Serial.begin(115200);
}


void loop() {
 Serial.println("___");
 read_adc3903(1);
 delay(500);
}


// Write complete configuration at startup
void Config_MCP3903(void)
{
unsigned char t;
       digitalWrite(CS, LOW);
CS_setup_time; // CS setup time
       SPI.transfer(t);              // don't care what we send
// Send write command, first address = CONFIGL register
byte commandbits = SPI_device_address | (CONFIG<<1);
       SPI.transfer(commandbits);       // Send write command, first address = CONFIGL register
       SPI.transfer(0xFC);       // Reset for all ADCs
       SPI.transfer(0x00);       // default
       SPI.transfer(0x00);       // EXTCLK=0 = etxerner oszi
CS_hold_time; // CS hold time
digitalWrite(CS, HIGH);
CS_disable_time; // CS disable time
digitalWrite(CS, LOW);
CS_setup_time; // CS setup time
       t = SPI.transfer(t);              // don't care what we send

// Send write command, first address = PHASE register
commandbits = SPI_device_address | (PHASE<<1);
SPI.transfer(commandbits);       //
/*
PHASEr_3903.reg_MSB = 0; // Phase delay=0
PHASEr_3903.reg_middle = 0; // Phase delay=0
PHASEr_3903.reg_LSB = 0; // Phase delay=0

GAINr_3903.reg_MSB = 0; // GAIN = 1 for all channels
GAINr_3903.reg_middle = 0;
GAINr_3903.reg_LSB = 0;

STATUSr_3903.reg_MSB = 0xDF; // Address counter incremented on all registers
STATUSr_3903.reg_middle = 0xF0; // 24 bit mode for all ADCs, DR_LTY=1, DR_HIZ=1, DR_LINK=1
STATUSr_3903.reg_LSB = 0x3F; // default

CONFIGr_3903.reg_MSB = 0x00; // default
CONFIGr_3903.reg_middle = 0x0F; // default
CONFIGr_3903.reg_LSB = 0xF1; // EXTCLK=1
*/
commandbits = 0; //PHASEr_3903.reg_MSB; // Write phase data
       SPI.transfer(commandbits);
       
commandbits = 0; //PHASEr_3903.reg_middle; // Write phase data
       SPI.transfer(commandbits);

commandbits = 0; //PHASEr_3903.reg_LSB; // Write phase data
       SPI.transfer(commandbits);

commandbits = 0; //GAINr_3903.reg_MSB; // Write gain data
       SPI.transfer(commandbits);
       
commandbits = 0; //GAINr_3903.reg_middle; // Write gain data
       SPI.transfer(commandbits);

commandbits = 0; //GAINr_3903.reg_LSB; // Write gain data
       SPI.transfer(commandbits);

commandbits = 0xDF; //STATUSr_3903.reg_MSB; // Write status data
       SPI.transfer(commandbits);

commandbits = 0xF0; //STATUSr_3903.reg_middle; // Write status data
       SPI.transfer(commandbits);

commandbits = 0x3F; //STATUSr_3903.reg_LSB; // Write status data
       SPI.transfer(commandbits);

commandbits = 0x00; //CONFIGr_3903.reg_MSB; // Write config data
       SPI.transfer(commandbits);

commandbits = 0x0F; //CONFIGr_3903.reg_middle; // Write config data
       SPI.transfer(commandbits);

commandbits = 0xF1; //CONFIGr_3903.reg_LSB; // Write config data
       SPI.transfer(commandbits);

digitalWrite(CS, HIGH);
CS_hold_time; // CS hold time
digitalWrite(CS, HIGH);
CS_disable_time; // CS disable time
       
}


int read_adc3903(int channel){
   
 digitalWrite (CS, LOW); // Select adc

 byte commandbits = 0xAA;
 int INIT = SPI.transfer(commandbits);       // send out first byte of command bits
 Serial.print(INIT);  Serial.print("!");
 
  // read low byte
 int HB = SPI.transfer(0x01);              // don't care what we send
 int MB = SPI.transfer(0x01);              // don't care what we send
 int LB = SPI.transfer(0x01);              // don't care what we send
 digitalWrite(CS, HIGH); // turn off device

 Serial.print(HB);  Serial.print(":");
 Serial.print(MB);  Serial.print(":");  
 Serial.println(LB);
 
 }





I succeeded with MCP3304, but the MCP3903 kills me.
Can somebody can past me working code with that chip?

Thanks a lot

Go Up