EDIT: The problems were fixed (it was some bad coding, confusion by direct port manipulation and ultimately an OR operation instead of an AND operation with direct port manipulation). A library has been written and is dowloadable here. Place it in the library folder of your Arduino install. It includes a readme with explanation of all functions, a sample sketch for channel selection, one for standard deviation and the datasheet. It can be easily adjusted for other, similar ADC chips. See the post here for more info.
Update 28/3/'12: Made compatible with Arduino 1.0, is still compatible with earlier versions. Nothing really changed except for the name of the Arduino library which was changed from Wiring.h to Arduino.h.
Hi, a few weeks ago I ordered an Arduino and since I've been really getting in to it. I've already used various sensors, used a LCD and written software for a new instrument I'm developing, including various menus and settings and data logging to EEPROM (actually I had already written a large part of it before the Arduino even arrived). The instrument I'm developing is for gliding, I want to measure the temperature of the air to detect thermals. So far we have always used variometers which detect the vertical speed, but the temperature is also a very valuable source of information as the increase in temperature is measurable outside the actual lift-sink boundary of the thermal.
My instrument will combine the variometer and the temperature sensor in a single audible signal, for easy processing by humans. A temperature measuring device has been made in the past but the problem was that it was a stand-alone device with its own audible signal, and it was really hard to concentrate on both the vario and temperature sound.
With the internal 10-bit ADC I'm able to get a .1*C sensitivity. It gives erratic data if the temperature is between 2 points, and I need more accuracy anyway. With more accuracy I could also implement some filters to filter noise and adjust sensitivity. So I ordered a Texas Instruments ADS1213 (was the only decent ADC available on ebay and had to buy it on ebay, because mouser, farnell and such charge insane shipping costs), which is accessible by SPI. It also has a very high sample rate of 1k SPS at an effective resolution of 16 bits and something like 3.5SPS at an amazing 22 bits. The fastest setting would allow me to get an accuracy of 65 times the Arduino's internal ADC, which equals .0015 *C. I spent yesterday reading the datasheet and trying to figure out how to make it work.
I did the following:
- As the ADS1213 needs an external clock, I hacked together some code to configure Timer2 to output a 1MHz signal (the recommended nominal value).
- I hacked together some other code to try to bit-bang SPI. In part because setting Timer2 to 1MHz makes pin 11 unusable too, and that's one of the hardware SPI ports. In the datasheet there were some minimum times and as I was worried that the Arduino would switch signals too fast, I built in some delays. Also, the code I took was written for a MCP3208 which changes data on the falling side of the SPI clock signal, and I modified it to change data on the rising side of the SPI clock signal.
Here's my pin connections and setup:
ADC pin
4 non-inverting input channel 1 Thermistor
6 Analog GND
8 Chip Select Pin 8
10 Crystal in Pin 3
12 Digital GND
13 Digital +5V
14 Xin, Serial Clock Pin 13
15 Serial in/out Pin 10 (MOSI)
16 Serial out Pin 12 (MISO)
17 Data Ready (high = ready) Pin 4
18 Mode (0 = slave) GND
19 Analog +5V
20 Refout > Refin
21 Refin < Refout
Here's my commented code, it polls every 1/2 second if data is available (data is available at >300Hz per second but I poll every 1/2 second to avoid too much data on the screen).
*** See post below for code, apparently I exceed the limit of 9500 characters ***
The problem is that I only get bogus data, sometimes it returns 14 or 15 bits of mainly 1's, sometimes it returns the complete long filled primarily with 1's. I don't really get why this is happening, since it shouldn't even be possible. I tried to vary the delay times and even delete them but it made no difference. I tried to read the command register which I wrote to in setup() but it just gave a 0.
Here's the ADS1213 datasheet: http://focus.ti.com/lit/ds/symlink/ads1213.pdf and product page: ADS1213 data sheet, product information and support | TI.com
Problems I could imagine myself:
- The clock output on pin 3 is not working correctly. Though if I unplug it, I get no data at all.
- The Refout > Refin should be connected to ground with a capacitor like in the datasheet?
- The ADS1213 doesn't like the Clock input from Arduino's pin 3, because it is either a different frequency or it really does like real crystals that produce sine waves more. In the datasheet it says that it does like real crystals more because they produce sine waves, but it also says somewhere that Xin can be connected to a microcontroller to be able to vary the power consumption on the fly.
- I fucked up somewhere in the code or connections but don't see it because I have too little experience with interfacing. (the most viable option...)
I'd really appreciate it if someone would take a look at my code and connections and see where it went wrong. When (or if?) it is working it can maybe also be converted into a library to aid other people in need of a very precise ADC.