After the previous posts I wanted to do something more using Arduino and SPI Bus. Actually I’m working on a project in which I’m going to need an ADC and I need a little more precision than 10-bit ADC from Atmega328.

Looking for  a convenient ADC I found very interesting products in Linear Technology site. Mainly I was interested in LTC1298 and LTC1286 ADC. Both are similar products. Both are 12-bit, successive approximation sampling A/D converter and both are provided with SPI bus. But I like very much that there aren’t external components. Just the IC-to-IC connection.

I asked LT for free samples and a week later I get two LTC1298 in my home (Many thanks to Linear Technology). I tested with Bus Pirate and they just works fine.

The LTC1298 has two channel inputs (ch0 and ch1) that can be selected for the measure you want to. There are four options available:

  • Channel 0
  • Channel 1
  • Differential (Channel 0 – Channel 1)
  • Differential (Channel 1 – Channel 0)

Additionally, it’s possible to select the bit order in which the A/D converter sends the read value through SPI.

The Library

I wrote a simple library to use in Arduino with LTC1298. Basically I used the SPI functions I already wrote inside a new library with two new functions: One to initialize the communications (just calls the SPI_Init() function) and other to read the data from ADC.

The ltc1298_Read() function needs two parameters:

Mode:

  • CH0
  • CH1
  • DF0: Differential CH0-CH1
  • DF1: Differential CH1-CH0

Bit Order:

  • LSB: LSB First
  • MSB: MSB First

The function returns a 16bit value (But A/D is just 12-bit: 0×000~0xFFF).

To use the ltc1298 library after include it in your program you must to initialize the communication, placing ltc1298_Init() function somewhere into setup().

void setup(){
  ...
  ...
  ltc1298_Init();      /* Inicialize the comunication with LTC1298 */
  ...
  ...
}

Then, in your program you can read the Analog Data, specifying which channel are you reading from or how are you processing a differential channel measure. Give that data to a convinient variable space (at least 16bit wide).

void loop(){
   ...
   ...
   uint16_t Data_0=ltc1298_Read(CH0, MSB);
   uint16_t Data_1=ltc1298_Read(CH1, MSB);
   ...
   ...
}

Important note: In that library, is possible to specify the bit order (MSB or LSB). Is important using the same bit order in Master and Slave device.  At this time inside the Library the SPI configuration for Arduino is set to MSB. Due that, if you’re not changing the value in SPI configuration you must use MSB always.

You can Download the Library here.

Connecting

The connection between Arduino and LTC1298 uses a 4-wire SPI.

Arduino LTC1298
Pin Name Pin Name
10 SS 1 CS/SHDN
11 MOSI 5 DIN
12 MISO 6 DOUT
13 SCK 7 CLK

In LTC1298 Pin 4 and 8 are for supply connection (GND and +5V), and Pins 2 and 3 are the two analog channel inputs (CH0 and CH1).

Is very inportant to notice that Arduino pins from 10 to 13 are defined and used by Library to hold SPI Communication. So is not possible to give other use to those pins if your including the LTC1298 Library.

The Exemple Code

The following code can be found in Exemples folder, inside the Library.

/*
 *******************************************************
 *  Name:          LTC1298 Exemple    
 *
 *  Author:        Joan Martínez
 *
 *  Start Date:    1 Sept 2012        
 *
 *  Version Date:  1 Sept 2012 
 *
 *  Description:   Arduino as SPI Master controlling
 *                 an ADC LTC1298 from Linear Technology.
 *                 The library includes SPI driver. Take 
 *                 that in acount.
 *  Platform:      Arduino (Any...)
 *
 *******************************************************/

#include <ltc1298.h>

#define MEASURES 100

long int value;         /* Stores the read value */

void setup(){
  Serial.begin(9600);  /* Inicialize serial port */
  ltc1298_Init();      /* Inicialize the comunication with LTC1298 */
}

void loop(){
    /* Make 100 measures. Every read value 
    is added to the former one and then the 
    total is divided by 100. The result is 
    mapped and presented in a convenient way */

  value=0;
  for(int i=0; i<MEASURES; i++) value+=ltc1298_Read(CH0, MSB); /* ltc1298_Read() sends the 4-bit
                                   programming word for LTC1298
                                   and reads the Data from it */
  value=value/MEASURES;
  uint16_t newValue=map(value,0,4095,0,4899);
  uint8_t integerValue=newValue/1000;
  uint16_t decimalValue=newValue-1000*integerValue;
  Serial.print(integerValue);
  Serial.print('.');
  if(decimalValue<100) Serial.print('0');
  if(decimalValue<10) Serial.print('0');
  Serial.print(decimalValue);
  Serial.println(" V");  
  delay(1000);
}

The program measures CH0 from ADC 100 times and gives a mean value from it. That is a simple voltmeter.

Download the Library here.

Download LTC1298/LTC1286 Datasheet here.

About these ads