RetroBSD

2.11BSD operating system for microcontrollers
It is currently Tue Mar 31, 2020 1:35 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Sun Dec 15, 2013 11:44 am 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2401
Location: Rapa Nui
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)
#

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Tue Dec 17, 2013 11:07 am 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2401
Location: Rapa Nui
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
#

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
PostPosted: Tue Dec 17, 2013 6:15 pm 
User avatar

Joined: Mon Nov 12, 2012 3:17 pm
Posts: 164
Location: Bratislava, Slovakia
Pito wrote:
Another demo.

adcread1110temp.c:
Code:
return 66;

Typo? Should be
Code:
return 666;

Indicating there is something seriously wrong.

_________________
http://jaromir.xf.cz/
https://hackaday.io/jaromir/


Top
 Profile  
 
PostPosted: Fri Dec 20, 2013 8:39 am 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2401
Location: Rapa Nui
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 14883 times ]

_________________
Pukao Hats Cleaning Services Ltd.
Top
 Profile  
 
PostPosted: Fri Oct 02, 2015 5:07 pm 
Contributor
User avatar

Joined: Thu Nov 08, 2012 7:04 am
Posts: 2401
Location: Rapa Nui
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
#

_________________
Pukao Hats Cleaning Services Ltd.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
cron




Powered by phpBB® Forum Software © phpBB Group

BSD Daemon used with permission