Closed srisankaran closed 10 months ago
Go ahead and implement it. The code is open source.
Why isn't it a good idea?
Do it, if you want, I won't do it for you.
/*________________________________________________________________________________________________________
ESP32 micro-Voltmeter using ADS1256
By: Aryn (aka Sri Sankaran)
Last edit: 31/01/2024
________________________________________________________________________________________________________*/
/*INFO
PIN CONFIG (ESP32)
SPI *default pins:
IN - 23
OUT - 19
SCK - 18
CS - 5
-----------------
Other pins:
RST - 4
DRDY - 2 (intr pin)
CLOCK RATE
f_CLKIN = 7.68 MHz
τ_CLKIN = 130.2 ns */
/*______________________________________________________________________________________________________*/
//LIBRARY
#include <SPI.h> //SPI comunication
//BAUD RATE
#define bdrt_display 2000000
//ADC PINS
#define RESET_PIN 4
#define DRDY_PIN 2
#define CS_PIN 5 //!!fixed (do not change!)
/*________________________________________________________________________________________________________
DEFINE REGISTERS
________________________________________________________________________________________________________*/
#define STATUS 0x00
#define MUX 0x01
#define ADCON 0x02
#define DRATE 0x03
// STATUS
// ID - ID - ID - ID - ORDER - ACAL - BUFEN - DRDY
#define STATUS_RST 0x01
// MUX
// PSEL3 - PSEL2 - PSEL1 - PSEL0 - NSEL3 - NSEL2 - NSEL1 - NSEL0
#define MUX_RST 0x01
#define Diff1 P_AIN0+N_AIN1
#define Diff2 P_AIN2+N_AIN3
#define Diff3 P_AIN4+N_AIN5
#define Diff4 P_AIN6+N_AIN7
// ADCON
// 0 - CLK1 - CLK0 - SDCS1 - SDCS0 - PGA2 - PGA1 - PAG0
#define ADCON_RST 0x20
#define PGA_1 B00100000 //±5V
#define PGA_2 B00100001 //±2.5V
#define PGA_4 B00100010 //±1.25V
#define PGA_8 B00100011 //±0.625V
#define PGA_16 B00100100 //±0.3125V
#define PGA_32 B00100101 //±0.15625V current 0.5µA
#define PGA_64_2 B00100110 //±0.078125V current 2µA
#define PGA_64_10 B00100111 //±0.078125V current 10µA
// DRATE
// DR7 - DR6 - DR5 - DR4 - DR3 - DR2 - DR1 - DR0
#define DRATE_RST 0xF0
#define DR_100 B10000010
#define DR_50 B01100011
#define DR_10 B00100011
/*______________________________________________________________________________________________________*/
// SYSTEM CONTROL
#define WAKEUP 0x00
#define SYNC 0xFC
#define STANDBY 0xFD
#define RESET 0xFE
#define NOP 0xFF
// DATA READ
#define RDATA 0x01
#define RDATAC 0x03
#define SDATAC 0x0F
// READ REGISTER
#define RREG 0x10
#define WREG 0x50
// CALIBRATION
#define SYSGCAL 0xF4
#define SYSOCAL 0xF3
#define SELFGCAL 0xF2
#define SELFOCAL 0xF1
#define SELFCAL 0xF0
/*________________________________________________________________________________________________________
PROGRAM
________________________________________________________________________________________________________*/
void setup()
{
SPI.begin();
Serial.begin(bdrt_display);
init_adc();
ShowRegisterValues();
}
//Variables
int8_t pga = 1;
void loop()
{
float volt = dynamicVoltRead();
Serial.print("PGA = ");
Serial.print(pga);
Serial.print(" ");
Serial.println(volt, 6);
}
/*________________________________________________________________________________________________________
ADC FUNCTIONS
________________________________________________________________________________________________________*/
volatile int drdyState = false;
void init_adc()
{
pinMode(CS_PIN, OUTPUT);
pinMode(DRDY_PIN, INPUT);
pinMode(RESET_PIN, OUTPUT);
reset_hard();
delay(50);
attachInterrupt(digitalPinToInterrupt(DRDY_PIN), drdy_Interrupt, FALLING);
delay(50);
reset_soft();
delay(100);
userConfig();
}
void userConfig() //user's register congiguration
{
writeReg(MUX, Diff1);
writeReg(ADCON, PGA_1);
writeReg(DRATE, DR_50);
delay(200);
sendCmd(SELFCAL);
delay(200);
}
void ShowRegisterValues()
{
Serial.println();
Serial.print("STATUS: ");
Serial.println(readReg(STATUS));
Serial.print("MUX: ");
Serial.println(readReg(MUX));
Serial.print("ADCON: ");
Serial.println(readReg(ADCON));
Serial.print("DRATE: ");
Serial.println(readReg(DRATE));
}
long readReg(uint8_t regAdr)
{
uint8_t readRegBufr;
digitalWrite(5, LOW);
delayMicroseconds(10);
SPI.transfer(RREG | regAdr);
SPI.transfer(0x00);
delayMicroseconds(10);
readRegBufr = SPI.transfer(NOP);
delayMicroseconds(10);
digitalWrite(5, HIGH);
SPI.endTransaction();
return readRegBufr;
}
void writeReg(uint8_t regAdr, uint8_t regVal)
{
uint8_t regValPre = readReg(regAdr);
repeat:
if (regVal != regValPre)
{
drdyWait();
SPI.beginTransaction(SPISettings(bdrt_display, MSBFIRST, SPI_MODE1));
digitalWrite(5, LOW);
delayMicroseconds(10);
SPI.transfer(WREG | regAdr);
SPI.transfer(0x00);
SPI.transfer(regVal);
delayMicroseconds(10);
digitalWrite(5, HIGH);
SPI.endTransaction();
}
if (regVal != readReg(regAdr))
{
goto repeat;
}
else
{
// Serial.print("Register Write 0x");
// Serial.print(regAdr, HEX);
// Serial.println(" successful.");
}
sendCmd(SELFCAL);
sendCmd(SELFOCAL);
}
int32_t readAdc()
{
int32_t adc_val = 0;
drdyWait();
SPI.beginTransaction(SPISettings(bdrt_display, MSBFIRST, SPI_MODE1));
digitalWrite(5, LOW);
delayMicroseconds(5);
SPI.transfer(RDATA);
delayMicroseconds(10);
adc_val |= SPI.transfer(NOP);
delayMicroseconds(10);
adc_val <<= 8;
adc_val |= SPI.transfer(NOP);
delayMicroseconds(10);
adc_val <<= 8;
adc_val |= SPI.transfer(NOP);
delayMicroseconds(5);
digitalWrite(5, HIGH);
SPI.endTransaction();
if (adc_val > 0x7fffff) //if MSB == 1
{
adc_val = adc_val - 16777216; //2's complement
}
return adc_val;
}
void drdyWait()
{
while (drdyState)
{
continue;
}
noInterrupts();
drdyState = HIGH;
interrupts();
}
void drdy_Interrupt()
{
drdyState = LOW;
}
void reset_soft()
{
SPI.beginTransaction(SPISettings(bdrt_display, MSBFIRST, SPI_MODE1));
digitalWrite(5, LOW);
delayMicroseconds(10);
SPI.transfer(RESET);
delay(2);
SPI.transfer(SDATAC);
delayMicroseconds(100);
digitalWrite(5, HIGH);
SPI.endTransaction();
}
void reset_hard()
{
digitalWrite(CS_PIN, LOW);
digitalWrite(RESET_PIN, LOW);
delay(10);
digitalWrite(RESET_PIN, HIGH);
}
void sendCmd(uint8_t directCmd)
{
drdyWait();
SPI.beginTransaction(SPISettings(bdrt_display, MSBFIRST, SPI_MODE1));
digitalWrite(5, LOW);
delayMicroseconds(10);
SPI.transfer(directCmd);
delayMicroseconds(10);
digitalWrite(5, HIGH);
SPI.endTransaction();
delay(50);
}
/*________________________________________________________________________________________________________
USER FUNCTIONS
________________________________________________________________________________________________________*/
float readVolt()
{
float readVoltBufr = readAdc()*5 / (pow(2,pga-1)* ((1<<23)-1) ); //readAdc*ref / ((2^gain)*resolution)
return readVoltBufr;
}
float dynamicVoltRead()
{
writeReg(ADCON, PGA_1); //just for safety pga is set to default
pga=1;
float dynamicVoltBufr = readVolt();
if (abs(dynamicVoltBufr) < 0.05)
{
writeReg(ADCON, PGA_64_2);
pga=7;
}
else if (abs(dynamicVoltBufr) < 0.1)
{
writeReg(ADCON, PGA_32);
pga=6;
}
else if (abs(dynamicVoltBufr) < 0.2)
{
writeReg(ADCON, PGA_16);
pga=5;
}
else if (abs(dynamicVoltBufr) < 0.5)
{
writeReg(ADCON, PGA_8);
pga=4;
}
else if (abs(dynamicVoltBufr) < 1.0)
{
writeReg(ADCON, PGA_4);
pga=3;
}
else if (abs(dynamicVoltBufr) < 2.0)
{
writeReg(ADCON, PGA_2);
pga=2;
}
else {}
dynamicVoltBufr = Alot();
writeReg(ADCON, PGA_1); //set pga back to default
return dynamicVoltBufr;
}
float Alot()
{
int32_t timesBfr = 100;
float SigmaVoltBfr = 0.;
for(int32_t i=1; i<=timesBfr; i++)
{
SigmaVoltBfr=SigmaVoltBfr+readVolt();
}
SigmaVoltBfr=SigmaVoltBfr/timesBfr;
return SigmaVoltBfr;
}
I've successfully implemented and tested my code and was interested in enhancing the ads1256 library by contributing additional features to make it even more robust. I'm a bit puzzled by your response, and I hope my intention is clear. I believe constructive collaboration can lead to the best possible outcome for the library. I hope you don't take offense; I'm just expressing my eagerness to contribute positively to the project.
First of all, the above code has nothing to do with my library, it is a totally different code. The purpose of my library is to implement all the functions of the ADS1256. No less, no more. Therefore, while your idea might be good, it is not necessary to be included in the library. Those who want this function can implement the logic on top of the library, directly in their Arduino code.
Do it, if you want, I won't do it for you.
Your comment comes across as unprofessional. I didn't intend to imply that I wanted additional features for my own purposes; rather, I simply believed it would be beneficial if such a feature existed. As you've indicated, the primary objective of the library is to fully implement all functions of the ADS1256 without compromise. I understand and respect that perspective. However, if this is the tone conveyed through this forum, I question its suitability for constructive dialogue.
Additionally, I want to clarify that I have written the above code without utilizing your library, so I am capable of implementing it independently. My intention was to share the idea so that others could also benefit from it.
It would be cool if there was a function to implement a dynamic function to monitor voltage levels and automatically adjust the Programmable Gain Amplifier (PGA) when readings fall below specified thresholds, such as 2.5V, 1.25V,... This intelligent control mechanism optimizes precision by fine-tuning the PGA settings, ensuring more accurate and reliable small-scale voltage measurements.