Go Down

Topic: MCP3903 - Super Fast Delta Sigma 24bit ADC over SPI coding problem (Read 855 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy