├── LICENSE ├── README.md ├── examples ├── ADS1256_Basic_Switching_Channel │ └── ADS1256_Basic_Switching_Channel.ino └── ADS1256_Efficient_Input_Cycling │ └── ADS1256_Efficient_Input_Cycling.ino ├── keywords.txt ├── ADS1256.h └── ADS1256.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Adien Akhmad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ADS1256 2 | Arduino Library for Texas Instrument ADS1256, working with Arduino IDE 1.8.5, Arduino UNO 3 | 4 | # Installation 5 | As any arduino library (import library) 6 | 7 | # Wiring 8 | ADS Board - Arduino UNO Board 9 | 10 | 5V - 5V 11 | 12 | GND - GND 13 | 14 | SCLK - pin 13 (SCK) 15 | 16 | DIN - pin 11 (MOSI) 17 | 18 | DOUT - pin 12 (MISO) 19 | 20 | DRDY - pin 9 21 | 22 | CS - pin 10 23 | 24 | POWN - 5V 25 | 26 | 27 | # Examples 28 | Basic_Switching_Channel: How to change the channels 29 | 30 | ADS1256_Efficient_Input_Cycling: Read and print 31 | 32 | # Functions 33 | 34 | ADS1256 adc(clockSpeed in Mhz, VREF in volt, boolean if use RESET PIN ): Class Constructor: 35 | 36 | adc.sendCommand(SDATAC): Send SDATAC to stop reading contionus data, so we can send other command 37 | 38 | adc.waitDRDY(): Waits for the data ready flag (ADC conversion ended and ready to be read) 39 | 40 | adc.setChannel(x): Sets the channels to be read in next reading cycle, configured in "single end" (reads between the "x" input AINx and ground GND) 41 | 42 | adc.setChannel(i,j): Sets the channels to be read in next reading cycle, configured in "differential mode", first argument (i) is the positive input and second argument (j) is negative input to ADC. As stated in device datasheet any combination (i,j) (between 0 and 7) is possible but it's recomended to use adjacent inputs (0 and 1, 2 and 3, etc) 43 | 44 | adc.readRegister(reg): Returns value of the register "reg" 45 | 46 | adc.readCurrentChannel(): Returns the value of the current reading stored in ADC 47 | 48 | #Notice: Working as 5/1/2019 49 | 50 | -------------------------------------------------------------------------------- /examples/ADS1256_Basic_Switching_Channel/ADS1256_Basic_Switching_Channel.ino: -------------------------------------------------------------------------------- 1 | // Arudino Sample Code to use ADS1256 library 2 | // Switching channel for ADS1256. 3 | // This sample code writes to MUX register and reads ADC values back. 4 | // First for loop reads all channels in single ended mode. 5 | // Second for loop reads 4 differential channels 6 | // The purpose of this code is to show how to use switchChannel function. 7 | // Written by Adien Akhmad, August 2015 8 | // Modfified Jan 2019 by Axel Sepulveda for ATMEGA328 9 | 10 | #include 11 | #include 12 | 13 | // Initialize ADS1256 object 14 | ADS1256 adc(7.68, 2.5, true ); // clockSpeed in Mhz, VREF in volt, if use RESET PIN 15 | 16 | void setup() 17 | { 18 | Serial.begin(9600); 19 | 20 | // Sending SDATAC to stop reading contionus data, so we can send other command 21 | adc.sendCommand(SDATAC); 22 | Serial.println("SDATAC command sent"); 23 | 24 | /* Single Ended Mode 25 | ADS1256 support 8 single ended channel 26 | use setChannel(p) for this purpose, where p is the number of positive input channel between 0 and 7 (AIN0 to AIN7). 27 | AINCOM are automatically set as the negative input channel. 28 | */ 29 | 30 | Serial.println("Changing channel for single ended mode."); 31 | 32 | for (int i = 0; i < 8; ++i) 33 | { 34 | adc.waitDRDY(); 35 | adc.setChannel(i); 36 | Serial.print("Current Channel: "); 37 | Serial.println(adc.readRegister(MUX),HEX); // Read the multiplex register to see the current active channel 38 | //Should it be? adc.readCurrentChannel() 39 | } 40 | 41 | /* Differential Mode 42 | ADS1256 support 4 differential channel 43 | use setChannel(p,n) for this purpose, where 44 | p is the number of positive input channel between 0 and 7 (AIN0 to AIN7), 45 | n is the number of negative input channel between 0 and 7 (AIN0 to AIN7). 46 | */ 47 | 48 | Serial.println("Changing channel for differential mode."); 49 | 50 | for (int i = 0; i < 8; i+=2) 51 | { 52 | adc.waitDRDY(); 53 | adc.setChannel(i,i+1); 54 | Serial.print("Current Channel: "); 55 | Serial.println(adc.readRegister(MUX),HEX); // Read the multiplex register to see the current active channel 56 | //Should it be? adc.readCurrentChannel() 57 | } 58 | 59 | // Please note that AINCOM is defined as channel number 8 60 | // When you read the serial output, 61 | // 08h means AIN0 - AINCOM 62 | // 18h means AIN1 - AINCOM 63 | // 28h means AIN2 - AINCOM 64 | // etc 65 | 66 | } 67 | 68 | void loop() 69 | { 70 | 71 | } 72 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ADS1256 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | writeRegister KEYWORD2 15 | readRegister KEYWORD2 16 | sendCommand KEYWORD2 17 | readChannel KEYWORD2 18 | setConversionFactor KEYWORD2 19 | switchChannel KEYWORD2 20 | start KEYWORD2 21 | waitDRDY KEYWORD2 22 | 23 | 24 | ###################################### 25 | # Constants (LITERAL1) 26 | ####################################### 27 | STATUS LITERAL1 28 | MUX LITERAL1 29 | ADCON LITERAL1 30 | DRATE LITERAL1 31 | IO LITERAL1 32 | OFC0 LITERAL1 33 | OFC1 LITERAL1 34 | OFC2 LITERAL1 35 | FSC0 LITERAL1 36 | FSC1 LITERAL1 37 | FSC2 LITERAL1 38 | 39 | 40 | WAKEUP LITERAL1 41 | RDATA LITERAL1 42 | RDATAC LITERAL1 43 | SDATAC LITERAL1 44 | RREG LITERAL1 45 | WREG LITERAL1 46 | SELFCAL LITERAL1 47 | SELFOCAL LITERAL1 48 | SELFGCAL LITERAL1 49 | SYSOCAL LITERAL1 50 | SYSGCAL LITERAL1 51 | SYNC LITERAL1 52 | STANDBY LITERAL1 53 | RESET LITERAL1 54 | 55 | 56 | 57 | ADS1256_MUXP_AIN0 LITERAL1 58 | ADS1256_MUXP_AIN1 LITERAL1 59 | ADS1256_MUXP_AIN2 LITERAL1 60 | ADS1256_MUXP_AIN3 LITERAL1 61 | ADS1256_MUXP_AIN4 LITERAL1 62 | ADS1256_MUXP_AIN5 LITERAL1 63 | ADS1256_MUXP_AIN6 LITERAL1 64 | ADS1256_MUXP_AIN7 LITERAL1 65 | ADS1256_MUXP_AINCOM LITERAL1 66 | 67 | ADS1256_MUXN_AIN0 LITERAL1 68 | ADS1256_MUXN_AIN1 LITERAL1 69 | ADS1256_MUXN_AIN2 LITERAL1 70 | ADS1256_MUXN_AIN3 LITERAL1 71 | ADS1256_MUXN_AIN4 LITERAL1 72 | ADS1256_MUXN_AIN5 LITERAL1 73 | ADS1256_MUXN_AIN6 LITERAL1 74 | ADS1256_MUXN_AIN7 LITERAL1 75 | ADS1256_MUXN_AINCOM LITERAL1 76 | 77 | ADS1256_GAIN_1 LITERAL1 78 | ADS1256_GAIN_2 LITERAL1 79 | ADS1256_GAIN_4 LITERAL1 80 | ADS1256_GAIN_8 LITERAL1 81 | ADS1256_GAIN_16 LITERAL1 82 | ADS1256_GAIN_32 LITERAL1 83 | ADS1256_GAIN_64 LITERAL1 84 | 85 | 86 | ADS1256_DRATE_30000SPS LITERAL1 87 | ADS1256_DRATE_15000SPS LITERAL1 88 | ADS1256_DRATE_7500SPS LITERAL1 89 | ADS1256_DRATE_3750SPS LITERAL1 90 | ADS1256_DRATE_2000SPS LITERAL1 91 | ADS1256_DRATE_1000SPS LITERAL1 92 | ADS1256_DRATE_500SPS LITERAL1 93 | ADS1256_DRATE_100SPS LITERAL1 94 | ADS1256_DRATE_60SPS LITERAL1 95 | ADS1256_DRATE_50SPS LITERAL1 96 | ADS1256_DRATE_30SPS LITERAL1 97 | ADS1256_DRATE_25SPS LITERAL1 98 | ADS1256_DRATE_15SPS LITERAL1 99 | ADS1256_DRATE_10SPS LITERAL1 100 | ADS1256_DRATE_5SPS LITERAL1 101 | ADS1256_DRATE_2_5SPS LITERAL1 102 | -------------------------------------------------------------------------------- /examples/ADS1256_Efficient_Input_Cycling/ADS1256_Efficient_Input_Cycling.ino: -------------------------------------------------------------------------------- 1 | // Arudino Sample Code to use ADS1256 library 2 | 3 | // Efficient Input Cycling 4 | // Reads 4 differential channels using effiecient input cycling 5 | /* Sensor reading: 6 | sensor1 = differential input connected on AIN0 - AIN1 7 | sensor2 = differential input connected on AIN2 - AIN3 8 | sensor3 = differential input connected on AIN4 - AIN5 9 | sensor4 = differential input connected on AIN6 - AIN7 10 | */ 11 | // to learn further, read on datasheet page 21, figure 19 : Cycling the ADS1256 Input Multiplexer 12 | 13 | // http://www.ti.com/lit/ds/symlink/ads1256.pdf 14 | 15 | // Written by Adien Akhmad, August 2015 16 | // Modfified Jan 2019 by Axel Sepulveda for ATMEGA328 17 | 18 | 19 | #include 20 | #include 21 | 22 | float clockMHZ = 7.68; // crystal frequency used on ADS1256 23 | float vRef = 2.5; // voltage reference 24 | // Initialize ADS1256 object 25 | ADS1256 adc(clockMHZ,vRef,false); // RESETPIN is permanently tied to 3.3v 26 | 27 | 28 | 29 | float sensor1, sensor2, sensor3, sensor4; 30 | 31 | 32 | void setup() 33 | { 34 | Serial.begin(9600); 35 | 36 | Serial.println("Starting ADC"); 37 | 38 | // start the ADS1256 with data rate of 15 SPS 39 | // other data rates: 40 | // ADS1256_DRATE_30000SPS 41 | // ADS1256_DRATE_15000SPS 42 | // ADS1256_DRATE_7500SPS 43 | // ADS1256_DRATE_3750SPS 44 | // ADS1256_DRATE_2000SPS 45 | // ADS1256_DRATE_1000SPS 46 | // ADS1256_DRATE_500SPS 47 | // ADS1256_DRATE_100SPS 48 | // ADS1256_DRATE_60SPS 49 | // ADS1256_DRATE_50SPS 50 | // ADS1256_DRATE_30SPS 51 | // ADS1256_DRATE_25SPS 52 | // ADS1256_DRATE_15SPS 53 | // ADS1256_DRATE_10SPS 54 | // ADS1256_DRATE_5SPS 55 | // ADS1256_DRATE_2_5SPS 56 | // 57 | // NOTE : Data Rate vary depending on crystal frequency. Data rates listed below assumes the crystal frequency is 7.68Mhz 58 | // for other frequency consult the datasheet. 59 | //Posible Gains 60 | //ADS1256_GAIN_1 61 | //ADS1256_GAIN_2 62 | //ADS1256_GAIN_4 63 | //ADS1256_GAIN_8 64 | //ADS1256_GAIN_16 65 | //ADS1256_GAIN_32 66 | //ADS1256_GAIN_64 67 | adc.begin(ADS1256_DRATE_15SPS,ADS1256_GAIN_1,false); 68 | 69 | Serial.println("ADC Started"); 70 | 71 | // Set MUX Register to AINO and AIN1 so it start doing the ADC conversion 72 | adc.setChannel(0,1); 73 | } 74 | 75 | void loop() 76 | { 77 | 78 | // Efficient Input Cycling 79 | // to learn further, read on datasheet page 21, figure 19 : Cycling the ADS1256 Input Multiplexer 80 | 81 | adc.waitDRDY(); // wait for DRDY to go low before changing multiplexer register 82 | adc.setChannel(2,3); // Set the MUX for differential between ch2 and 3 83 | sensor1 = adc.readCurrentChannel(); // DOUT arriving here are from MUX AIN0 and AIN1 84 | 85 | adc.waitDRDY(); 86 | adc.setChannel(4,5); 87 | sensor2 = adc.readCurrentChannel(); //// DOUT arriving here are from MUX AIN2 and AIN3 88 | 89 | adc.waitDRDY(); 90 | adc.setChannel(6,7); 91 | sensor3 = adc.readCurrentChannel(); // DOUT arriving here are from MUX AIN4 and AIN5 92 | 93 | adc.waitDRDY(); 94 | adc.setChannel(0,1); // switch back to MUX AIN0 and AIN1 95 | sensor4 = adc.readCurrentChannel(); // DOUT arriving here are from MUX AIN6 and AIN7 96 | 97 | //print the result. 98 | Serial.print(sensor1,10); 99 | Serial.print("\t"); 100 | Serial.print(sensor2,10); 101 | Serial.print("\t"); 102 | Serial.print(sensor3,10); 103 | Serial.print("\t"); 104 | Serial.println(sensor4,10); 105 | } 106 | 107 | -------------------------------------------------------------------------------- /ADS1256.h: -------------------------------------------------------------------------------- 1 | /* 2 | ADS1256.h - Arduino Library for communication with Texas Instrument ADS1256 ADC 3 | Written by Adien Akhmad, August 2015 4 | Modifified Jan 2019 by Axel Sepulveda for ATMEGA328 5 | */ 6 | 7 | #ifndef ADS1256_h 8 | #define ADS1256_h 9 | 10 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) 11 | // Define PORT 12 | #define PORT_DRDY PORTB // Pin 9 on Arduino UNO 13 | #define PIN_DRDY PINB 14 | #define PINDEX_DRDY PB1 15 | #define DDR_DRDY DDRB 16 | 17 | #define PORT_CS PORTB // Pin 10 on Arduino UNO 18 | #define PIN_CS PINB 19 | #define PINDEX_CS PB2 20 | #define DDR_CS DDRB 21 | 22 | #define PORT_RESET PORTB // PIN 8 on Arduino UNO 23 | #define PIN_REST PINB 24 | #define PINDEX_RESET PB0 25 | #define DDR_RESET DDRB 26 | 27 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 28 | // Define PORT 29 | #define PORT_DRDY PORTL // Pin 49 on Arduino Mega 30 | #define PIN_DRDY PINL 31 | #define PINDEX_DRDY PL0 32 | #define DDR_DRDY DDRL 33 | 34 | #define PORT_CS PORTB // Pin 53 on Arduino Mega 35 | #define PIN_CS PINB 36 | #define PINDEX_CS PB0 37 | #define DDR_CS DDRB 38 | 39 | #define PORT_RESET PORTL // PIN 48 on Arduino Mega 40 | #define PIN_REST PINL 41 | #define PINDEX_RESET PL1 42 | #define DDR_RESET DDRL 43 | 44 | // Contributions are welcome 45 | #elif defined(ARDUINO_ARCH_ESP32) 46 | #error "Oops! ESP32 architecture not supported yet" 47 | // Contributions are welcome 48 | #else 49 | // Contributions are welcome 50 | #error "Oops! Your board architecture is not supported yet'" 51 | #endif 52 | // ADS1256 Register 53 | #define STATUS 0x00 54 | #define MUX 0x01 55 | #define ADCON 0x02 56 | #define DRATE 0x03 57 | #define IO 0x04 58 | #define OFC0 0x05 59 | #define OFC1 0x06 60 | #define OFC2 0x07 61 | #define FSC0 0x08 62 | #define FSC1 0x09 63 | #define FSC2 0x0A 64 | 65 | // ADS1256 Command 66 | #define WAKEUP 0x00 67 | #define RDATA 0x01 68 | #define RDATAC 0x03 69 | #define SDATAC 0x0f 70 | #define RREG 0x10 71 | #define WREG 0x50 72 | #define SELFCAL 0xF0 73 | #define SELFOCAL 0xF1 74 | #define SELFGCAL 0xF2 75 | #define SYSOCAL 0xF3 76 | #define SYSGCAL 0xF4 77 | #define SYNC 0xFC 78 | #define STANDBY 0xFD 79 | #define RESET 0xFE 80 | 81 | // define multiplexer codes 82 | #define ADS1256_MUXP_AIN0 0x00 83 | #define ADS1256_MUXP_AIN1 0x10 84 | #define ADS1256_MUXP_AIN2 0x20 85 | #define ADS1256_MUXP_AIN3 0x30 86 | #define ADS1256_MUXP_AIN4 0x40 87 | #define ADS1256_MUXP_AIN5 0x50 88 | #define ADS1256_MUXP_AIN6 0x60 89 | #define ADS1256_MUXP_AIN7 0x70 90 | #define ADS1256_MUXP_AINCOM 0x80 91 | 92 | #define ADS1256_MUXN_AIN0 0x00 93 | #define ADS1256_MUXN_AIN1 0x01 94 | #define ADS1256_MUXN_AIN2 0x02 95 | #define ADS1256_MUXN_AIN3 0x03 96 | #define ADS1256_MUXN_AIN4 0x04 97 | #define ADS1256_MUXN_AIN5 0x05 98 | #define ADS1256_MUXN_AIN6 0x06 99 | #define ADS1256_MUXN_AIN7 0x07 100 | #define ADS1256_MUXN_AINCOM 0x08 101 | 102 | // define gain codes 103 | #define ADS1256_GAIN_1 0x00 104 | #define ADS1256_GAIN_2 0x01 105 | #define ADS1256_GAIN_4 0x02 106 | #define ADS1256_GAIN_8 0x03 107 | #define ADS1256_GAIN_16 0x04 108 | #define ADS1256_GAIN_32 0x05 109 | #define ADS1256_GAIN_64 0x06 110 | 111 | // define drate codes 112 | /* 113 | NOTE : Data Rate vary depending on crystal frequency. Data rates 114 | listed below assumes the crystal frequency is 7.68Mhz 115 | for other frequency consult the datasheet. 116 | */ 117 | 118 | #define ADS1256_DRATE_30000SPS 0xF0 119 | #define ADS1256_DRATE_15000SPS 0xE0 120 | #define ADS1256_DRATE_7500SPS 0xD0 121 | #define ADS1256_DRATE_3750SPS 0xC0 122 | #define ADS1256_DRATE_2000SPS 0xB0 123 | #define ADS1256_DRATE_1000SPS 0xA1 124 | #define ADS1256_DRATE_500SPS 0x92 125 | #define ADS1256_DRATE_100SPS 0x82 126 | #define ADS1256_DRATE_60SPS 0x72 127 | #define ADS1256_DRATE_50SPS 0x63 128 | #define ADS1256_DRATE_30SPS 0x53 129 | #define ADS1256_DRATE_25SPS 0x43 130 | #define ADS1256_DRATE_15SPS 0x33 131 | #define ADS1256_DRATE_10SPS 0x23 132 | #define ADS1256_DRATE_5SPS 0x13 133 | #define ADS1256_DRATE_2_5SPS 0x03 134 | 135 | #include "Arduino.h" 136 | #include "SPI.h" 137 | 138 | class ADS1256 { 139 | public: 140 | ADS1256(float clockspdMhz, float vref, bool useresetpin); 141 | void writeRegister(unsigned char reg, unsigned char wdata); 142 | unsigned char readRegister(unsigned char reg); 143 | void sendCommand(unsigned char cmd); 144 | float readCurrentChannel(); 145 | void setConversionFactor(float val); 146 | void setChannel(byte channel); 147 | void setChannel(byte AIP, byte AIN); 148 | void begin(unsigned char drate, unsigned char gain, bool bufferenable); 149 | void waitDRDY(); 150 | void setGain(uint8_t gain); 151 | void readTest(); 152 | 153 | private: 154 | void CSON(); 155 | void CSOFF(); 156 | unsigned long read_uint24(); 157 | long read_int32(); 158 | float read_float32(); 159 | byte _pga; 160 | float _VREF; 161 | float _conversionFactor; 162 | }; 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /ADS1256.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ADS1256.h - Arduino Library for communication with Texas Instrument ADS1256 ADC 3 | Written by Adien Akhmad, August 2015 4 | Modfified Jan 2019 by Axel Sepulveda for ATMEGA328 5 | */ 6 | 7 | #include "ADS1256.h" 8 | #include "Arduino.h" 9 | #include "SPI.h" 10 | 11 | ADS1256::ADS1256(float clockspdMhz, float vref, bool useResetPin) { 12 | // Set DRDY as input 13 | DDR_DRDY &= ~(1 << PINDEX_DRDY); 14 | // Set CS as output 15 | DDR_CS |= (1 << PINDEX_CS); 16 | 17 | if (useResetPin) { 18 | // set RESETPIN as output 19 | DDR_RESET |= (1 << PINDEX_RESET); 20 | // pull RESETPIN high 21 | PORT_RESET |= (1 << PINDEX_RESET); 22 | } 23 | 24 | // Voltage Reference 25 | _VREF = vref; 26 | 27 | // Default conversion factor 28 | _conversionFactor = 1.0; 29 | 30 | // Start SPI on a quarter of ADC clock speed 31 | SPI.begin(); 32 | SPI.beginTransaction( 33 | SPISettings(clockspdMhz * 1000000 / 4, MSBFIRST, SPI_MODE1)); 34 | } 35 | 36 | void ADS1256::writeRegister(unsigned char reg, unsigned char wdata) { 37 | CSON(); 38 | SPI.transfer(WREG | reg); 39 | SPI.transfer(0); 40 | SPI.transfer(wdata); 41 | __builtin_avr_delay_cycles(8); // t11 delay (4*tCLKIN) after WREG command, 42 | // 16Mhz avr clock is approximately twice 43 | // faster that 7.68 Mhz ADS1256 master clock 44 | CSOFF(); 45 | } 46 | 47 | unsigned char ADS1256::readRegister(unsigned char reg) { 48 | unsigned char readValue; 49 | 50 | CSON(); 51 | SPI.transfer(RREG | reg); 52 | SPI.transfer(0); 53 | __builtin_avr_delay_cycles(200); // t6 delay (50*tCLKIN), 16Mhz avr clock is 54 | // approximately twice faster that 7.68 Mhz 55 | // ADS1256 master clock 56 | readValue = SPI.transfer(0); 57 | __builtin_avr_delay_cycles(8); // t11 delay 58 | CSOFF(); 59 | 60 | return readValue; 61 | } 62 | 63 | void ADS1256::sendCommand(unsigned char reg) { 64 | CSON(); 65 | waitDRDY(); 66 | SPI.transfer(reg); 67 | __builtin_avr_delay_cycles(8); // t11 68 | CSOFF(); 69 | } 70 | 71 | void ADS1256::setConversionFactor(float val) { _conversionFactor = val; } 72 | 73 | void ADS1256::readTest() { 74 | unsigned char _highByte, _midByte, _lowByte; 75 | CSON(); 76 | SPI.transfer(RDATA); 77 | __builtin_avr_delay_cycles(200); // t6 delay 78 | 79 | _highByte = SPI.transfer(WAKEUP); 80 | _midByte = SPI.transfer(WAKEUP); 81 | _lowByte = SPI.transfer(WAKEUP); 82 | 83 | CSOFF(); 84 | } 85 | 86 | float ADS1256::readCurrentChannel() { 87 | CSON(); 88 | SPI.transfer(RDATA); 89 | __builtin_avr_delay_cycles(200); // t6 delay 90 | float adsCode = read_float32(); 91 | CSOFF(); 92 | return ((adsCode / 0x7FFFFF) * ((2 * _VREF) / (float)_pga)) * 93 | _conversionFactor; 94 | } 95 | 96 | // Call this ONLY after RDATA command 97 | unsigned long ADS1256::read_uint24() { 98 | unsigned char _highByte, _midByte, _lowByte; 99 | unsigned long value; 100 | 101 | _highByte = SPI.transfer(WAKEUP); 102 | _midByte = SPI.transfer(WAKEUP); 103 | _lowByte = SPI.transfer(WAKEUP); 104 | 105 | // Combine all 3-bytes to 24-bit data using byte shifting. 106 | value = ((long)_highByte << 16) + ((long)_midByte << 8) + ((long)_lowByte); 107 | return value; 108 | } 109 | 110 | // Call this ONLY after RDATA command 111 | long ADS1256::read_int32() { 112 | long value = read_uint24(); 113 | 114 | if (value & 0x00800000) { 115 | value |= 0xff000000; 116 | } 117 | 118 | return value; 119 | } 120 | 121 | // Call this ONLY after RDATA command 122 | float ADS1256::read_float32() { 123 | long value = read_int32(); 124 | return (float)value; 125 | } 126 | 127 | // Channel switching for single ended mode. Negative input channel are 128 | // automatically set to AINCOM 129 | void ADS1256::setChannel(byte channel) { setChannel(channel, -1); } 130 | 131 | // Channel Switching for differential mode. Use -1 to set input channel to 132 | // AINCOM 133 | void ADS1256::setChannel(byte AIN_P, byte AIN_N) { 134 | unsigned char MUX_CHANNEL; 135 | unsigned char MUXP; 136 | unsigned char MUXN; 137 | 138 | switch (AIN_P) { 139 | case 0: 140 | MUXP = ADS1256_MUXP_AIN0; 141 | break; 142 | case 1: 143 | MUXP = ADS1256_MUXP_AIN1; 144 | break; 145 | case 2: 146 | MUXP = ADS1256_MUXP_AIN2; 147 | break; 148 | case 3: 149 | MUXP = ADS1256_MUXP_AIN3; 150 | break; 151 | case 4: 152 | MUXP = ADS1256_MUXP_AIN4; 153 | break; 154 | case 5: 155 | MUXP = ADS1256_MUXP_AIN5; 156 | break; 157 | case 6: 158 | MUXP = ADS1256_MUXP_AIN6; 159 | break; 160 | case 7: 161 | MUXP = ADS1256_MUXP_AIN7; 162 | break; 163 | default: 164 | MUXP = ADS1256_MUXP_AINCOM; 165 | } 166 | 167 | switch (AIN_N) { 168 | case 0: 169 | MUXN = ADS1256_MUXN_AIN0; 170 | break; 171 | case 1: 172 | MUXN = ADS1256_MUXN_AIN1; 173 | break; 174 | case 2: 175 | MUXN = ADS1256_MUXN_AIN2; 176 | break; 177 | case 3: 178 | MUXN = ADS1256_MUXN_AIN3; 179 | break; 180 | case 4: 181 | MUXN = ADS1256_MUXN_AIN4; 182 | break; 183 | case 5: 184 | MUXN = ADS1256_MUXN_AIN5; 185 | break; 186 | case 6: 187 | MUXN = ADS1256_MUXN_AIN6; 188 | break; 189 | case 7: 190 | MUXN = ADS1256_MUXN_AIN7; 191 | break; 192 | default: 193 | MUXN = ADS1256_MUXN_AINCOM; 194 | } 195 | 196 | MUX_CHANNEL = MUXP | MUXN; 197 | 198 | CSON(); 199 | writeRegister(MUX, MUX_CHANNEL); 200 | sendCommand(SYNC); 201 | sendCommand(WAKEUP); 202 | CSOFF(); 203 | } 204 | 205 | void ADS1256::begin(unsigned char drate, unsigned char gain, bool buffenable) { 206 | _pga = 1 << gain; 207 | sendCommand( 208 | SDATAC); // send out SDATAC command to stop continous reading mode. 209 | writeRegister(DRATE, drate); // write data rate register 210 | uint8_t bytemask = B00000111; 211 | uint8_t adcon = readRegister(ADCON); 212 | uint8_t byte2send = (adcon & ~bytemask) | gain; 213 | writeRegister(ADCON, byte2send); 214 | if (buffenable) { 215 | uint8_t status = readRegister(STATUS); 216 | bitSet(status, 1); 217 | writeRegister(STATUS, status); 218 | } 219 | sendCommand(SELFCAL); // perform self calibration 220 | waitDRDY(); 221 | ; // wait ADS1256 to settle after self calibration 222 | } 223 | 224 | void ADS1256::CSON() { 225 | PORT_CS &= ~(1 << PINDEX_CS); 226 | } // digitalWrite(_CS, LOW); } 227 | 228 | void ADS1256::CSOFF() { 229 | PORT_CS |= (1 << PINDEX_CS); 230 | } // digitalWrite(_CS, HIGH); } 231 | 232 | void ADS1256::waitDRDY() { 233 | while (PIN_DRDY & (1 << PINDEX_DRDY)) 234 | ; 235 | } 236 | --------------------------------------------------------------------------------