Dear Platform IO team, when I compile my code with PlatformIO (vsCode), reading register via SPI communication gives different value than desired.
required register value 1
achieved register value 0
Write to Register 0x1 failed! on SetRegisterValue
required register value 240
achieved register value 120
Write to Register 0x1 failed! on SetRegisterValue
But when I put the same code to the arduino IDE, I get correct register write and reads.
Micro Controller - Teensey 4.1
SPI Communication - ADS1256
Softwares - WIN10 - ATOM 1.58 + Core 5.2.3 Home 3.4.0
Softwares - WIN10 - VS CODE 1.62.3 + Core 5.2.3 Home 3.4.0
Arduino - Arduino 1.9.16 Teenseyduino 1.55
Minimal reproducible code
// Library by - https://github.com/mbilsky/TeensyADS1256
// built up on the work of:
// https://github.com/Flydroid/ADS12xx-Library
// https://gist.github.com/dariosalvi78/f2e990b4317199d235bbf5963c3486ae
// https://github.com/adienakhmad/ADS1256
// Interrupt function
#include <Arduino.h>
#include <SPI.h> //SPI communication
#define SPI_SPEED 1900000
// /* For information to the register and settings see manual page (p..) */
// /* ADS1248 Register (see p42 for Register Map) */
#define STATUS 0x00 // Status Control Register 0
#define MUX 0x01 // Multiplexer Control Register 0
#define ADCON 0x02 // A/D Control Register 0
#define DRATE 0x03 // A/D Data Rate Control Register 0
#define OFC0 0x05 // Offset Calibration Coefficient Register 1
#define OFC1 0x06 // Offset Calibration Coefficient Register 2
#define OFC2 0x07 // Offset Calibration Coefficient Register 2
#define FSC0 0x08 // Full scale Callibration Coefficient Register 0
#define FSC1 0x09 // Full scale Callibration Coefficient Register 1
#define FSC2 0x0A // Full scale Callibration Coefficient REgister 2
#define STATUS_RESET 0x01 // Reset STATUS Register
#define MUX_RESET 0x01 // Reset MUX0 Register
#define PGA_1 B00000000 //(default)
#define DR_30000 B11110000 // 30.000 SPS (default)
#define DR_1000 B10100001 //1.000 SPS
#define RESET 0xFE // Reset To Power UP values
#define NOP 0xFF // No operation
#define RDATA 0x01 // Read data once
#define SDATAC 0x0F // Stop reading data continously
#define RREG 0x10 // Read From Register
#define WREG 0x50 // Write To Register
#define SELFCAL 0xF0 // Self Offset Calibration
#define ADS_RST_PIN 3 // ADS1256 reset pin
#define ADS_RDY_PIN 2 // ADS1256 data ready
#define ADS_CS_PIN 10 // ADS1256 chip select
volatile int DRDY_state = HIGH;
void DRDY_Interuppt() { DRDY_state = LOW; }
void Reset() {
SPI.beginTransaction(SPISettings(SPI_SPEED, MSBFIRST, SPI_MODE1)); // initialize SPI with clock, MSB first, SPI Mode1
digitalWriteFast(10, LOW);
delayMicroseconds(10);
SPI.transfer(RESET); // Reset
delay(2); // Minimum 0.6ms required for Reset to finish.
SPI.transfer(SDATAC); // Issue SDATAC
delayMicroseconds(100);
digitalWriteFast(10, HIGH);
SPI.endTransaction();
}
long GetRegisterValue(uint8_t regAdress) {
uint8_t bufr;
digitalWriteFast(10, LOW);
delayMicroseconds(10);
SPI.transfer(RREG | regAdress); // send 1st command byte, address of the register
SPI.transfer(0x00); // send 2nd command byte, read only one register
delayMicroseconds(10);
bufr = SPI.transfer(NOP); // read data of the register
delayMicroseconds(10);
digitalWriteFast(10, HIGH);
// digitalWrite(_START, LOW);
SPI.endTransaction();
return bufr;
}
void waitforDRDY() {
while (DRDY_state) {
continue;
}
noInterrupts();
DRDY_state = HIGH;
interrupts();
}
void SetRegisterValue(uint8_t regAdress, uint8_t regValue) {
// uint8_t regValuePre = GetRegisterValue(regAdress);
// if (regValue != regValuePre) {
// digitalWrite(_START, HIGH);
delayMicroseconds(10);
waitforDRDY();
SPI.beginTransaction(
SPISettings(SPI_SPEED, MSBFIRST, SPI_MODE1)); // initialize SPI with SPI_SPEED, MSB first, SPI Mode1
digitalWriteFast(10, LOW);
delayMicroseconds(10);
SPI.transfer(WREG | regAdress); // send 1st command byte, address of the register
SPI.transfer(0x00); // send 2nd command byte, write only one register
SPI.transfer(regValue); // write data (1 Byte) for the register
delayMicroseconds(10);
digitalWriteFast(10, HIGH);
// digitalWrite(_START, LOW);
long regRecvValue = GetRegisterValue(regAdress);
//
Serial.print("required register value ");
Serial.println(regValue);
Serial.print("achieved register value ");
Serial.println(regRecvValue);
//
if (regValue != regRecvValue) { // Check if write was succesfull
Serial.print("Write to Register 0x");
Serial.print(regAdress, HEX);
Serial.println(" failed! on SetRegisterValue");
} else {
Serial.println("success on SetRegisterValue");
}
SPI.endTransaction();
// }
}
void SendCMD(uint8_t cmd) {
waitforDRDY();
SPI.beginTransaction(
SPISettings(SPI_SPEED, MSBFIRST, SPI_MODE1)); // initialize SPI with 4Mhz clock, MSB first, SPI Mode0
digitalWriteFast(10, LOW);
delayMicroseconds(10);
SPI.transfer(cmd);
delayMicroseconds(10);
digitalWriteFast(10, HIGH);
SPI.endTransaction();
}
void initADS() {
attachInterrupt(ADS_RDY_PIN, DRDY_Interuppt, FALLING);
digitalWrite(ADS_RST_PIN, LOW);
delay(10); // LOW at least 4 clock cycles of onboard clock. 100 microsecons is enough
digitalWrite(ADS_RST_PIN, HIGH); // now reset to deafult values
delay(1000);
// now reset the ADS
Reset();
// let the system power up and stabilize (datasheet pg 24)
delay(2000);
// this enables the buffer which gets us more accurate voltage readings
// SetRegisterValue(STATUS,B00110010);
Serial.println(GetRegisterValue(STATUS));
// next set the mux register
// we are only trying to read differential values from pins 0 and 1. your needs may vary.
// this is the default setting so we can just reset it
SetRegisterValue(MUX, MUX_RESET); // set the mux register
// B00001000 for single ended measurement
// now set the ADCON register
// set the PGA to 64x
// you need to adjust the constants for the other ones according to datasheet pg 31 if you need other values
SetRegisterValue(ADCON, PGA_1); // set the adcon register
// next set the data rate
SetRegisterValue(DRATE, DR_30000); // set the drate register
// we're going to ignore the GPIO for now...
// lastly, we need to calibrate the system
// let it settle
delay(2000);
// then do calibration
SendCMD(SELFCAL); // send the calibration command
// then print out the values
delay(5);
Serial.print("OFC0: ");
Serial.println(GetRegisterValue(OFC0));
Serial.print("OFC1: ");
Serial.println(GetRegisterValue(OFC1));
Serial.print("OFC2: ");
Serial.println(GetRegisterValue(OFC2));
Serial.print("FSC0: ");
Serial.println(GetRegisterValue(FSC0));
Serial.print("FSC1: ");
Serial.println(GetRegisterValue(FSC1));
Serial.print("FSC2: ");
Serial.println(GetRegisterValue(FSC2));
}
// library files
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("booting");
// initialize the ADS
pinMode(ADS_CS_PIN, OUTPUT);
// digitalWrite (ADS_CS_PIN, HIGH);
// https://forum.arduino.cc/t/solved-spi-communication-failure-anything-obvious-with-the-code/172109
pinMode(ADS_RDY_PIN, INPUT);
pinMode(ADS_RST_PIN, OUTPUT);
digitalWrite(ADS_CS_PIN, HIGH);
// https://forum.arduino.cc/t/solved-spi-communication-failure-anything-obvious-with-the-code/172109
SPI.begin();
initADS();
Serial.println("done init");
}
int32_t val1;
int32_t val2;
int32_t val3;
void loop() {
Serial.println("here");
SetRegisterValue(0x00,B00000000);
SetRegisterValue(0x01, B00001000);
SetRegisterValue(0x02, B00000010);
SetRegisterValue(0x03, B00010011);
delay(1000);
}