-
-
Save dariosalvi78/c100e035bc9fa50e4ac7f31f94c51e89 to your computer and use it in GitHub Desktop.
/* ADS1256 simple library for Arduino | |
ADS1256, datasheet: http://www.ti.com/lit/ds/sbas288j/sbas288j.pdf | |
connections to Atmega328 (UNO) | |
CLK - pin 13 | |
DIN - pin 11 (MOSI) | |
DOUT - pin 12 (MISO) | |
CS - pin 10 | |
DRDY - pin 9 | |
RESET- pin 8 (or tie HIGH?) | |
DVDD - 3V3 | |
DGND - GND | |
*/ | |
#define ADS_SPISPEED 1250000 | |
#define ADS_RST_PIN 8 //ADS1256 reset pin | |
#define ADS_RDY_PIN 9 //ADS1256 data ready | |
#define ADS_CS_PIN 10 //ADS1256 chip select | |
// 11, 12 and 13 are taken by the SPI | |
void initADS(){ | |
pinMode(ADS_CS_PIN, OUTPUT); | |
pinMode(ADS_RDY_PIN, INPUT); | |
pinMode(ADS_RST_PIN, OUTPUT); | |
digitalWrite(ADS_RST_PIN, LOW); | |
delay(1); // LOW at least 4 clock cycles of onboard clock. 100 microsecons is enough | |
digitalWrite(ADS_RST_PIN, HIGH); // now reset to deafult values | |
delay(150); | |
digitalWrite(ADS_CS_PIN, LOW); // select ADS | |
delayMicroseconds(50); | |
while (digitalRead(ADS_RDY_PIN)) {} // wait for ready_line to go low | |
SPI.beginTransaction(SPISettings(ADS_SPISPEED, MSBFIRST, SPI_MODE1)); | |
delayMicroseconds(10); | |
//Reset to Power-Up Values (FEh) | |
SPI.transfer(0xFE); | |
delayMicroseconds(100); | |
byte status_reg = 0 ; // address (datasheet p. 30) | |
byte status_data = 0x01; //status: Most Significant Bit First, Auto-Calibration Disabled, Analog Input Buffer Disabled | |
//0x03; //to activate buffer | |
SPI.transfer(0x50 | status_reg); | |
SPI.transfer(0x00); // 2nd command byte, write one register only | |
SPI.transfer(status_data); // write the databyte to the register | |
delayMicroseconds(10); | |
//PGA SETTING | |
//1 ±5V 000 (1) | |
//2 ±2.5V 001 (2) | |
//4 ±1.25V 010 (3) | |
//8 ±0.625V 011 (4) | |
//16 ±312.5mV 100 (5) | |
//32 ±156.25mV 101 (6) | |
//64 ±78.125mV 110 (7) OR 111 (8) | |
byte adcon_reg = 2; //A/D Control Register (Address 02h) | |
byte adcon_data = 0x20; // 0 01 00 000 => Clock Out Frequency = fCLKIN, Sensor Detect OFF, gain 1 | |
//0x25 for setting gain to 32, 0x27 to 64 | |
SPI.transfer(0x50 | adcon_reg); | |
SPI.transfer(0x00); // 2nd command byte, write one register only | |
SPI.transfer(adcon_data); // write the databyte to the register | |
delayMicroseconds(10); | |
digitalWrite(ADS_CS_PIN, HIGH); //unselect ADS | |
delayMicroseconds(50); | |
Serial.println("ADS1256 configured"); | |
} | |
long readADS(byte channel) { | |
long adc_val = 0; // unsigned long is on 32 bits | |
digitalWrite(ADS_CS_PIN, LOW); | |
delayMicroseconds(50); | |
SPI.beginTransaction(SPISettings(ADS_SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI | |
delayMicroseconds(10); | |
//The most efficient way to cycle through the inputs is to | |
//change the multiplexer setting (using a WREG command | |
//to the multiplexer register MUX) immediately after DRDY | |
//goes low. Then, after changing the multiplexer, restart the | |
//conversion process by issuing the SYNC and WAKEUP | |
//commands, and retrieve the data with the RDATA | |
//command. | |
while (digitalRead(ADS_RDY_PIN)) {} ; | |
byte data = (channel << 4) | (1 << 3); //AIN-channel and AINCOM | |
SPI.transfer(0x50 | 1); // write (0x50) MUX register (0x01) | |
SPI.transfer(0x00); // number of registers to be read/written − 1, write one register only | |
SPI.transfer(data); // write the databyte to the register | |
delayMicroseconds(10); | |
//SYNC command 1111 1100 | |
SPI.transfer(0xFC); | |
delayMicroseconds(10); | |
//WAKEUP 0000 0000 | |
SPI.transfer(0x00); | |
delayMicroseconds(10); | |
SPI.transfer(0x01); // Read Data 0000 0001 (01h) | |
delayMicroseconds(10); | |
adc_val = SPI.transfer(0); | |
adc_val <<= 8; //shift to left | |
adc_val |= SPI.transfer(0); | |
adc_val <<= 8; | |
adc_val |= SPI.transfer(0); | |
//The ADS1255/6 output 24 bits of data in Binary Two’s | |
//Complement format. The LSB has a weight of | |
//2VREF/(PGA(223 − 1)). A positive full-scale input produces | |
//an output code of 7FFFFFh and the negative full-scale | |
//input produces an output code of 800000h. | |
if (adc_val > 0x7fffff) { //if MSB == 1 | |
adc_val = 16777216ul - adc_val; //do 2's complement, discard sign | |
} | |
delayMicroseconds(10); | |
digitalWrite(ADS_CS_PIN, HIGH); | |
delayMicroseconds(50); | |
SPI.endTransaction(); | |
Serial.print("Got measurement from ADS "); | |
Serial.println(adc_val); | |
return adc_val; | |
} | |
long readADSDiff(byte positiveCh, byte negativeCh) { | |
long adc_val = 0; // unsigned long is on 32 bits | |
digitalWrite(ADS_CS_PIN, LOW); | |
delayMicroseconds(50); | |
SPI.beginTransaction(SPISettings(ADS_SPISPEED, MSBFIRST, SPI_MODE1)); | |
delayMicroseconds(10); | |
while (digitalRead(ADS_RDY_PIN)) {} ; | |
byte data = (positiveCh << 4) | negativeCh; //xxxx1000 - AINp = positiveCh, AINn = negativeCh | |
SPI.transfer(0x50 | 1); // write (0x50) MUX register (0x01) | |
SPI.transfer(0x00); // number of registers to be read/written − 1, write one register only | |
SPI.transfer(data); // write the databyte to the register | |
delayMicroseconds(10); | |
//SYNC command 1111 1100 | |
SPI.transfer(0xFC); | |
delayMicroseconds(10); | |
//WAKEUP 0000 0000 | |
SPI.transfer(0x00); | |
delayMicroseconds(10); | |
SPI.transfer(0x01); // Read Data 0000 0001 (01h) | |
delayMicroseconds(10); | |
adc_val = SPI.transfer(0); | |
adc_val <<= 8; //shift to left | |
adc_val |= SPI.transfer(0); | |
adc_val <<= 8; | |
adc_val |= SPI.transfer(0); | |
delayMicroseconds(10); | |
digitalWrite(ADS_CS_PIN, HIGH); | |
delayMicroseconds(50); | |
if (adc_val > 0x7fffff) { //if MSB == 1 | |
adc_val = adc_val - 16777216; //do 2's complement, keep the sign this time! | |
} | |
Serial.print("Got diff measurement from ADS "); | |
Serial.println(adc_val); | |
return adc_val; | |
} |
there's an Arduino library you can use also: https://github.com/adienakhmad/ADS1256
but if you still want to use this simple library, you can just call readADS(0), readADS(1), ... etc.
OK, Thanks a lot for your reply.
About the Lib from "adienakhmad", it is not compatible with ESP...
I've doublecheck your lib... Indeed I didn't have seen before this command !!! Looks pretty good. I gonna test that soon !!!
Hi Dario,
I have a question about your code. At my work I was given some functions to interact with an ADS1256 and some of the lines of codes are very similar but not quite and I can't anyone here, because the person that developed this code is not in the group anymore, so I thought to check with you if you don't mind.
In your code, in lines 106 and 160, you have this "adc_val = SPI.transfer(0);"
In the lines below, instead of the "=" there is the "|=". Is that done on purpose or there is a typo in lines 106 and 160?
Sorry, I am not that familiar with those things yet. I would really appreciate your help.
Thank you in advance.
I developed this code ages ago so I can't be of help. All I can say is that it worked.
I would invite you to get some understanding of C and particularly bitwise operators which is what is used that line.
Hi Dario,
Thank you very much. I will try to investigate this on my own and to refresh my memory about the bitwise operators in C.
I am sure it worked and I am thankful you shared it with us.
Best, Massimo
Hi,
I'm a beginner in programmation...
I've a pending project with ADS1256 and ESP8266.
Your simple library looks good but I would like to catch the 8 Analog channel values (0=>32768) with this type of code :
sensor1 = adc.readChannel(0);
sensor2 = adc.readChannel(1);
...
I've never use registers so... I don't know how to get the values from your code :(
Many thanks in advance !!!