Hello,
I'm working with an ADS1256 and arduino. I'm having what seems an odd problem(to me anyway), the First read and every other read of either data or registers results in all 1s, The remainder of reads seem to be correct.
ie if i read in the value of all the registers and print them to serial monitor byte at a time the first read results in
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
The second read produces:
C5
30
01
20
F0
E1
A9
FD
FF
51
17
third, same as first
fourth, same as second and the pattern repeats.
Any suggestions?
The ADS1256 is an implementation that was commercially produced on a pcb with crystal and reference circuitry et al. I'm using an arduino due.
Main code:
#include "ads1256.h" ADS1256 ads; void setup() { // put your setup code here, to run once: Serial.begin(115200); ads.begin(); } void loop() { int avail = Serial.available(); if(avail > 0)//Triggered on any serial input { Serial.print("\n"); while(avail--) Serial.print((char)Serial.read()); //echo serial Serial.print("\n\n"); ads.readRegisters(); for(int i = 0; i < NUM_REGISTERS; i++) Serial.println(ads.reg[i],HEX); } }
ADS1256.h:
#ifndef __ADS1256_h #define __ADS1256_h #include <arduino.h> #define DRDY_PIN 25 #define CS_PIN 23 #define MISO_PIN 27 #define MOSI_PIN 26 #define SCK_PIN 24 #define RESET_PIN 22 #define XIN_FREQ 7680000 #define XIN_PER 1 / XIN_FREQ
//these define timing relationships #define WRITEINST_READDATA 75 * XIN_PER #define SCKLAST_CSHIGH 8 * XIN_PER #define WREG_DELAY 4 * XIN_PER #define RREG_DELAY 4 * XIN_PER #define SYNC_DELAY 24 * XIN_PER #define MICROSECONDS(a) a * 1000 *1000 //values are in seconds * 1000 gets millis *1000 gets micros #define ADS_WAKEUP 0b00000000 #define ADS_RDATA 0b00000001 #define ADS_RDATAC 0b00000011 #define ADS_SDATAC 0b00001111 #define ADS_SELFCAL 0b11110000 #define ADS_SELFOCAL 0b11110001 #define ADS_SELFGCAL 0b11110010 #define ADS_SYSOCAL 0b11110011 #define ADS_SYSGCAL 0b11110100 #define ADS_SYNC 0b11111100 #define ADS_STANDBY 0b11111101 #define ADS_RESET 0b11111110 #define ADS_RREG(ADDR) 0b0001 << 4 | ADDR #define ADS_WREG(ADDR) 0b0101 << 4 | ADDR enum REG_ADDR { STATUS = 0, MUX, ADCON, DRATE, IO, OFC0, OFC1, OFC2, FSC0, FSC1, FSC2, NUM_REGISTERS }; class ADS1256 { public: byte reg[NUM_REGISTERS]; void readRegisters() { shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_RREG(STATUS)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, NUM_REGISTERS - 1); delayMicroseconds(MICROSECONDS(WRITEINST_READDATA)); for(int i = 0; i < NUM_REGISTERS; i++) reg[i] = shiftIn(MISO_PIN, SCK_PIN, MSBFIRST); } byte readReg(byte addr) { shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_RREG(addr)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, 0x00); delayMicroseconds(MICROSECONDS(WRITEINST_READDATA)); byte val = shiftIn(MISO_PIN, SCK_PIN, MSBFIRST); delayMicroseconds(RREG_DELAY); return val; } void writeReg(byte addr, byte value) { shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_WREG(addr)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, 0x00); shiftOut(MISO_PIN, SCK_PIN, MSBFIRST, value); delayMicroseconds(WREG_DELAY); } void ADCreset(int pin) { digitalWrite(pin, LOW); delayMicroseconds(MICROSECONDS(5 * XIN_PER));//Make sure we start low for long enough //now we reset digitalWrite(pin, HIGH); delayMicroseconds(MICROSECONDS(300 * XIN_PER)); digitalWrite(pin, LOW); delayMicroseconds(MICROSECONDS(5 * XIN_PER)); digitalWrite(pin, HIGH); delayMicroseconds(MICROSECONDS(550 * XIN_PER)); digitalWrite(pin, LOW); delayMicroseconds(MICROSECONDS(5 * XIN_PER)); digitalWrite(pin, HIGH); delayMicroseconds(MICROSECONDS(1050 * XIN_PER)); digitalWrite(pin, LOW); } void begin() { pinMode(RESET_PIN, OUTPUT); digitalWrite(RESET_PIN, HIGH); pinMode(DRDY_PIN, INPUT); pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, LOW); pinMode(SCK_PIN, OUTPUT); digitalWrite(SCK_PIN, LOW); pinMode(MOSI_PIN, OUTPUT); digitalWrite(MOSI_PIN, HIGH); pinMode(MISO_PIN, INPUT_PULLUP); digitalWrite(RESET_PIN, LOW); delayMicroseconds(4 * XIN_PER); digitalWrite(RESET_PIN, HIGH); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_SDATAC); while (digitalRead(DRDY_PIN == HIGH)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_SELFCAL); unsigned long last = micros(); while (digitalRead(DRDY_PIN == HIGH)); Serial.println(micros() - last); readRegisters(); } bool channel(int ch) { //Channel 2 is jumpered to AGND and is the defacto AINn if (ch == 2) return false; byte _ch = 0; switch (ch) { case 1: _ch = 0x01; break; case 3: _ch = 0x21; break; case 4: _ch = 0x31; break; case 5: _ch = 0x41; break; case 6: _ch = 0x51; break; case 7: _ch = 0x61; break; case 8: _ch = 0x71; break; } while (digitalRead(DRDY_PIN) == HIGH); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_WREG(MUX)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, 0b00000000); //num bytes 0000 = 1, 0001 = 2, 0010 = 3, etc max 11 bytes per data sheet shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, _ch); delayMicroseconds(MICROSECONDS(WREG_DELAY)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_SYNC); delayMicroseconds(MICROSECONDS(SYNC_DELAY)); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_WAKEUP); } int read() { int result = 0; while (digitalRead(DRDY_PIN) == HIGH); shiftOut(MOSI_PIN, SCK_PIN, MSBFIRST, ADS_RDATA); delayMicroseconds(MICROSECONDS(WRITEINST_READDATA)); result |= (shiftIn(MISO_PIN, SCK_PIN, MSBFIRST) << 16); result |= (shiftIn(MISO_PIN, SCK_PIN, MSBFIRST) << 8); result |= shiftIn(MISO_PIN, SCK_PIN, MSBFIRST); // result |= (this->readByte() << 16); // result |= (this->readByte() << 8); // result |= this->readByte(); result &= 0x00FFFFFF; // if(result & 0x00800000){ // result |= 0xFE000000; // } delayMicroseconds(MICROSECONDS(SCKLAST_CSHIGH)); return result; } }; #endif