Hi,
I have Teensy 4.0 and ADS1256 module. I read data from ADXL and send via USB to PC. But I have problem with lot of noise from USB. If I use USB isolator, it is OK.
But I am thinking about otehr possibility - differential reading. But I am not sure if it will be useful.
My code is:
if I change to this, will it work? I know, I can try it, but it is not possible now and I will be ready.
Old:
New:
And change float READ_ADC()
Will it work if I connect to AIN0 and AIN1 instead AIN0 and AINCOM?
Thanks!
I have Teensy 4.0 and ADS1256 module. I read data from ADXL and send via USB to PC. But I have problem with lot of noise from USB. If I use USB isolator, it is OK.
But I am thinking about otehr possibility - differential reading. But I am not sure if it will be useful.
My code is:
Code:
#include <SPI.h>
// PIN assignements
#define CS_PIN 21
#define DRDY_PIN 22
#define RST_PIN 8
// SPI
#define SPISPEED 1950000
// ADS1256 registers
#define STATUS_REG 0x00
#define MUX_REG 0x01
#define ADCON_REG 0x02
#define DRATE_REG 0x03
// ADS1256 commands
#define WAKEUP_CMD 0x00 // completes SYNC and exits standby mode
#define RDATA_CMD 0x01 // read data
#define RREG_CMD 0x10 // read register (register ID in low nibble)
#define WREG_CMD 0x50 // write register (register ID in low nibble)
#define SELFCAL_CMD 0xF0 // offset and gain self-calibration
#define SYNC_CMD 0xFC // synchronize the A/D conversion
#define STANDBY_CMD 0xFD // begin standby mode
#define RESET_CMD 0xFE // reset to power-up values
#define VREF (2.5) // for conversion of raw ADC data to Volts
#define BUFFER_SIZE (30000) // samples
#define DRATE_15K (0xE0) // 15 kSPS
#define DRATE_30K (0xF0) // 30 kSPS
#define STATUS_REG_0x01 (0x01) // MSB first, Auto-Cal Dsbl, Input Buffer Dsbl
#define STATUS_REG_0x03 (0x03) // MSB first, Auto-Cal Dsbl, Input Buffer Enbl
#define STATUS_REG_0x07 (0x07) // MSB first, Auto-Cal Enbl, Input Buffer Enbl
#define ADCON_REG_VALUE (0x21) // 0 01 00 001 => Clock Out Freq = fCLKIN,
// Sensor Detect OFF, gain 2 7.68MHz
#define DRATE_REG_VALUE (BUFFER_SIZE==15000 ? DRATE_15K : DRATE_30K)
#define MUX_REG_VALUE (B00001000) // AINCOM
volatile int DRDY_state = HIGH;
float adc_volt[BUFFER_SIZE];
float adc_g[BUFFER_SIZE];
char inChar;
void writeRegister(uint8_t address, uint8_t value)
{
SPI.transfer( WREG_CMD | address );
SPI.transfer( 0x00 );
SPI.transfer( value );
delayMicroseconds( 100 );
}
void setup()
{
Serial.begin( 9600 ); // USB data rate is always max
while (!Serial) {} // wait for USB serial ready
//Serial.println( "ADS1256 test program" );
START_SPI();
attachInterrupt( DRDY_PIN, DRDY_Interrupt, FALLING );
}
void loop()
{
//uint32_t t0 = micros();
for (int i=0; i < BUFFER_SIZE; i++) {
waitDRDY();
adc_volt[i] = READ_ADC();
}
//Serial.printf( "Read %1d samples in %1lu us\n", BUFFER_SIZE, micros()-t0 );
if (Serial.available() > 0) {
inChar = Serial.read();
//START_SPI();
if (inChar == 'r') {
for(int i=0; i<BUFFER_SIZE; i++) {
byte *b = (byte *)&adc_volt[i];
Serial.write(b[0]);
Serial.write(b[1]);
Serial.write(b[2]);
Serial.write(b[3]);
}
}
if (inChar == 't') {
Serial.println("@");
}
}
}
float READ_ADC()
{
int32_t adc_raw;
SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1));
digitalWriteFast(CS_PIN, LOW);
SPI.transfer( RDATA_CMD );
delayMicroseconds(5); // delay MUST be >= 5 us
adc_raw = 0;
adc_raw |= SPI.transfer(0);
adc_raw <<= 8;
adc_raw |= SPI.transfer(0);
adc_raw <<= 8;
adc_raw |= SPI.transfer(0);
digitalWriteFast(CS_PIN, HIGH);
SPI.endTransaction();
if (adc_raw & (1<<23)) { // if 24-bit MSB == 1
adc_raw |= 0xFF000000; // value is negative, sign-extend to 32 bits
}
float v = adc_raw * (float)(VREF / (1<<23));
return( v );
}
// DRDY falling-edge interrupt function
void DRDY_Interrupt()
{
DRDY_state = LOW;
}
void waitDRDY()
{
// wait for DRDY_state to be LOW
while (DRDY_state == HIGH) {
continue;
}
// then set it back to HIGH
DRDY_state = HIGH;
}
void START_SPI ()
{
// configure I/O pins
pinMode(CS_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH); // init CS high (disable)
pinMode(DRDY_PIN, INPUT);
pinMode(RST_PIN, OUTPUT);
// hardware reset ADS1256 by toggling pin LOW then HIGH
digitalWrite(RST_PIN, LOW);
delay(1);
digitalWrite(RST_PIN, HIGH);
delay(500); //500
// start the spi-bus
SPI.begin();
delay(500); //500
// wait for DRDY signal LOW
while (digitalRead(DRDY_PIN)) {}
SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1));
digitalWriteFast(CS_PIN, LOW);
delayMicroseconds(100); //100
// reset to power-up state
SPI.transfer( RESET_CMD );
delay(5);
// configure registers
writeRegister( STATUS_REG, STATUS_REG_0x03 );
writeRegister( ADCON_REG, ADCON_REG_VALUE );
writeRegister( DRATE_REG, DRATE_REG_VALUE );
writeRegister( MUX_REG, MUX_REG_VALUE );
// auto-calibrate (send command, wait DRDY = LOW, then wait DRDY = HIGH)
SPI.transfer( SELFCAL_CMD );
uint32_t t0 = micros();
while (digitalReadFast(DRDY_PIN)!=LOW && micros()-t0 < 10000) {}
while (digitalReadFast(DRDY_PIN)!=HIGH && micros()-t0 < 10000) {}
digitalWriteFast(CS_PIN, HIGH);
SPI.endTransaction();
}
if I change to this, will it work? I know, I can try it, but it is not possible now and I will be ready.
Old:
Code:
#define MUX_REG_VALUE (B00001000) // AINCOM
New:
Code:
#define MUX_REG_VALUE (B00000001) // AIN0-AIN1
And change float READ_ADC()
Code:
float READ_ADC()
{
int32_t adc_raw;
SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1));
digitalWriteFast(CS_PIN, LOW);
SPI.transfer( RDATA_CMD );
delayMicroseconds(5); // delay MUST be >= 5 us
adc_raw = 0;
adc_raw |= SPI.transfer(0);
adc_raw <<= 8;
adc_raw |= SPI.transfer(0);
adc_raw <<= 8;
adc_raw |= SPI.transfer(0);
digitalWriteFast(CS_PIN, HIGH);
SPI.endTransaction();
if (adc_raw & (1<<23)) { // if 24-bit MSB == 1
adc_raw |= 0xFF000000; // value is negative, sign-extend to 32 bits
}
float v = adc_raw * (float)(VREF / (1<<23));
float vd = v - (VREF/2.0);
return( vd );
}
Will it work if I connect to AIN0 and AIN1 instead AIN0 and AINCOM?
Thanks!