Hello All,
I'm building a little pcb with the LTC2400 as a primer to interfacing with some complex ADC's, but I've run into a small problem...
Here is the background:
This project is based on this:
http://interface.khm.de/index.php/lab/experiments/connect-a-ltc2400-high-precision-24-bit-analog-to-digital-converter/
-Arduino-
Arduino Duemilanove atmega 328
Running off USB power (no external power source) & Windows 7 laptop
Arduino IDE 1.0.6
-Board-
Radioshack double sided PCB 1.25"x1"
2x Panasonic 10uf electrolytic capacitors (round through hole)
1x Radioshack 0.1uf film capacitor (flat through hole)
1x lp2950-33 (TO92) Datasheet
1x lt2400 (SOIC8) Datasheet
Here is the eagle schematic & board layout:
(be nice, this is my first time using eagle)
for reference, the ltc2400 pin out
Here is the code:
credit again goes to aforementioned link
/* LTC2400 24 Bit ADC Test
* Connect an LTC2400 24 Bit ADC to the Arduino Board in SPI Mode
*
*
*
* KHM 2009 / Martin Nawrath
* Kunsthochschule fuer Medien Koeln
* Academy of Media Arts Cologne
*/
#include <Stdio.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define LTC_CS 2 // LTC2400 Chip Select Pin on Portb 2
#define LTC_MISO 4 // LTC2400 SDO Select Pin on Portb 4
#define LTC_SCK 5 // LTC2400 SCK Select Pin on Portb 5
void setup() {
cbi(PORTB,LTC_SCK); // LTC2400 SCK low
sbi (DDRB,LTC_CS); // LTC2400 CS HIGH
cbi (DDRB,LTC_MISO);
sbi (DDRB,LTC_SCK);
Serial.begin(57600);
// init SPI Hardware
sbi(SPCR,MSTR) ; // SPI master mode
sbi(SPCR,SPR0) ; // SPI speed
sbi(SPCR,SPR1); // SPI speed
sbi(SPCR,SPE); //SPI enable
Serial.println("LTC2400 ADC Test");
}
float volt;
float v_ref=3.3; // Reference Voltage, 5.0 Volt for LT1021 or 3.0 for LP2950-3
long int ltw = 0; // ADC Data ling int
int cnt; // counter
byte b0; //
byte sig; // sign bit flag
char st1[20]; // float voltage text
/********************************************************************/
void loop() {
cbi(PORTB,LTC_CS); // LTC2400 CS Low
delayMicroseconds(1);
if (!(PINB & (1 << 4))) { // ADC Converter ready ?
// cli();
ltw=0;
sig=0;
b0 = SPI_read(); // read 4 bytes adc raw data with SPI
if ((b0 & 0x20) ==0) sig=1; // is input negative ?
b0 &=0x1F; // discard bit 25..31
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
ltw <<= 8;
b0 = SPI_read();
ltw |= b0;
delayMicroseconds(1);
sbi(PORTB,LTC_CS); // LTC2400 CS Low
delay(200);
if (sig) ltw |= 0xf0000000; // if input negative insert sign bit
ltw=ltw/16; // scale result down , last 4 bits have no information
volt = ltw * v_ref / 16777216; // max scale
Serial.print(cnt++);
Serial.print("; ");
printFloat(volt,6); // print voltage as floating number
Serial.println(" ");
}
sbi(PORTB,LTC_CS); // LTC2400 CS hi
delay(20);
}
/********************************************************************/
byte SPI_read()
{
SPDR = 0;
while (!(SPSR & (1 << SPIF))) ; /* Wait for SPI shift out done */
return SPDR;
}
/********************************************************************/
// printFloat from tim / Arduino: Playground
// printFloat prints out the float 'value' rounded to 'places' places
//after the decimal point
void printFloat(float value, int places) {
// this is used to cast digits
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;
// if value is negative, set tempfloat to the abs value
// make sure we round properly. this could use pow from
//<math.h>, but doesn't seem worth the import
// if this rounding step isn't here, the value 54.321 prints as
// calculate rounding term d: 0.5/pow(10,places)
float d = 0.5;
if (value < 0)
d *= -1.0;
// divide by ten for each decimal place
for (i = 0; i < places; i++)
d/= 10.0;
// this small addition, combined with truncation will round our
tempfloat += d;
if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}
// write out the negative if needed
if (value < 0)
Serial.print('-');
if (tenscount == 0)
Serial.print(0, DEC);
for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
Serial.print(digit, DEC);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}
// if no places after decimal, stop now and return
if (places <= 0)
return;
// otherwise, write the point and continue on
Serial.print(',');
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
Serial.print(digit,DEC);
// once written, subtract off that digit
tempfloat = tempfloat - (float) digit;
}
}
Here is an example of the creep, as output on serial monitor:
Here is a picture of the board:
Here is the basic rundown.
I copied the above mentioned link's schematic as closely as I could in order to make the board. In summary, it uses the Arduino 5v source to a 100ohm resistor, a 10uf capacitor, the voltage regulator stepping down the voltage to 3.3v. The regulated 3.3v source is then fed into a 0.1uf capacitor and then used as the LTC2400 reference voltage. The LTC2400 uses the same 5v source for vcc that the regulator does. ADC in for the LTC2400 uses another 10uf capacitor tied to ground. All grounds (including ADCout) are tied to a single arduino ground wire. Clock is tied to vcc for 50hz rejection. All capacitor's positive legs are tied to either 3.3v, 5v, or ADCin, all negative leads are attached to ground.
Finally, here's the problem:
In measuring voltages, I got some substantial creep in readings, (see photo above) even when the ADCin and ADCout lines are not connected to anything. Over a minute or so, I would see voltages go from 0-1v. I verified that these voltages were actually in the line by my separate volt meter. This setup would read the voltage of the AA battery to the hundred properly (verified by same method to hundredth of a volt), but would creep even when the battery was connected. Also, strangely, I would get readings of ~1.64v with nothing connected to the lines (which is exactly 1/2 of measured output voltage by the lp2950-33, 3.28v)
In trying to figure this out-
-I pulled the 10uf capacitor on the ADCin line, no major effect, still creeping.
-I pulled the 0.1uf capacitor from the reference line, output signal suffered by fluctuating hundredth of a voltage instead of ten thousandth of a volt, still creeping although less obvious due high fluctuations.
-When I connect the volt meter to the ADCin, ADCout(GND) lines, the creep drops, then restarts (even if the leads are still connected)
-When I connect the volt meter to the regulated 3.3v and GND lines, the creep drops, then restarts (even if the leads are still connected)
-When I connect the volt meter to arduino 5v and GND lines, creep does NOT drop
After this, I'm at a loss. Clearly something isn't right, and it doesn't seem code related, or related to the capacitors (since I removed them and the problem is still there).
Advice, ideas, comments?