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:
#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