RetroBSD
http://retrobsd.org/

ADS1110 (16bit ADC) I2C driver
http://retrobsd.org/viewtopic.php?f=5&t=8562
Page 1 of 1

Author:  Pito [ Sun Dec 15, 2013 11:44 am ]
Post subject:  ADS1110 (16bit ADC) I2C driver

TI's ADS1110 is a cheap 16bit ADC in 6 pin sot23 smd package (true diff inputs, 1x 2x 4x 8x preamplifier, ref voltage, 16bit adc, I2C). The I2C addresses are hardwired, 8 addresses available. Enclosed a simple driver to try.

ads1110.h:
Code:
// Simple ADC ADS1110 driver
// Pito 12/2013

#include "i2c.h"

int adc1110init(unsigned char adr, unsigned char conf) {
   I2CStart();
   if (I2CSend(adr << 1) == NACK){
      I2CStop();
      return -1;
   }
   I2CSend(conf);
   I2CStop();
   return 0;
}

int adc1110read(unsigned char adr){
   unsigned char highbyte, lowbyte, configRegister;
   int data;
   I2CStart();
   if (I2CSend((adr << 1) | 0x01) == NACK){
      I2CStop();
      return -1;
   }
   highbyte = I2CRead(ACK);
   lowbyte = I2CRead(ACK);
   configRegister = I2CRead(ACK);

   data = (highbyte<<8) + lowbyte;
   I2CStop();
   return data;
}


adcread1110.c:
Code:
// DEMO - Simple ADS1110 16bit ADC READING
// returns adc value and adc value in uVolts
// Compile under uecide
// Pito 12/2012

#include "prxntf.h"    // using smaller printf
#include "ads1110.h"

// this ADC chip has got 0x4C address
#define ADC4  0x4C
// unipolar input (V- input wired to Gnd), 8x amplifier
// 256mV full scale (15bit), 8uV resolution
// 15 samples/sec, continuous conversion mode
#define MODE  0x8F

int main () {

   // init the pins driver
   if (pinsinit() < 0) return 66;

   // init the I2C
   I2CInit();

   // init the adc driver
   if (adc1110init(ADC4, MODE)< 0){
      prxntf("### ADC4 NOT AVAILABLE!\n");
                 pinsclose();
                 return 66;
   }
   prxntf("ADC = %d\n", adc1110read(ADC4));
   prxntf("ADC = %d uV\n", (int)(1000000*(adc1110read(ADC4)*6.2502e-5*0.125)));

   pinsclose();
   return 0;
}


Code:
# ./adcread1110
ADC = 25563
ADC = 199717 uV
# ./adcread1110
ADC = 25532
ADC = 199693 uV
# ./adcread1110
ADC = 25564
ADC = 199725 uV
# ./adcread1110
ADC = 25556
ADC = 199662 uV
#


Interestingly the ADS1110 responds to the 0 address (general call) as well:
Code:
# i2cscan
I2C dev found, adr(r/w): 00(01/00)  4C(99/98)  51(A3/A2)
#

Author:  Pito [ Tue Dec 17, 2013 11:07 am ]
Post subject:  Re: ADS1110 (16bit ADC) I2C driver

Another demo.

adcread1110temp.c:
Code:
// DEMO - LM35 and ADS1110 16bit ADC READING
// returns LM35 temperature value ( 0-51.199 degC)
// Compile under uecide
// Pito 12/2012

#include "prxntf.h"
#include "ads1110.h"

#define ADC4  0x4C

// 4x amplif. (512mV full scale), 15bit unipolar
// 15 samples/sec, continuous conversion mode
#define MODE  0x8E

int main () {
   int adc, temp_int, temp_frac;
   double tmp;
   // init the pins driver
   if (pinsinit() < 0) return 66;
   // init the I2C
   I2CInit();
   // init the adc driver
   if (adc1110init(ADC4, MODE)< 0){
      prxntf("### ADC4 NOT AVAILABLE!\n");
      pinsclose();
      return 66;
   }
   adc = adc1110read(ADC4);
   tmp = adc*6.2502e-5*0.25;   // voltage in Volts
   temp_int = (int)(100.0*tmp);  // LM35: 10mV = 1degC
   // and 3 decimal places
   temp_frac = (int)(1000.0*(100.0*tmp - temp_int));

   prxntf("Temp = %d.%03d degC\n", temp_int, temp_frac);

   pinsclose();
   return 0;
}


Code:
# ./adcread1110temp
Temp = 23.024 degC
# ./adcread1110temp
Temp = 23.022 degC
# ./adcread1110temp
Temp = 23.019 degC
# ./adcread1110temp
Temp = 23.017 degC
# ./adcread1110temp
Temp = 23.016 degC
#

Author:  jaromir [ Tue Dec 17, 2013 6:15 pm ]
Post subject:  Re: ADS1110 (16bit ADC) I2C driver

Pito wrote:
Another demo.

adcread1110temp.c:
Code:
return 66;

Typo? Should be
Code:
return 666;

Indicating there is something seriously wrong.

Author:  Pito [ Fri Dec 20, 2013 8:39 am ]
Post subject:  Re: ADS1110 (16bit ADC) I2C driver

And with sending out the data to UART1 (console at UART2) at 1Mbit/sec:

Code:
// DEMO - LM35 temperature sensor and ADS1110 16bit ADC
// Returns LM35 temperature value ( 0-50.999 degC)
// Prints out to UART1 (needs to be enabled in kernel)
// Compile under uecide
// Pito 12/2012

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sgtty.h>
#include "i2c.h"
#include "ads1110.h"

#define ADC4  0x4C

// 4x amplif. (512mV full scale), 15bit unipolar
// 15 sampl/sec, continuous mode
#define MODE  0x8E

int main () {
   int fd;
   char buf[20];
   int adc, temp_int, temp_frac;
   double tmp;

   // structure with Uart mode bits
   struct sgttyb mode;

   // open the Uart1
   if ((fd = open("/dev/tty0",O_RDWR)) < 0){
      printf("Unable to open the Uart1..\n");
      close(fd);
      return 66;
   }

   // set the Uart1 baud rate (1000kbaud)
   ioctl(fd, TIOCGETP, &mode);
   mode.sg_ispeed = mode.sg_ospeed = B1000000;
   ioctl(fd, TIOCSETN, &mode);

   // init the pins driver
   if (pinsinit() < 0) return 66;
   // init the I2C
   I2CInit();
   // init the adc driver
   if (adc1110init(ADC4, MODE)< 0){
      printf("### ADC4 NOT AVAILABLE!\n");
      pinsclose();
      return 66;
   }
   adc = adc1110read(ADC4);
   tmp = adc*6.2502e-5*0.25;   // voltage in V
   temp_int = (int)(100.0*tmp);  // LM35: 10mV = 1degC
   // and 3 decimal places
   temp_frac = (int)(1000.0*(100.0*tmp - temp_int));

   sprintf(buf, "Temp = %d.%03d degC\n", temp_int, temp_frac);

   // write the Uart1
   if ((write(fd, buf, sizeof(buf))) != sizeof(buf)) {
      printf("Unable to write the Uart1..\n");
      close(fd);
      return 66;
   }

   pinsclose();
   close(fd);
   return 0;
}


Uart1:
Code:
..
Temp = 23.269 degC
Temp = 23.267 degC
Temp = 23.267 degC
Temp = 23.266 degC
Temp = 23.271 degC


with:
Code:
# cat > temp
while true
do
./adcread1110temp1
done
# chmod +x temp
# ./temp &


Attachments:
uarts.jpg
uarts.jpg [ 55.84 KiB | Viewed 15327 times ]

Author:  Pito [ Fri Oct 02, 2015 5:07 pm ]
Post subject:  Re: ADS1110 (16bit ADC) I2C driver

The update for SmallerC (with the bitbanged i2c.h driver and float calc).
ADS1110rd.c
Code:
// DEMO - Simple ADS1110 16bit ADC READING
// returns adc value and adc value in Volts
// Compiled under SmallerC
// Pito 10/2015

#include <stdio.h>
#include "ADS1110.h"

// my ADC chip used has got the 0x4C address
#define ADC4  0x4C
// unipolar input (V- input wired to GND), 2x amplifier
// 1024mV full scale (15bit), 31.25uV resolution
// 15 samples/sec, continuous conversion mode
#define MODE  0x8D

// coef 3.125e-5
#define F_V_coef   0x3803126F

// 32-bit soft float
int __mulsf3(int, int);
#define MUL __mulsf3
int __fixsfsi(int);
int __floatsisf(int);
#define I2F __floatsisf
#define F2I __fixsfsi

int main () {

   int data;

   // init the pins driver
   if (pinsinit() < 0) return -1;

   // init the I2C
   I2CInit();

   // init the adc driver
   if (adc1110init(ADC4, MODE)< 0){
      printf("### ADC4 NOT AVAILABLE!\n");
                 pinsclose();
                 return -1;
   }
   
   data = adc1110read(ADC4);
   printf("ADC = %d\r\n", data);
   data = MUL(F_V_coef, I2F(data));
   printf("ADC = %1.5f V\r\n", data);
   pinsclose();
   return 0;
}

ADS1110.h
Code:
// Simple i2c ADC ADS1110 driver
// Pito 10/2015

#include "i2c.h"

int adc1110init(unsigned char adr, unsigned char conf) {
   I2CStart();
   if (I2CSend(adr << 1) == 1){
      I2CStop();
      return -1;
   }
   I2CSend(conf);
   I2CStop();
   return 0;
}

int adc1110read(unsigned char adr){
   unsigned char highbyte, lowbyte, configRegister;
   int data;
   I2CStart();
   if (I2CSend((adr << 1) | 0x01) == 1){
      I2CStop();
      return -1;
   }
   highbyte = I2CRead(1);
   lowbyte = I2CRead(1);
   configRegister = I2CRead(0);
   I2CStop();
   data = (highbyte<<8) + lowbyte;
   return data;
}


Code:
# i2cscan
I2C dev found, addr(r/w): 00(01/00)  1E(3D/3C)  4C(99/98)  53(A7/A6)  57(AF/AE)  68(D1/D0)  69(D3/D2)  77(EF/EE)

Code:
# cc -o ads ADS1110rd.c
# ./ads
ADC = 17604
ADC = 0.55013 V
# ./ads
ADC = 17599
ADC = 0.54997 V
# ./ads
ADC = 17600
ADC = 0.55000 V
#

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/